This commit is contained in:
13
.history/.dockerignore_20250904015110
Normal file
13
.history/.dockerignore_20250904015110
Normal file
@@ -0,0 +1,13 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
bot.db
|
||||
.idea/
|
||||
.vscode/
|
||||
tests/
|
||||
.git/
|
||||
.gitignore
|
||||
13
.history/.dockerignore_20250904015136
Normal file
13
.history/.dockerignore_20250904015136
Normal file
@@ -0,0 +1,13 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
bot.db
|
||||
.idea/
|
||||
.vscode/
|
||||
tests/
|
||||
.git/
|
||||
.gitignore
|
||||
14
.history/.drone_20250903222304.yml
Normal file
14
.history/.drone_20250903222304.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: docker:dind
|
||||
privileged: true
|
||||
commands:
|
||||
- docker build -t post_bot .
|
||||
- name: test
|
||||
image: python:3.11-slim
|
||||
commands:
|
||||
- pip install --no-cache-dir python-telegram-bot sqlalchemy python-dotenv pytest
|
||||
- pytest tests/
|
||||
14
.history/.drone_20250903222551.yml
Normal file
14
.history/.drone_20250903222551.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: docker:dind
|
||||
privileged: true
|
||||
commands:
|
||||
- docker build -t post_bot .
|
||||
- name: test
|
||||
image: python:3.11-slim
|
||||
commands:
|
||||
- pip install --no-cache-dir python-telegram-bot sqlalchemy python-dotenv pytest
|
||||
- pytest tests/
|
||||
2
.history/.env_20250903222252.example
Normal file
2
.history/.env_20250903222252.example
Normal file
@@ -0,0 +1,2 @@
|
||||
TELEGRAM_TOKEN=your_token_here
|
||||
DATABASE_URL=sqlite:///bot.db
|
||||
2
.history/.env_20250903222550.example
Normal file
2
.history/.env_20250903222550.example
Normal file
@@ -0,0 +1,2 @@
|
||||
TELEGRAM_TOKEN=your_token_here
|
||||
DATABASE_URL=sqlite:///bot.db
|
||||
2
.history/.env_20250903222725
Normal file
2
.history/.env_20250903222725
Normal file
@@ -0,0 +1,2 @@
|
||||
TELEGRAM_TOKEN=your_token_here
|
||||
DATABASE_URL=sqlite:///bot.db
|
||||
2
.history/.env_20250903222731
Normal file
2
.history/.env_20250903222731
Normal file
@@ -0,0 +1,2 @@
|
||||
TELEGRAM_TOKEN=6414100562:AAFxeXt331_sKf8ui1EJve9vinUHyKHBjiU
|
||||
DATABASE_URL=sqlite:///bot.db
|
||||
2
.history/.env_20250903223048
Normal file
2
.history/.env_20250903223048
Normal file
@@ -0,0 +1,2 @@
|
||||
TELEGRAM_TOKEN=6414100562:AAEbDJZnFFJfddS0SV1xA4L0MQqxOArU4a0
|
||||
DATABASE_URL=sqlite:///bot.db
|
||||
0
.history/.gitignore_20250904015025
Normal file
0
.history/.gitignore_20250904015025
Normal file
5
.history/.gitignore_20250904015046
Normal file
5
.history/.gitignore_20250904015046
Normal file
@@ -0,0 +1,5 @@
|
||||
.env
|
||||
.venv/
|
||||
.history
|
||||
__pycache__/
|
||||
.db
|
||||
27
.history/.gitignore_20250904015125
Normal file
27
.history/.gitignore_20250904015125
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# DB
|
||||
bot.db
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Docker
|
||||
*.log
|
||||
|
||||
# Tests
|
||||
tests/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
27
.history/.gitignore_20250904015136
Normal file
27
.history/.gitignore_20250904015136
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
# Python
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# DB
|
||||
bot.db
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Docker
|
||||
*.log
|
||||
|
||||
# Tests
|
||||
tests/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
5
.history/Dockerfile_20250903222300
Normal file
5
.history/Dockerfile_20250903222300
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
RUN pip install --no-cache-dir python-telegram-bot sqlalchemy python-dotenv
|
||||
CMD ["python", "main.py"]
|
||||
5
.history/Dockerfile_20250903222550
Normal file
5
.history/Dockerfile_20250903222550
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM python:3.11-slim
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
RUN pip install --no-cache-dir python-telegram-bot sqlalchemy python-dotenv
|
||||
CMD ["python", "main.py"]
|
||||
13
.history/db_20250903222256.py
Normal file
13
.history/db_20250903222256.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import os
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from models import Base
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///bot.db')
|
||||
engine = create_engine(DATABASE_URL, echo=True)
|
||||
SessionLocal = sessionmaker(bind=engine)
|
||||
|
||||
def init_db():
|
||||
Base.metadata.create_all(engine)
|
||||
13
.history/db_20250903222550.py
Normal file
13
.history/db_20250903222550.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import os
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from models import Base
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///bot.db')
|
||||
engine = create_engine(DATABASE_URL, echo=True)
|
||||
SessionLocal = sessionmaker(bind=engine)
|
||||
|
||||
def init_db():
|
||||
Base.metadata.create_all(engine)
|
||||
9
.history/docker-compose_20250903222302.yml
Normal file
9
.history/docker-compose_20250903222302.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
bot:
|
||||
build: .
|
||||
env_file:
|
||||
- .env.example
|
||||
volumes:
|
||||
- ./bot.db:/app/bot.db
|
||||
restart: unless-stopped
|
||||
9
.history/docker-compose_20250903222551.yml
Normal file
9
.history/docker-compose_20250903222551.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
version: '3.8'
|
||||
services:
|
||||
bot:
|
||||
build: .
|
||||
env_file:
|
||||
- .env.example
|
||||
volumes:
|
||||
- ./bot.db:/app/bot.db
|
||||
restart: unless-stopped
|
||||
63
.history/handlers/add_button_20250903222421.py
Normal file
63
.history/handlers/add_button_20250903222421.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
63
.history/handlers/add_button_20250903222551.py
Normal file
63
.history/handlers/add_button_20250903222551.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
63
.history/handlers/add_button_20250903222834.py
Normal file
63
.history/handlers/add_button_20250903222834.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
63
.history/handlers/add_button_20250903222845.py
Normal file
63
.history/handlers/add_button_20250903222845.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
73
.history/handlers/add_button_20250904013311.py
Normal file
73
.history/handlers/add_button_20250904013311.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
# Если выбран канал или группа уже сохранены — сразу переход к названию
|
||||
if context.user_data.get('channel_id'):
|
||||
context.user_data['target'] = f"channel_{context.user_data['channel_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
elif context.user_data.get('group_id'):
|
||||
context.user_data['target'] = f"group_{context.user_data['group_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
# Если нет — стандартный выбор
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
73
.history/handlers/add_button_20250904013404.py
Normal file
73
.history/handlers/add_button_20250904013404.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
# Если выбран канал или группа уже сохранены — сразу переход к названию
|
||||
if context.user_data.get('channel_id'):
|
||||
context.user_data['target'] = f"channel_{context.user_data['channel_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
elif context.user_data.get('group_id'):
|
||||
context.user_data['target'] = f"group_{context.user_data['group_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
# Если нет — стандартный выбор
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data['button_name']
|
||||
target = context.user_data['target']
|
||||
session = SessionLocal()
|
||||
if target.startswith('channel_'):
|
||||
channel_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, channel_id=channel_id)
|
||||
else:
|
||||
group_id = int(target.split('_')[1])
|
||||
button = Button(name=name, url=url, group_id=group_id)
|
||||
session.add(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
84
.history/handlers/add_button_20250904013434.py
Normal file
84
.history/handlers/add_button_20250904013434.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
# Если выбран канал или группа уже сохранены — сразу переход к названию
|
||||
if context.user_data.get('channel_id'):
|
||||
context.user_data['target'] = f"channel_{context.user_data['channel_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
elif context.user_data.get('group_id'):
|
||||
context.user_data['target'] = f"group_{context.user_data['group_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
# Если нет — стандартный выбор
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data.get('button_name')
|
||||
target = context.user_data.get('target')
|
||||
if not target or ('_' not in target):
|
||||
await update.message.reply_text('Ошибка: не выбран канал или группа. Попробуйте снова.')
|
||||
return ConversationHandler.END
|
||||
session = SessionLocal()
|
||||
try:
|
||||
type_, obj_id = target.split('_', 1)
|
||||
obj_id = int(obj_id)
|
||||
if type_ == 'channel':
|
||||
button = Button(name=name, url=url, channel_id=obj_id)
|
||||
elif type_ == 'group':
|
||||
button = Button(name=name, url=url, group_id=obj_id)
|
||||
else:
|
||||
await update.message.reply_text('Ошибка: неверный тип объекта.')
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
session.add(button)
|
||||
session.commit()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f'Ошибка при добавлении кнопки: {e}')
|
||||
finally:
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
84
.history/handlers/add_button_20250904013628.py
Normal file
84
.history/handlers/add_button_20250904013628.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes, ConversationHandler, CommandHandler, CallbackQueryHandler, MessageHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_TARGET, INPUT_NAME, INPUT_URL = range(3)
|
||||
|
||||
async def add_button_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
# Если выбран канал или группа уже сохранены — сразу переход к названию
|
||||
if context.user_data.get('channel_id'):
|
||||
context.user_data['target'] = f"channel_{context.user_data['channel_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
elif context.user_data.get('group_id'):
|
||||
context.user_data['target'] = f"group_{context.user_data['group_id']}"
|
||||
await update.message.reply_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
# Если нет — стандартный выбор
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([{'text': f'Канал: {c.name}', 'callback_data': f'channel_{c.id}'}])
|
||||
for g in groups:
|
||||
keyboard.append([{'text': f'Группа: {g.name}', 'callback_data': f'group_{g.id}'}])
|
||||
if not keyboard:
|
||||
await update.message.reply_text('Нет каналов или групп для добавления кнопки.')
|
||||
return ConversationHandler.END
|
||||
await update.message.reply_text('Выберите канал или группу:', reply_markup=None)
|
||||
context.user_data['keyboard'] = keyboard
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
context.user_data['target'] = data
|
||||
await query.edit_message_text('Введите название кнопки:')
|
||||
return INPUT_NAME
|
||||
|
||||
async def input_name(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['button_name'] = update.message.text
|
||||
await update.message.reply_text('Введите ссылку для кнопки:')
|
||||
return INPUT_URL
|
||||
|
||||
async def input_url(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
url = update.message.text
|
||||
name = context.user_data.get('button_name')
|
||||
target = context.user_data.get('target')
|
||||
if not target or ('_' not in target):
|
||||
await update.message.reply_text('Ошибка: не выбран канал или группа. Попробуйте снова.')
|
||||
return ConversationHandler.END
|
||||
session = SessionLocal()
|
||||
try:
|
||||
type_, obj_id = target.split('_', 1)
|
||||
obj_id = int(obj_id)
|
||||
if type_ == 'channel':
|
||||
button = Button(name=name, url=url, channel_id=obj_id)
|
||||
elif type_ == 'group':
|
||||
button = Button(name=name, url=url, group_id=obj_id)
|
||||
else:
|
||||
await update.message.reply_text('Ошибка: неверный тип объекта.')
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
session.add(button)
|
||||
session.commit()
|
||||
await update.message.reply_text('Кнопка добавлена.')
|
||||
except Exception as e:
|
||||
await update.message.reply_text(f'Ошибка при добавлении кнопки: {e}')
|
||||
finally:
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
|
||||
add_button_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('add_button', add_button_start)],
|
||||
states={
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
INPUT_NAME: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_name)],
|
||||
INPUT_URL: [MessageHandler(filters.TEXT & ~filters.COMMAND, input_url)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
17
.history/handlers/add_channel_20250903222417.py
Normal file
17
.history/handlers/add_channel_20250903222417.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Channel
|
||||
|
||||
async def add_channel(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 2:
|
||||
await update.message.reply_text('Используйте: /add_channel <название> <ссылка>')
|
||||
return
|
||||
name, link = args[0], args[1]
|
||||
session = SessionLocal()
|
||||
channel = Channel(name=name, link=link)
|
||||
session.add(channel)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Канал "{name}" добавлен.')
|
||||
17
.history/handlers/add_channel_20250903222551.py
Normal file
17
.history/handlers/add_channel_20250903222551.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Channel
|
||||
|
||||
async def add_channel(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 2:
|
||||
await update.message.reply_text('Используйте: /add_channel <название> <ссылка>')
|
||||
return
|
||||
name, link = args[0], args[1]
|
||||
session = SessionLocal()
|
||||
channel = Channel(name=name, link=link)
|
||||
session.add(channel)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Канал "{name}" добавлен.')
|
||||
17
.history/handlers/add_group_20250903222419.py
Normal file
17
.history/handlers/add_group_20250903222419.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Group
|
||||
|
||||
async def add_group(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 2:
|
||||
await update.message.reply_text('Используйте: /add_group <название> <ссылка>')
|
||||
return
|
||||
name, link = args[0], args[1]
|
||||
session = SessionLocal()
|
||||
group = Group(name=name, link=link)
|
||||
session.add(group)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Группа "{name}" добавлена.')
|
||||
17
.history/handlers/add_group_20250903222551.py
Normal file
17
.history/handlers/add_group_20250903222551.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Group
|
||||
|
||||
async def add_group(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 2:
|
||||
await update.message.reply_text('Используйте: /add_group <название> <ссылка>')
|
||||
return
|
||||
name, link = args[0], args[1]
|
||||
session = SessionLocal()
|
||||
group = Group(name=name, link=link)
|
||||
session.add(group)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Группа "{name}" добавлена.')
|
||||
40
.history/handlers/channel_buttons_20250903223438.py
Normal file
40
.history/handlers/channel_buttons_20250903223438.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import CommandHandler, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Channel, Button
|
||||
|
||||
SELECT_CHANNEL, MANAGE_BUTTONS = range(2)
|
||||
|
||||
async def channel_buttons_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
session.close()
|
||||
keyboard = [[InlineKeyboardButton(c.name, callback_data=str(c.id))] for c in channels]
|
||||
await update.message.reply_text(
|
||||
"Выберите канал для настройки клавиатуры:",
|
||||
reply_markup=InlineKeyboardMarkup(keyboard)
|
||||
)
|
||||
return SELECT_CHANNEL
|
||||
|
||||
async def select_channel(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
channel_id = int(query.data)
|
||||
context.user_data['channel_id'] = channel_id
|
||||
session = SessionLocal()
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
session.close()
|
||||
text = "Кнопки этого канала:\n"
|
||||
for b in buttons:
|
||||
text += f"- {b.name}: {b.url}\n"
|
||||
text += "\nДобавить новую кнопку: /add_button\nУдалить: /del_button <название>"
|
||||
await query.edit_message_text(text)
|
||||
return ConversationHandler.END
|
||||
|
||||
channel_buttons_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('channel_buttons', channel_buttons_start)],
|
||||
states={
|
||||
SELECT_CHANNEL: [CallbackQueryHandler(select_channel)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
40
.history/handlers/channel_buttons_20250904013103.py
Normal file
40
.history/handlers/channel_buttons_20250904013103.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import CommandHandler, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Channel, Button
|
||||
|
||||
SELECT_CHANNEL, MANAGE_BUTTONS = range(2)
|
||||
|
||||
async def channel_buttons_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
session.close()
|
||||
keyboard = [[InlineKeyboardButton(c.name, callback_data=str(c.id))] for c in channels]
|
||||
await update.message.reply_text(
|
||||
"Выберите канал для настройки клавиатуры:",
|
||||
reply_markup=InlineKeyboardMarkup(keyboard)
|
||||
)
|
||||
return SELECT_CHANNEL
|
||||
|
||||
async def select_channel(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
channel_id = int(query.data)
|
||||
context.user_data['channel_id'] = channel_id
|
||||
session = SessionLocal()
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
session.close()
|
||||
text = "Кнопки этого канала:\n"
|
||||
for b in buttons:
|
||||
text += f"- {b.name}: {b.url}\n"
|
||||
text += "\nДобавить новую кнопку: /add_button\nУдалить: /del_button <название>"
|
||||
await query.edit_message_text(text)
|
||||
return ConversationHandler.END
|
||||
|
||||
channel_buttons_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('channel_buttons', channel_buttons_start)],
|
||||
states={
|
||||
SELECT_CHANNEL: [CallbackQueryHandler(select_channel)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
21
.history/handlers/del_button_20250903223442.py
Normal file
21
.history/handlers/del_button_20250903223442.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import CommandHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Button
|
||||
|
||||
async def del_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if not args:
|
||||
await update.message.reply_text('Используйте: /del_button <название>')
|
||||
return
|
||||
name = args[0]
|
||||
session = SessionLocal()
|
||||
button = session.query(Button).filter_by(name=name).first()
|
||||
if not button:
|
||||
await update.message.reply_text('Кнопка не найдена.')
|
||||
session.close()
|
||||
return
|
||||
session.delete(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Кнопка "{name}" удалена.')
|
||||
21
.history/handlers/del_button_20250904013103.py
Normal file
21
.history/handlers/del_button_20250904013103.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import CommandHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Button
|
||||
|
||||
async def del_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if not args:
|
||||
await update.message.reply_text('Используйте: /del_button <название>')
|
||||
return
|
||||
name = args[0]
|
||||
session = SessionLocal()
|
||||
button = session.query(Button).filter_by(name=name).first()
|
||||
if not button:
|
||||
await update.message.reply_text('Кнопка не найдена.')
|
||||
session.close()
|
||||
return
|
||||
session.delete(button)
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Кнопка "{name}" удалена.')
|
||||
22
.history/handlers/edit_button_20250903223440.py
Normal file
22
.history/handlers/edit_button_20250903223440.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import CommandHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Button
|
||||
|
||||
async def edit_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 3:
|
||||
await update.message.reply_text('Используйте: /edit_button <название> <новое_название> <новая_ссылка>')
|
||||
return
|
||||
name, new_name, new_url = args[0], args[1], args[2]
|
||||
session = SessionLocal()
|
||||
button = session.query(Button).filter_by(name=name).first()
|
||||
if not button:
|
||||
await update.message.reply_text('Кнопка не найдена.')
|
||||
session.close()
|
||||
return
|
||||
button.name = new_name
|
||||
button.url = new_url
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Кнопка "{name}" изменена.')
|
||||
22
.history/handlers/edit_button_20250904013103.py
Normal file
22
.history/handlers/edit_button_20250904013103.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from telegram import Update
|
||||
from telegram.ext import CommandHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Button
|
||||
|
||||
async def edit_button(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
args = context.args
|
||||
if len(args) < 3:
|
||||
await update.message.reply_text('Используйте: /edit_button <название> <новое_название> <новая_ссылка>')
|
||||
return
|
||||
name, new_name, new_url = args[0], args[1], args[2]
|
||||
session = SessionLocal()
|
||||
button = session.query(Button).filter_by(name=name).first()
|
||||
if not button:
|
||||
await update.message.reply_text('Кнопка не найдена.')
|
||||
session.close()
|
||||
return
|
||||
button.name = new_name
|
||||
button.url = new_url
|
||||
session.commit()
|
||||
session.close()
|
||||
await update.message.reply_text(f'Кнопка "{name}" изменена.')
|
||||
2
.history/handlers/edit_post_20250903223444.py
Normal file
2
.history/handlers/edit_post_20250903223444.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Заглушка для будущей реализации редактирования поста
|
||||
# Можно реализовать хранение черновиков и их редактирование
|
||||
2
.history/handlers/edit_post_20250904013103.py
Normal file
2
.history/handlers/edit_post_20250904013103.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Заглушка для будущей реализации редактирования поста
|
||||
# Можно реализовать хранение черновиков и их редактирование
|
||||
40
.history/handlers/group_buttons_20250903223435.py
Normal file
40
.history/handlers/group_buttons_20250903223435.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import CommandHandler, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Group, Button
|
||||
|
||||
SELECT_GROUP, MANAGE_BUTTONS = range(2)
|
||||
|
||||
async def group_buttons_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = [[InlineKeyboardButton(g.name, callback_data=str(g.id))] for g in groups]
|
||||
await update.message.reply_text(
|
||||
"Выберите группу для настройки клавиатуры:",
|
||||
reply_markup=InlineKeyboardMarkup(keyboard)
|
||||
)
|
||||
return SELECT_GROUP
|
||||
|
||||
async def select_group(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
group_id = int(query.data)
|
||||
context.user_data['group_id'] = group_id
|
||||
session = SessionLocal()
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
session.close()
|
||||
text = "Кнопки этой группы:\n"
|
||||
for b in buttons:
|
||||
text += f"- {b.name}: {b.url}\n"
|
||||
text += "\nДобавить новую кнопку: /add_button\nУдалить: /del_button <название>"
|
||||
await query.edit_message_text(text)
|
||||
return ConversationHandler.END
|
||||
|
||||
group_buttons_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('group_buttons', group_buttons_start)],
|
||||
states={
|
||||
SELECT_GROUP: [CallbackQueryHandler(select_group)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
40
.history/handlers/group_buttons_20250904013103.py
Normal file
40
.history/handlers/group_buttons_20250904013103.py
Normal file
@@ -0,0 +1,40 @@
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import CommandHandler, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from db import SessionLocal
|
||||
from models import Group, Button
|
||||
|
||||
SELECT_GROUP, MANAGE_BUTTONS = range(2)
|
||||
|
||||
async def group_buttons_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = [[InlineKeyboardButton(g.name, callback_data=str(g.id))] for g in groups]
|
||||
await update.message.reply_text(
|
||||
"Выберите группу для настройки клавиатуры:",
|
||||
reply_markup=InlineKeyboardMarkup(keyboard)
|
||||
)
|
||||
return SELECT_GROUP
|
||||
|
||||
async def select_group(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
group_id = int(query.data)
|
||||
context.user_data['group_id'] = group_id
|
||||
session = SessionLocal()
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
session.close()
|
||||
text = "Кнопки этой группы:\n"
|
||||
for b in buttons:
|
||||
text += f"- {b.name}: {b.url}\n"
|
||||
text += "\nДобавить новую кнопку: /add_button\nУдалить: /del_button <название>"
|
||||
await query.edit_message_text(text)
|
||||
return ConversationHandler.END
|
||||
|
||||
group_buttons_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('group_buttons', group_buttons_start)],
|
||||
states={
|
||||
SELECT_GROUP: [CallbackQueryHandler(select_group)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
62
.history/handlers/new_post_20250903222423.py
Normal file
62
.history/handlers/new_post_20250903222423.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
||||
|
||||
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
||||
return SELECT_MEDIA
|
||||
|
||||
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if update.message.photo:
|
||||
context.user_data['photo'] = update.message.photo[-1].file_id
|
||||
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
||||
return SELECT_TEXT
|
||||
|
||||
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['text'] = update.message.text or update.message.caption
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([InlineKeyboardButton(f'Канал: {c.name}', callback_data=f'channel_{c.id}')])
|
||||
for g in groups:
|
||||
keyboard.append([InlineKeyboardButton(f'Группа: {g.name}', callback_data=f'group_{g.id}')])
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
session = SessionLocal()
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
channel = session.query(Channel).get(channel_id)
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=channel.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
else:
|
||||
group_id = int(data.split('_')[1])
|
||||
group = session.query(Group).get(group_id)
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=group.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
session.close()
|
||||
await query.edit_message_text('Пост отправлен!')
|
||||
return ConversationHandler.END
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('new_post', new_post_start)],
|
||||
states={
|
||||
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
||||
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
62
.history/handlers/new_post_20250903222551.py
Normal file
62
.history/handlers/new_post_20250903222551.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
||||
|
||||
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
||||
return SELECT_MEDIA
|
||||
|
||||
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if update.message.photo:
|
||||
context.user_data['photo'] = update.message.photo[-1].file_id
|
||||
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
||||
return SELECT_TEXT
|
||||
|
||||
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['text'] = update.message.text or update.message.caption
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([InlineKeyboardButton(f'Канал: {c.name}', callback_data=f'channel_{c.id}')])
|
||||
for g in groups:
|
||||
keyboard.append([InlineKeyboardButton(f'Группа: {g.name}', callback_data=f'group_{g.id}')])
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
session = SessionLocal()
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
channel = session.query(Channel).get(channel_id)
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=channel.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
else:
|
||||
group_id = int(data.split('_')[1])
|
||||
group = session.query(Group).get(group_id)
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=group.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
session.close()
|
||||
await query.edit_message_text('Пост отправлен!')
|
||||
return ConversationHandler.END
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('new_post', new_post_start)],
|
||||
states={
|
||||
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
||||
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
63
.history/handlers/new_post_20250903223031.py
Normal file
63
.history/handlers/new_post_20250903223031.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters, CallbackQueryHandler, ContextTypes
|
||||
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
||||
|
||||
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
||||
return SELECT_MEDIA
|
||||
|
||||
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if update.message.photo:
|
||||
context.user_data['photo'] = update.message.photo[-1].file_id
|
||||
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
||||
return SELECT_TEXT
|
||||
|
||||
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['text'] = update.message.text or update.message.caption
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([InlineKeyboardButton(f'Канал: {c.name}', callback_data=f'channel_{c.id}')])
|
||||
for g in groups:
|
||||
keyboard.append([InlineKeyboardButton(f'Группа: {g.name}', callback_data=f'group_{g.id}')])
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
session = SessionLocal()
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
channel = session.query(Channel).get(channel_id)
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=channel.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
else:
|
||||
group_id = int(data.split('_')[1])
|
||||
group = session.query(Group).get(group_id)
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
await context.bot.send_photo(chat_id=group.link, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
session.close()
|
||||
await query.edit_message_text('Пост отправлен!')
|
||||
return ConversationHandler.END
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('new_post', new_post_start)],
|
||||
states={
|
||||
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
||||
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
73
.history/handlers/new_post_20250904013938.py
Normal file
73
.history/handlers/new_post_20250904013938.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters, CallbackQueryHandler, ContextTypes
|
||||
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
||||
|
||||
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
||||
return SELECT_MEDIA
|
||||
|
||||
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if update.message.photo:
|
||||
context.user_data['photo'] = update.message.photo[-1].file_id
|
||||
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
||||
return SELECT_TEXT
|
||||
|
||||
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['text'] = update.message.text or update.message.caption
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([InlineKeyboardButton(f'Канал: {c.name}', callback_data=f'channel_{c.id}')])
|
||||
for g in groups:
|
||||
keyboard.append([InlineKeyboardButton(f'Группа: {g.name}', callback_data=f'group_{g.id}')])
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
session = SessionLocal()
|
||||
try:
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
channel = session.query(Channel).get(channel_id)
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
chat_id = channel.link.strip()
|
||||
else:
|
||||
group_id = int(data.split('_')[1])
|
||||
group = session.query(Group).get(group_id)
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
chat_id = group.link.strip()
|
||||
# Проверка chat_id
|
||||
if not (chat_id.startswith('@') or chat_id.startswith('-')):
|
||||
await query.edit_message_text('Ошибка: ссылка должна быть username (@channel) или числовой ID (-100...)')
|
||||
return ConversationHandler.END
|
||||
try:
|
||||
await context.bot.send_photo(chat_id=chat_id, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
await query.edit_message_text('Пост отправлен!')
|
||||
except Exception as e:
|
||||
await query.edit_message_text(f'Ошибка отправки поста: {e}')
|
||||
finally:
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('new_post', new_post_start)],
|
||||
states={
|
||||
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
||||
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
73
.history/handlers/new_post_20250904013952.py
Normal file
73
.history/handlers/new_post_20250904013952.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from telegram import Update, InputMediaPhoto, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from telegram.ext import ContextTypes, ConversationHandler, MessageHandler, CommandHandler, filters, CallbackQueryHandler, ContextTypes
|
||||
|
||||
from db import SessionLocal
|
||||
from models import Channel, Group, Button
|
||||
|
||||
SELECT_MEDIA, SELECT_TEXT, SELECT_TARGET = range(3)
|
||||
|
||||
async def new_post_start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
await update.message.reply_text('Отправьте картинку для поста или /skip:')
|
||||
return SELECT_MEDIA
|
||||
|
||||
async def select_media(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
if update.message.photo:
|
||||
context.user_data['photo'] = update.message.photo[-1].file_id
|
||||
await update.message.reply_text('Введите текст поста или пересланное сообщение:')
|
||||
return SELECT_TEXT
|
||||
|
||||
async def select_text(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
context.user_data['text'] = update.message.text or update.message.caption
|
||||
session = SessionLocal()
|
||||
channels = session.query(Channel).all()
|
||||
groups = session.query(Group).all()
|
||||
session.close()
|
||||
keyboard = []
|
||||
for c in channels:
|
||||
keyboard.append([InlineKeyboardButton(f'Канал: {c.name}', callback_data=f'channel_{c.id}')])
|
||||
for g in groups:
|
||||
keyboard.append([InlineKeyboardButton(f'Группа: {g.name}', callback_data=f'group_{g.id}')])
|
||||
reply_markup = InlineKeyboardMarkup(keyboard)
|
||||
await update.message.reply_text('Выберите, куда отправить пост:', reply_markup=reply_markup)
|
||||
return SELECT_TARGET
|
||||
|
||||
async def select_target(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.callback_query
|
||||
await query.answer()
|
||||
data = query.data
|
||||
session = SessionLocal()
|
||||
try:
|
||||
if data.startswith('channel_'):
|
||||
channel_id = int(data.split('_')[1])
|
||||
channel = session.query(Channel).get(channel_id)
|
||||
buttons = session.query(Button).filter_by(channel_id=channel_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
chat_id = channel.link.strip()
|
||||
else:
|
||||
group_id = int(data.split('_')[1])
|
||||
group = session.query(Group).get(group_id)
|
||||
buttons = session.query(Button).filter_by(group_id=group_id).all()
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(b.name, url=b.url)] for b in buttons]) if buttons else None
|
||||
chat_id = group.link.strip()
|
||||
# Проверка chat_id
|
||||
if not (chat_id.startswith('@') or chat_id.startswith('-')):
|
||||
await query.edit_message_text('Ошибка: ссылка должна быть username (@channel) или числовой ID (-100...)')
|
||||
return ConversationHandler.END
|
||||
try:
|
||||
await context.bot.send_photo(chat_id=chat_id, photo=context.user_data.get('photo'), caption=context.user_data.get('text'), reply_markup=markup)
|
||||
await query.edit_message_text('Пост отправлен!')
|
||||
except Exception as e:
|
||||
await query.edit_message_text(f'Ошибка отправки поста: {e}')
|
||||
finally:
|
||||
session.close()
|
||||
return ConversationHandler.END
|
||||
|
||||
new_post_conv = ConversationHandler(
|
||||
entry_points=[CommandHandler('new_post', new_post_start)],
|
||||
states={
|
||||
SELECT_MEDIA: [MessageHandler(filters.PHOTO | filters.Document.IMAGE | filters.COMMAND, select_media)],
|
||||
SELECT_TEXT: [MessageHandler(filters.TEXT | filters.FORWARDED, select_text)],
|
||||
SELECT_TARGET: [CallbackQueryHandler(select_target)],
|
||||
},
|
||||
fallbacks=[]
|
||||
)
|
||||
2
.history/handlers/send_post_20250903223446.py
Normal file
2
.history/handlers/send_post_20250903223446.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Заглушка для будущей реализации отправки поста вручную
|
||||
# Можно реализовать выбор поста и канал/группу для отправки
|
||||
2
.history/handlers/send_post_20250904013103.py
Normal file
2
.history/handlers/send_post_20250904013103.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# Заглушка для будущей реализации отправки поста вручную
|
||||
# Можно реализовать выбор поста и канал/группу для отправки
|
||||
39
.history/main_20250903222258.py
Normal file
39
.history/main_20250903222258.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import logging
|
||||
import os
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from dotenv import load_dotenv
|
||||
from db import SessionLocal, init_db
|
||||
from models import Admin, Channel, Group, Button
|
||||
|
||||
load_dotenv()
|
||||
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
user_id = update.effective_user.id
|
||||
admin = session.query(Admin).filter_by(tg_id=user_id).first()
|
||||
if not admin:
|
||||
admin = Admin(tg_id=user_id)
|
||||
session.add(admin)
|
||||
session.commit()
|
||||
await update.message.reply_text('Вы зарегистрированы как админ.')
|
||||
else:
|
||||
await update.message.reply_text('Вы уже зарегистрированы.')
|
||||
session.close()
|
||||
|
||||
# ...handlers for add_channel, add_group, add_button, new_post, etc. будут добавлены...
|
||||
|
||||
def main():
|
||||
application = Application.builder().token(TELEGRAM_TOKEN).build()
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
# ...add other handlers...
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
48
.history/main_20250903222436.py
Normal file
48
.history/main_20250903222436.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import logging
|
||||
import os
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from dotenv import load_dotenv
|
||||
from db import SessionLocal, init_db
|
||||
from models import Admin, Channel, Group, Button
|
||||
|
||||
load_dotenv()
|
||||
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
user_id = update.effective_user.id
|
||||
admin = session.query(Admin).filter_by(tg_id=user_id).first()
|
||||
if not admin:
|
||||
admin = Admin(tg_id=user_id)
|
||||
session.add(admin)
|
||||
session.commit()
|
||||
await update.message.reply_text('Вы зарегистрированы как админ.')
|
||||
else:
|
||||
await update.message.reply_text('Вы уже зарегистрированы.')
|
||||
session.close()
|
||||
|
||||
|
||||
# Импорт обработчиков
|
||||
from handlers.add_channel import add_channel
|
||||
from handlers.add_group import add_group
|
||||
from handlers.add_button import add_button_conv
|
||||
from handlers.new_post import new_post_conv
|
||||
|
||||
def main():
|
||||
|
||||
application = Application.builder().token(TELEGRAM_TOKEN).build()
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
application.add_handler(CommandHandler('add_channel', add_channel))
|
||||
application.add_handler(CommandHandler('add_group', add_group))
|
||||
application.add_handler(add_button_conv)
|
||||
application.add_handler(new_post_conv)
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
48
.history/main_20250903222550.py
Normal file
48
.history/main_20250903222550.py
Normal file
@@ -0,0 +1,48 @@
|
||||
import logging
|
||||
import os
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from dotenv import load_dotenv
|
||||
from db import SessionLocal, init_db
|
||||
from models import Admin, Channel, Group, Button
|
||||
|
||||
load_dotenv()
|
||||
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
user_id = update.effective_user.id
|
||||
admin = session.query(Admin).filter_by(tg_id=user_id).first()
|
||||
if not admin:
|
||||
admin = Admin(tg_id=user_id)
|
||||
session.add(admin)
|
||||
session.commit()
|
||||
await update.message.reply_text('Вы зарегистрированы как админ.')
|
||||
else:
|
||||
await update.message.reply_text('Вы уже зарегистрированы.')
|
||||
session.close()
|
||||
|
||||
|
||||
# Импорт обработчиков
|
||||
from handlers.add_channel import add_channel
|
||||
from handlers.add_group import add_group
|
||||
from handlers.add_button import add_button_conv
|
||||
from handlers.new_post import new_post_conv
|
||||
|
||||
def main():
|
||||
|
||||
application = Application.builder().token(TELEGRAM_TOKEN).build()
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
application.add_handler(CommandHandler('add_channel', add_channel))
|
||||
application.add_handler(CommandHandler('add_group', add_group))
|
||||
application.add_handler(add_button_conv)
|
||||
application.add_handler(new_post_conv)
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
56
.history/main_20250903223508.py
Normal file
56
.history/main_20250903223508.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import logging
|
||||
import os
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from dotenv import load_dotenv
|
||||
from db import SessionLocal, init_db
|
||||
from models import Admin, Channel, Group, Button
|
||||
|
||||
load_dotenv()
|
||||
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
user_id = update.effective_user.id
|
||||
admin = session.query(Admin).filter_by(tg_id=user_id).first()
|
||||
if not admin:
|
||||
admin = Admin(tg_id=user_id)
|
||||
session.add(admin)
|
||||
session.commit()
|
||||
await update.message.reply_text('Вы зарегистрированы как админ.')
|
||||
else:
|
||||
await update.message.reply_text('Вы уже зарегистрированы.')
|
||||
session.close()
|
||||
|
||||
|
||||
# Импорт обработчиков
|
||||
from handlers.add_channel import add_channel
|
||||
from handlers.add_group import add_group
|
||||
from handlers.add_button import add_button_conv
|
||||
from handlers.new_post import new_post_conv
|
||||
from handlers.group_buttons import group_buttons_conv
|
||||
from handlers.channel_buttons import channel_buttons_conv
|
||||
from handlers.edit_button import edit_button
|
||||
from handlers.del_button import del_button
|
||||
|
||||
def main():
|
||||
|
||||
application = Application.builder().token(TELEGRAM_TOKEN).build()
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
application.add_handler(CommandHandler('add_channel', add_channel))
|
||||
application.add_handler(CommandHandler('add_group', add_group))
|
||||
application.add_handler(add_button_conv)
|
||||
application.add_handler(new_post_conv)
|
||||
application.add_handler(group_buttons_conv)
|
||||
application.add_handler(channel_buttons_conv)
|
||||
application.add_handler(CommandHandler('edit_button', edit_button))
|
||||
application.add_handler(CommandHandler('del_button', del_button))
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
56
.history/main_20250904013103.py
Normal file
56
.history/main_20250904013103.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import logging
|
||||
import os
|
||||
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackQueryHandler, ConversationHandler, ContextTypes
|
||||
from dotenv import load_dotenv
|
||||
from db import SessionLocal, init_db
|
||||
from models import Admin, Channel, Group, Button
|
||||
|
||||
load_dotenv()
|
||||
TELEGRAM_TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
init_db()
|
||||
|
||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
session = SessionLocal()
|
||||
user_id = update.effective_user.id
|
||||
admin = session.query(Admin).filter_by(tg_id=user_id).first()
|
||||
if not admin:
|
||||
admin = Admin(tg_id=user_id)
|
||||
session.add(admin)
|
||||
session.commit()
|
||||
await update.message.reply_text('Вы зарегистрированы как админ.')
|
||||
else:
|
||||
await update.message.reply_text('Вы уже зарегистрированы.')
|
||||
session.close()
|
||||
|
||||
|
||||
# Импорт обработчиков
|
||||
from handlers.add_channel import add_channel
|
||||
from handlers.add_group import add_group
|
||||
from handlers.add_button import add_button_conv
|
||||
from handlers.new_post import new_post_conv
|
||||
from handlers.group_buttons import group_buttons_conv
|
||||
from handlers.channel_buttons import channel_buttons_conv
|
||||
from handlers.edit_button import edit_button
|
||||
from handlers.del_button import del_button
|
||||
|
||||
def main():
|
||||
|
||||
application = Application.builder().token(TELEGRAM_TOKEN).build()
|
||||
application.add_handler(CommandHandler('start', start))
|
||||
application.add_handler(CommandHandler('add_channel', add_channel))
|
||||
application.add_handler(CommandHandler('add_group', add_group))
|
||||
application.add_handler(add_button_conv)
|
||||
application.add_handler(new_post_conv)
|
||||
application.add_handler(group_buttons_conv)
|
||||
application.add_handler(channel_buttons_conv)
|
||||
application.add_handler(CommandHandler('edit_button', edit_button))
|
||||
application.add_handler(CommandHandler('del_button', del_button))
|
||||
application.run_polling()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
33
.history/models_20250903222255.py
Normal file
33
.history/models_20250903222255.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, Text
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Admin(Base):
|
||||
__tablename__ = 'admins'
|
||||
id = Column(Integer, primary_key=True)
|
||||
tg_id = Column(Integer, unique=True, nullable=False)
|
||||
|
||||
class Channel(Base):
|
||||
__tablename__ = 'channels'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
link = Column(String, nullable=False)
|
||||
buttons = relationship('Button', back_populates='channel')
|
||||
|
||||
class Group(Base):
|
||||
__tablename__ = 'groups'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
link = Column(String, nullable=False)
|
||||
buttons = relationship('Button', back_populates='group')
|
||||
|
||||
class Button(Base):
|
||||
__tablename__ = 'buttons'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
url = Column(String, nullable=False)
|
||||
channel_id = Column(Integer, ForeignKey('channels.id'), nullable=True)
|
||||
group_id = Column(Integer, ForeignKey('groups.id'), nullable=True)
|
||||
channel = relationship('Channel', back_populates='buttons')
|
||||
group = relationship('Group', back_populates='buttons')
|
||||
33
.history/models_20250903222550.py
Normal file
33
.history/models_20250903222550.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from sqlalchemy import Column, Integer, String, ForeignKey, Text
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class Admin(Base):
|
||||
__tablename__ = 'admins'
|
||||
id = Column(Integer, primary_key=True)
|
||||
tg_id = Column(Integer, unique=True, nullable=False)
|
||||
|
||||
class Channel(Base):
|
||||
__tablename__ = 'channels'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
link = Column(String, nullable=False)
|
||||
buttons = relationship('Button', back_populates='channel')
|
||||
|
||||
class Group(Base):
|
||||
__tablename__ = 'groups'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
link = Column(String, nullable=False)
|
||||
buttons = relationship('Button', back_populates='group')
|
||||
|
||||
class Button(Base):
|
||||
__tablename__ = 'buttons'
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False)
|
||||
url = Column(String, nullable=False)
|
||||
channel_id = Column(Integer, ForeignKey('channels.id'), nullable=True)
|
||||
group_id = Column(Integer, ForeignKey('groups.id'), nullable=True)
|
||||
channel = relationship('Channel', back_populates='buttons')
|
||||
group = relationship('Group', back_populates='buttons')
|
||||
4
.history/requirements_20250903222620.txt
Normal file
4
.history/requirements_20250903222620.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
python-telegram-bot>=20.0
|
||||
sqlalchemy>=2.0
|
||||
python-dotenv>=1.0
|
||||
pytest>=7.0
|
||||
4
.history/requirements_20250903222628.txt
Normal file
4
.history/requirements_20250903222628.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
python-telegram-bot>=20.0
|
||||
sqlalchemy>=2.0
|
||||
python-dotenv>=1.0
|
||||
pytest>=7.0
|
||||
Reference in New Issue
Block a user