bafifi4972's picture
Create app.py
21ced4e verified
import os
import logging
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command
from aiogram.utils.keyboard import InlineKeyboardBuilder
from deep_translator import GoogleTranslator
import sqlite3
from datetime import datetime
from dotenv import load_dotenv
# Загрузка переменных окружения
load_dotenv()
API_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
# Инициализация бота
bot = Bot(API_TOKEN)
dp = Dispatcher()
logging.basicConfig(level=logging.INFO)
# Инициализация БД
DB_NAME = 'translator_bot.db'
def init_db():
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS users
(user_id INT PRIMARY KEY,
target_lang TEXT DEFAULT 'en',
active INT DEFAULT 1)''')
c.execute('''CREATE TABLE IF NOT EXISTS history
(id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INT,
original TEXT,
translated TEXT,
direction TEXT,
timestamp DATETIME)''')
conn.commit()
conn.close()
init_db()
# Языки с эмодзи
LANGUAGES = {
'en': '🇬🇧 Английский',
'es': '🇪🇸 Испанский',
'fr': '🇫🇷 Французский',
'de': '🇩🇪 Немецкий',
'zh-CN': '🇨🇳 Китайский',
'ja': '🇯🇵 Японский',
'ru': '🇷🇺 Русский',
'ar': '🇦🇪 Арабский',
'hi': '🇮🇳 Хинди',
'ko': '🇰🇷 Корейский',
'it': '🇮🇹 Итальянский',
'pt': '🇵🇹 Португальский',
'tr': '🇹🇷 Турецкий'
}
# Клавиатуры
def main_keyboard():
builder = InlineKeyboardBuilder()
builder.button(text="⚙️ Настройки", callback_data="settings")
builder.button(text="📜 История", callback_data="history")
builder.button(text="❌ Выключить", callback_data="toggle_off")
builder.button(text="✅ Включить", callback_data="toggle_on")
builder.adjust(2)
return builder.as_markup()
def settings_keyboard():
builder = InlineKeyboardBuilder()
for code, name in LANGUAGES.items():
builder.button(text=name, callback_data=f"set_{code}")
builder.button(text="🔙 Назад", callback_data="main_menu")
builder.adjust(3)
return builder.as_markup()
# Управление пользователями
def get_user_settings(user_id):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute("SELECT target_lang, active FROM users WHERE user_id=?", (user_id,))
user = c.fetchone()
conn.close()
if user:
return {'target_lang': user[0], 'active': bool(user[1])}
else:
# Создаем нового пользователя
set_user_settings(user_id, 'en', 1)
return {'target_lang': 'en', 'active': True}
def set_user_settings(user_id, target_lang=None, active=None):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute("SELECT * FROM users WHERE user_id=?", (user_id,))
user = c.fetchone()
if user:
if target_lang:
c.execute("UPDATE users SET target_lang=? WHERE user_id=?",
(target_lang, user_id))
if active is not None:
c.execute("UPDATE users SET active=? WHERE user_id=?",
(int(active), user_id))
else:
c.execute("INSERT INTO users (user_id, target_lang, active) VALUES (?, ?, ?)",
(user_id, target_lang or 'en', int(active) if active is not None else 1))
conn.commit()
conn.close()
def save_history(user_id, original, translated, direction):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute("INSERT INTO history (user_id, original, translated, direction, timestamp) VALUES (?, ?, ?, ?, ?)",
(user_id, original, translated, direction, datetime.now()))
conn.commit()
conn.close()
def get_history(user_id, limit=10):
conn = sqlite3.connect(DB_NAME)
c = conn.cursor()
c.execute("SELECT original, translated, direction, timestamp FROM history WHERE user_id=? ORDER BY timestamp DESC LIMIT ?",
(user_id, limit))
history = c.fetchall()
conn.close()
return history
# Обработчики команд
@dp.message(Command('start'))
async def start_cmd(message: types.Message):
user_id = message.from_user.id
set_user_settings(user_id, active=1)
welcome_text = (
"🚀 <b>Ultra Translator</b> - мгновенный переводчик\n\n"
"Просто отправьте текст и получите перевод!\n\n"
"• Автоопределение языка\n"
"• Поддержка 15+ языков\n"
"• История переводов\n\n"
"⚙️ Настройте язык перевода через меню"
)
await message.answer(welcome_text,
reply_markup=main_keyboard(),
parse_mode='HTML')
@dp.message(Command('toggle'))
async def toggle_cmd(message: types.Message):
user_id = message.from_user.id
settings = get_user_settings(user_id)
new_status = not settings['active']
set_user_settings(user_id, active=new_status)
if new_status:
await message.answer("✅ Переводчик включен. Отправьте текст для перевода!")
else:
await message.answer("❌ Переводчик выключен. Используйте /toggle для включения.")
# Основной обработчик текста
@dp.message(F.text)
async def handle_text(message: types.Message):
user_id = message.from_user.id
settings = get_user_settings(user_id)
# Проверка активности
if not settings['active']:
return
text = message.text
target_lang = settings['target_lang']
# Перевод
try:
# Автоопределение языка и перевод
translated = GoogleTranslator(source='auto', target=target_lang).translate(text)
# Определение языка источника
detected_lang = GoogleTranslator(source='auto').detect(text)
lang_name = LANGUAGES.get(detected_lang, detected_lang)
# Сохранение в историю
direction = f"{detected_lang}{target_lang}"
save_history(user_id, text, translated, direction)
# Форматирование ответа
response = (
f"🌐 Перевод (<b>{lang_name}{LANGUAGES[target_lang]}</b>):\n"
f"{translated}"
)
await message.reply(response, parse_mode='HTML')
except Exception as e:
logging.error(f"Translation error: {e}")
await message.reply("⚠️ Ошибка перевода. Попробуйте другой текст.")
# Обработчики инлайн-кнопок
@dp.callback_query(F.data == "settings")
async def settings_menu(callback: types.CallbackQuery):
user_id = callback.from_user.id
settings = get_user_settings(user_id)
current_lang = LANGUAGES.get(settings['target_lang'], settings['target_lang'])
await callback.message.edit_text(
f"⚙️ <b>Настройки</b>\nТекущий язык: {current_lang}\nВыберите новый язык:",
reply_markup=settings_keyboard(),
parse_mode='HTML'
)
await callback.answer()
@dp.callback_query(F.data == "history")
async def show_history(callback: types.CallbackQuery):
user_id = callback.from_user.id
history = get_history(user_id)
if not history:
await callback.message.answer("📭 История переводов пуста")
await callback.answer()
return
response = "🕒 <b>Последние переводы</b>:\n\n"
for i, (original, translated, direction, timestamp) in enumerate(history):
response += f"▫️ {original[:50]}{'...' if len(original) > 50 else ''}\n"
response += f" → {translated[:50]}{'...' if len(translated) > 50 else ''}\n\n"
await callback.message.answer(response, parse_mode='HTML')
await callback.answer()
@dp.callback_query(F.data.startswith("set_"))
async def set_language(callback: types.CallbackQuery):
lang_code = callback.data.split('_')[1]
user_id = callback.from_user.id
if lang_code in LANGUAGES:
set_user_settings(user_id, target_lang=lang_code)
lang_name = LANGUAGES[lang_code]
await callback.answer(f"✅ Язык перевода: {lang_name}")
else:
await callback.answer("⚠️ Неподдерживаемый язык")
# Возвращаемся в главное меню
await callback.message.edit_text(
"Настройки сохранены!",
reply_markup=main_keyboard()
)
@dp.callback_query(F.data == "main_menu")
async def main_menu(callback: types.CallbackQuery):
await callback.message.edit_text(
"Выберите действие:",
reply_markup=main_keyboard()
)
await callback.answer()
@dp.callback_query(F.data == "toggle_on")
async def toggle_on(callback: types.CallbackQuery):
user_id = callback.from_user.id
set_user_settings(user_id, active=True)
await callback.answer("✅ Переводчик включен")
await main_menu(callback)
@dp.callback_query(F.data == "toggle_off")
async def toggle_off(callback: types.CallbackQuery):
user_id = callback.from_user.id
set_user_settings(user_id, active=False)
await callback.answer("❌ Переводчик выключен")
await main_menu(callback)
# Запуск бота
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
import asyncio
asyncio.run(main())