Spaces:
Runtime error
Runtime error
| 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 | |
| # Обработчики команд | |
| 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') | |
| 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 для включения.") | |
| # Основной обработчик текста | |
| 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("⚠️ Ошибка перевода. Попробуйте другой текст.") | |
| # Обработчики инлайн-кнопок | |
| 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() | |
| 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() | |
| 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() | |
| ) | |
| async def main_menu(callback: types.CallbackQuery): | |
| await callback.message.edit_text( | |
| "Выберите действие:", | |
| reply_markup=main_keyboard() | |
| ) | |
| await callback.answer() | |
| 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) | |
| 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()) |