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()) |