From 0a9eb611435d27fca0c0ee66bfd539b0815fd1e4 Mon Sep 17 00:00:00 2001 From: drel Date: Thu, 30 Oct 2025 19:06:36 +0300 Subject: [PATCH] =?UTF-8?q?=D1=8B=D1=8B=D1=8B=D1=8B=D1=8B=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/localization.cpython-310.pyc | Bin 562 -> 3029 bytes furry.db | Bin 8192 -> 20480 bytes localization.py | 33 ++++- main.py | 175 ++++++++++++++++++++++- 4 files changed, 200 insertions(+), 8 deletions(-) diff --git a/__pycache__/localization.cpython-310.pyc b/__pycache__/localization.cpython-310.pyc index 73d06a98b95cc4056535d8160775402ffcd5a945..1f5100571c4feafc9cc90c9a238eaad4732c0e20 100644 GIT binary patch literal 3029 zcma);Piz!b9LIOJ1!`#p%2x0Xn zmHEq(&4RrGHp}-(b``7#>?+?MF^2VZFpAZ6-YeM+FpA3!en7GXFpA3pe^s(N7{#T| z4@!0qjN)>Szb4szFpA54{<>rjz$h*c_#w$2f>B%^@;=EPfl*u@@qWo3gHc=_^TP@I zDQ#^9MPz8jk2LWva6|{Zi|3j+Wgig&@8JVY{4hA81b&z+qbWX!x;uIz%vf&N>ImC$ zyHRfbwcw&(^XL6)P|h*`u3rl-_J&(%|CrlG2mbc!{)%4-+ibT`&{d=8zDxLea5=aX zT=EwoeTM~e{_SAKUu6DG{46orgj6;7&R_QH%wNGRRcNpJ%fZk7a&NeOT+d+Egf!3v9HYh``?$0y)1wRC3tnaemTfc&3btr5%%zUiJb_YnuFB?xW z7y#cks8qt84HInP)jtyBb_P z&icsAIt+_qN!M0b1+1;4@27052& z4Yyzh6-R}Vhr}Y$Wq_3pjs z3W^>2%CWR!QCMFeT3@J9QLn~t36`N)la#5tB~(707gMNO+kNZliV?di8F-np9~n9i zXHbhuxLel1qs_$)5_YBo%2@={+fYQo%KcBe&KUPN7p7d!H>49ob+H?TAsidItHjNBwpLzI;tTfG+U`7gT+Sdc?n<{R^W);uc z`|_eEq>#~F@R>5O@s=UhXr~Ws|P$u#LNPl)|hwu2a0vPpuB3L7y2{$dOY~?(CJT1>#SW;F^W%*xRy2jzUiDEr^Oj8bhDu9nx{INX(*-XaBERG zP(%L=+r#+Ewq(!0I{IBTDqdx=7q$&gn%vdJ@ig5> Imv*H81CAaOlmGw# delta 171 zcmcaAzKMk|pO=@50SKaZKF{E1n#kwDl*2GF!cm_io2f{nhB1W+M5k~DGt@AofW(Y| zVr)R#B!w%OA%y{gHMu8mVd|J%z~L;ll0lQ{7E4ZIUV0RJaY<2LVs2^?8_@hBw#jnb pHinEqW--V@5oQraAY_(dEaC)m{WKvoR4rHoh~SvKms^~X0RU?&BP;*_ diff --git a/furry.db b/furry.db index 68dc37b6498c0c044cd85d1f83f1528a105b64b5..83b1280d234afd13d3ebd75e8b0c0438da7e4b67 100644 GIT binary patch literal 20480 zcmeI)OHUI)00;2dZp%w?B@qd!2@4k>pa}wrcycJKR%oFwXuWKfvb0OvZE2@cJPF}w z!bkAv#e=9M8jTmf!1k!0fW&wp+^N&j0&S`$o(TC*x|x}s_is-#yJ^5TXE0q}O=nXY zlgG(*A_(MxEE7Un`Q_kOE!cR%Ud!-UIG6rYvX$IXZ*@urv3I^9(t78ybe|^>AOHaf zKmY;|fB*y_009U<;I9G;_LiQJ5h22~<)oflPx6hMn$y?wx*2WEI$VB*1{FC-r{@&8 zq3)2WrSwtWa(H{n*4pEA3OnvfpQ}ca>DgR066^Y?-js(r)@<{Q^3x2nU z`XlnJ5|L>rIPdoI_8!F>9Ia~+jce?zRec%D8nKw3m4iySu~ph+y2(_wnbDgRGrhpn z=t-R>#eD9%$_H)Iua;p(+H6u1^16K?W$0wOqjGg>!>4N*zAd)&P^Ul)b44#yg|$3O zSMq9=OC75w${Xjl^3&bADzx_W^$AE`QS z_5>{V@5QgXI+%KXv|INCV#z7 z12fBdE<&l>mAIRjiL>~`nwrxxv(qVmCY+e}gvOpNrZh@tr(!YcGIUoVFr_Zv3wsjb zWFhH|`O*R(tiNtB>vM6pxLthtj{)N;KH$9hWYYJTWfrC;#{EkHe`bS4*5(%}om(?} z)b)HN|1>bZG#T9p7dFE=g%8-lpQE z0^N2;ztDJoA$Hjvy|ufQ0}I;?Ua!4cZ?AT$aPs~C5s{8A=Hf6b2tWV=5P$##AOHaf XKmY;|fB*#kOW=wiI)&=r5{SP6lIKJC delta 78 zcmZozz}Vn0L0XWLfq{Vuh+%+nqK+{?Cxc$R3@=cKkw1rlKWDR`z&}2&MnOh)ad~;h Z#=^ (в ответ на сообщение)" + if lang == "ru" and strname == "filter_reply_required": return "Вы должны ответить на сообщение для установки фильтра." + if lang == "ru" and strname == "filter_unsupported_type": return "Неподдерживаемый тип сообщения. Поддерживаются: текст, фото, видео, документы, аудио, голосовые, стикеры." + if lang == "ru" and strname == "filter_set_success": return "Фильтр '{trigger}' успешно установлен!" + if lang == "ru" and strname == "filter_already_exists": return "Фильтр '{trigger}' уже существует." + if lang == "ru" and strname == "filter_remove_usage": return "Использование: /filter remove <триггер>" + if lang == "ru" and strname == "filter_remove_success": return "Фильтр '{trigger}' успешно удален." + if lang == "ru" and strname == "filter_not_found": return "Фильтр '{trigger}' не найден." + if lang == "ru" and strname == "filter_send_error": return "Ошибка при отправке медиа." + if lang == "ru" and strname == "filter_usage": return "Использование:\n/filter - показать все фильтры\n/filter set <триггер> - установить фильтр (в ответ на сообщение)\n/filter remove <триггер> - удалить фильтр" # ======== ENGLISH ======== if lang == "en" and strname == "test": return "Hello, world!" - if lang == "en" and strname == "succlang": return "English language has been successfully applied!" \ No newline at end of file + if lang == "en" and strname == "succlang": return "English language has been successfully applied!" + + # ======== FILTERS ENGLISH ======== + if lang == "en" and strname == "filter_list": return "Filters in this chat:" + if lang == "en" and strname == "no_filters": return "No filters in this chat." + if lang == "en" and strname == "filter_set_usage": return "Usage: /filter set (reply to a message)" + if lang == "en" and strname == "filter_reply_required": return "You must reply to a message to set a filter." + if lang == "en" and strname == "filter_unsupported_type": return "Unsupported message type. Supported: text, photos, videos, documents, audio, voice, stickers." + if lang == "en" and strname == "filter_set_success": return "Filter '{trigger}' set successfully!" + if lang == "en" and strname == "filter_already_exists": return "Filter '{trigger}' already exists." + if lang == "en" and strname == "filter_remove_usage": return "Usage: /filter remove " + if lang == "en" and strname == "filter_remove_success": return "Filter '{trigger}' removed successfully." + if lang == "en" and strname == "filter_not_found": return "Filter '{trigger}' not found." + if lang == "en" and strname == "filter_send_error": return "Error sending media." + if lang == "en" and strname == "filter_usage": return "Usage:\n/filter - show all filters\n/filter set - set filter (reply to a message)\n/filter remove - remove filter" + + return "String not found" \ No newline at end of file diff --git a/main.py b/main.py index 355f479..e264ed8 100644 --- a/main.py +++ b/main.py @@ -1,10 +1,12 @@ +# main.py import logging import localization as lang from telegram import Update -from telegram.ext import Application, CommandHandler, ContextTypes +from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes import os import sqlite3 + # Enable logging logging.basicConfig( format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO @@ -17,10 +19,22 @@ cursor = conn.cursor() def init_db(): cursor.execute(''' CREATE TABLE IF NOT EXISTS user_lang ( - chatid INTEGER PRIMARY KEY NULL, + chatid INTEGER PRIMARY KEY, lang TEXT DEFAULT 'no' ) ''') + cursor.execute(''' + CREATE TABLE IF NOT EXISTS filters ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + chatid INTEGER, + trigger TEXT, + content_type TEXT, + text_content TEXT, + file_id TEXT, + caption TEXT, + UNIQUE(chatid, trigger) + ) + ''') conn.commit() init_db() @@ -54,11 +68,11 @@ async def set_lang(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: try: userlang = str(context.args[0]) try: - cursor.execute("INSERT INTO user_lang (chatid, lang) VALUES (?, ?)", (chat_id, userlang)) # omfg + cursor.execute("INSERT INTO user_lang (chatid, lang) VALUES (?, ?)", (chat_id, userlang)) except: - fuckinnothing = "fuckinnothing" + pass - cursor.execute("UPDATE user_lang SET lang = ? WHERE chatid = ?", (userlang, chat_id)) # omfg + cursor.execute("UPDATE user_lang SET lang = ? WHERE chatid = ?", (userlang, chat_id)) conn.commit() cursor.execute("SELECT lang FROM user_lang WHERE chatid = ?", (chat_id,)) row = cursor.fetchone() @@ -66,14 +80,161 @@ async def set_lang(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: except: await update.message.reply_text('/lang en\n/lang ru') +async def filtercmd(update: Update, context: ContextTypes.DEFAULT_TYPE): + chat = update.effective_chat + chat_id = chat.id + + cursor.execute("SELECT lang FROM user_lang WHERE chatid = ?", (chat_id,)) + row = cursor.fetchone() + user_lang = row[0] if row else "en" + + if not context.args: + cursor.execute("SELECT trigger, content_type FROM filters WHERE chatid = ?", (chat_id,)) + filters_list = cursor.fetchall() + + if filters_list: + filter_text = lang.getstr(user_lang, "filter_list") + "\n" + for i, (trigger, content_type) in enumerate(filters_list, 1): + type_emoji = { + 'text': '📝', + 'photo': '🖼', + 'video': '🎥', + 'document': '📎', + 'audio': '🎵', + 'voice': '🎤', + 'sticker': '🤡' + }.get(content_type, '❓') + filter_text += f"{i}. {type_emoji} {trigger}\n" + await update.message.reply_text(filter_text) + else: + await update.message.reply_text(lang.getstr(user_lang, "no_filters")) + return + + action = context.args[0].lower() + + if action == "set": + if len(context.args) < 2: + await update.message.reply_text(lang.getstr(user_lang, "filter_set_usage")) + return + + if not update.message.reply_to_message: + await update.message.reply_text(lang.getstr(user_lang, "filter_reply_required")) + return + + trigger = context.args[1].lower() + replied_message = update.message.reply_to_message + + content_type = 'text' + text_content = None + file_id = None + caption = None + + if replied_message.text: + content_type = 'text' + text_content = replied_message.text + elif replied_message.photo: + content_type = 'photo' + file_id = replied_message.photo[-1].file_id + caption = replied_message.caption + elif replied_message.video: + content_type = 'video' + file_id = replied_message.video.file_id + caption = replied_message.caption + elif replied_message.document: + content_type = 'document' + file_id = replied_message.document.file_id + caption = replied_message.caption + elif replied_message.audio: + content_type = 'audio' + file_id = replied_message.audio.file_id + caption = replied_message.caption + elif replied_message.voice: + content_type = 'voice' + file_id = replied_message.voice.file_id + elif replied_message.sticker: + content_type = 'sticker' + file_id = replied_message.sticker.file_id + else: + await update.message.reply_text(lang.getstr(user_lang, "filter_unsupported_type")) + return + + try: + cursor.execute( + "INSERT INTO filters (chatid, trigger, content_type, text_content, file_id, caption) VALUES (?, ?, ?, ?, ?, ?)", + (chat_id, trigger, content_type, text_content, file_id, caption) + ) + conn.commit() + await update.message.reply_text(lang.getstr(user_lang, "filter_set_success").format(trigger=trigger)) + except sqlite3.IntegrityError: + await update.message.reply_text(lang.getstr(user_lang, "filter_already_exists").format(trigger=trigger)) + + elif action == "remove": + if len(context.args) < 2: + await update.message.reply_text(lang.getstr(user_lang, "filter_remove_usage")) + return + + trigger = context.args[1].lower() + + cursor.execute("DELETE FROM filters WHERE chatid = ? AND trigger = ?", (chat_id, trigger)) + conn.commit() + + if cursor.rowcount > 0: + await update.message.reply_text(lang.getstr(user_lang, "filter_remove_success").format(trigger=trigger)) + else: + await update.message.reply_text(lang.getstr(user_lang, "filter_not_found").format(trigger=trigger)) + + else: + await update.message.reply_text(lang.getstr(user_lang, "filter_usage")) + +async def handle_messages(update: Update, context: ContextTypes.DEFAULT_TYPE): + if update.message.text and update.message.text.startswith('/'): + return + + if update.message.from_user.is_bot: + return + + chat = update.effective_chat + chat_id = chat.id + message_text = update.message.text or update.message.caption or "" + + if not message_text: + return + + cursor.execute("SELECT trigger, content_type, text_content, file_id, caption FROM filters WHERE chatid = ?", (chat_id,)) + filters_list = cursor.fetchall() + + for trigger, content_type, text_content, file_id, caption in filters_list: + if trigger.lower() in message_text.lower(): + try: + if content_type == 'text': + await update.message.reply_text(text_content) + elif content_type == 'photo': + await update.message.reply_photo(file_id, caption=caption) + elif content_type == 'video': + await update.message.reply_video(file_id, caption=caption) + elif content_type == 'document': + await update.message.reply_document(file_id, caption=caption) + elif content_type == 'audio': + await update.message.reply_audio(file_id, caption=caption) + elif content_type == 'voice': + await update.message.reply_voice(file_id) + elif content_type == 'sticker': + await update.message.reply_sticker(file_id) + break # Only trigger one filter per message + except Exception as e: + logging.error(f"Error sending media: {e}") + await update.message.reply_text(lang.getstr("en", "filter_send_error")) + break + def main() -> None: application = Application.builder().token(bottoken).build() application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("lang", set_lang)) + application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_messages)) + application.add_handler(CommandHandler("filter", filtercmd)) application.run_polling(allowed_updates=Update.ALL_TYPES) - if __name__ == "__main__": - main() + main() \ No newline at end of file