Download plugins/settings.py from Thaimozhi/RenameBot: direct link, hf CLI and curl.
- Browser
- Download file 33.1 kB
-
https://huggingface.co/spaces/Thaimozhi/RenameBot/resolve/main/plugins/settings.py
- Command line
-
hf download hf://spaces/Thaimozhi/RenameBot/plugins/settings.py
-
curl -L -o settings.py https://huggingface.co/spaces/Thaimozhi/RenameBot/resolve/main/plugins/settings.py
33.1 kB
| import html | |
| from pyrogram import Client, filters | |
| from pyrogram.types import CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton | |
| from pyrogram.errors import MessageNotModified, MessageIdInvalid | |
| from helper.database import codeflixbots | |
| from plugins.file_rename import safe_answer # crash-proof query.answer() | |
| import pyromod.listen | |
| from pyromod.exceptions import ListenerTimeout | |
| # βββ Main Settings Menu ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def settings_menu(client, message): | |
| if not await codeflixbots.is_user_authorized(message.from_user.id): | |
| return await message.reply_text("<b>β You are not authorized to use this bot. Please contact the Owner/Admin to authorize you.</b>") | |
| await show_main_menu(client, message.chat.id, message.id, message.from_user.id) | |
| async def show_main_menu(client, chat_id, message_id, user_id, cb=None): | |
| use_metadata = await codeflixbots.get_metadata(user_id) | |
| remnames = await codeflixbots.get_remname_rules(user_id) | |
| rename_formats = await codeflixbots.get_rename_formats(user_id) | |
| is_reorder = await codeflixbots.get_is_audio_reorder(user_id) | |
| is_mediainfo = await codeflixbots.get_is_mediainfo(user_id) | |
| is_auto = await codeflixbots.get_is_auto_rename(user_id) | |
| auto_merge = await codeflixbots.get_auto_merge(user_id) | |
| merge_audio_reorder = await codeflixbots.get_merge_audio_reorder(user_id) | |
| keep_audio = await codeflixbots.get_keep_audio(user_id) | |
| thumb_size = await codeflixbots.get_thumb_size(user_id) | |
| upload_format = await codeflixbots.get_upload_format(user_id) | |
| auto_upload = await codeflixbots.get_auto_upload(user_id) | |
| _fmt_labels = {"auto": "π Auto", "video": "π¬ Video", "document": "π Document"} | |
| fmt_label = _fmt_labels.get(upload_format, "π Auto") | |
| markup = InlineKeyboardMarkup([ | |
| [ | |
| InlineKeyboardButton("π Caption", callback_data="set_ui_caption"), | |
| InlineKeyboardButton("βοΈ Prefix", callback_data="set_ui_prefix"), | |
| ], | |
| [ | |
| InlineKeyboardButton("βοΈ Suffix", callback_data="set_ui_suffix"), | |
| InlineKeyboardButton("π¨ Default Format", callback_data="set_ui_format"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"π Rename Formats ({len(rename_formats)})", callback_data="ui_rename_formats"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"π RemName Rules ({len(remnames)})", callback_data="set_ui_remnames"), | |
| ], | |
| [ | |
| InlineKeyboardButton("π΅ Audio Order", callback_data="set_ui_audioorder"), | |
| InlineKeyboardButton("π΅ Default Track", callback_data="set_ui_audiodefault"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"{'β ' if use_metadata else 'β'} Audio Metadata", callback_data="toggle_metadata"), | |
| InlineKeyboardButton(f"Auto-Rename: {'ON' if is_auto else 'OFF'}", callback_data="toggle_autorename"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"Reorder: {'ON β ' if is_reorder else 'OFF β'}", callback_data="toggle_audioreorder"), | |
| InlineKeyboardButton(f"MediaInfo: {'ON β ' if is_mediainfo else 'OFF β'}", callback_data="toggle_mediainfo"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"π§ Keep Audio: {keep_audio if keep_audio else 'ALL β '}", callback_data="set_ui_keepaudio"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"π§© Auto-Merge (zip): {'ON β ' if auto_merge else 'OFF β'}", callback_data="toggle_automerge"), | |
| ], | |
| [ | |
| InlineKeyboardButton("π΅ Merge Audio Order", callback_data="set_ui_mergeaudioorder"), | |
| InlineKeyboardButton(f"Merge Reorder: {'ON β ' if merge_audio_reorder else 'OFF β'}", callback_data="toggle_mergeaudioreorder"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"π€ Upload As: {fmt_label}", callback_data="cycle_upload_format"), | |
| InlineKeyboardButton(f"π Auto Upload: {'ON β ' if auto_upload else 'OFF β'}", callback_data="toggle_autoupload"), | |
| ], | |
| [ | |
| InlineKeyboardButton(f"πΌοΈ Thumb: {thumb_size}px", callback_data="ui_thumb_layout"), | |
| InlineKeyboardButton("βοΈ Trim / Split", callback_data="ui_trim_info"), | |
| ], | |
| [ | |
| InlineKeyboardButton("π₯ Import Config", callback_data="import_settings"), | |
| InlineKeyboardButton("π€ Export Config", callback_data="export_settings"), | |
| ], | |
| [ | |
| InlineKeyboardButton("π View All Settings", callback_data="view_settings"), | |
| InlineKeyboardButton("β Close", callback_data="close"), | |
| ] | |
| ]) | |
| text = ( | |
| "βοΈ **Advanced Settings Panel**\n\n" | |
| "Tap any button to configure your autofile renaming.\n\n" | |
| "*(For Auto Upload mode tweaks like Extract/Merge, Button Mode, setup /autoset)*" | |
| ) | |
| if cb: | |
| try: | |
| await cb.message.edit_text(text, reply_markup=markup) | |
| except (MessageNotModified, MessageIdInvalid): | |
| pass | |
| else: | |
| await client.send_message(chat_id, text, reply_markup=markup) | |
| # βββ Generic Prompt Handler ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def handle_set_ui(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| action = query.data.replace("set_ui_", "") | |
| if action == "remnames": | |
| remnames = await codeflixbots.get_remname_rules(user_id) | |
| text = f"**π RemName Rules** ({len(remnames)})\n\n" | |
| for i, rule in enumerate(remnames): | |
| find = html.escape(rule.get("find", "")) | |
| replace = html.escape(rule.get("replace", "")) | |
| text += f"`{i+1}. {find}` β `{replace}`\n" | |
| if not remnames: | |
| text += "_No rules added yet._" | |
| markup = InlineKeyboardMarkup([ | |
| [InlineKeyboardButton("β Add Rule", callback_data="add_remname_rule")], | |
| [InlineKeyboardButton("π Clear All", callback_data="clear_remname_rules")], | |
| [InlineKeyboardButton("β¬ οΈ Back", callback_data="settings_back")] | |
| ]) | |
| await query.message.edit_text(text, reply_markup=markup) | |
| return | |
| # Fetch current values for display | |
| current_values = { | |
| "caption": await codeflixbots.get_caption(user_id), | |
| "prefix": await codeflixbots.get_prefix(user_id), | |
| "suffix": await codeflixbots.get_suffix(user_id), | |
| "format": await codeflixbots.get_format_template(user_id), | |
| "audioorder": await codeflixbots.get_audio_order(user_id), | |
| "audiodefault": await codeflixbots.get_audio_default(user_id), | |
| "mergeaudioorder": await codeflixbots.get_merge_audio_order(user_id), | |
| "keepaudio": await codeflixbots.get_keep_audio(user_id), | |
| } | |
| current = current_values.get(action) | |
| current_text = f"\n\n**Current value:**\n`{html.escape(str(current))}`" if current else "\n\n_Not set yet._" | |
| prompts = { | |
| "caption": ( | |
| f"π **Set Custom Caption:**{current_text}\n\n" | |
| "**Variables:** `{filename}` (renamed name) | `{original_filename}` (upload name)\n" | |
| "`{size}` `{duration}` `{quality}` `{languages}` `{season}` `{episode}`\n\n" | |
| "**For Expandable Blockquote:** Use `<blockquote expandable>content</blockquote expandable>`\n\n" | |
| "Send new caption or `-` to clear.\n\n" | |
| "**Tip:** Slash commands such as `/trim` and `/mediainfo` are ignored here, so they will not be treated as caption input.\n" | |
| "**Audio Reorder:** At Settings β π΅ Audio Order, use track indices like `1,0,2` to reorder.\n" | |
| "**Metadata:** Set Title/Author/Artist at /metadata command, then toggle metadata ON in settings." | |
| ), | |
| "prefix": ( | |
| f"βοΈ **Set Prefix:**{current_text}\n\n" | |
| "Use `\\s` for a trailing space. HTML tags supported.\n" | |
| "Send new prefix or `-` to clear." | |
| ), | |
| "suffix": ( | |
| f"βοΈ **Set Suffix:**{current_text}\n\n" | |
| "Send new suffix or `-` to clear." | |
| ), | |
| "format": ( | |
| f"π¨ **Set Default Rename Format:**{current_text}\n\n" | |
| "Use `{season}`, `{episode}`, `{quality}` as variables.\n" | |
| "Used when no hint-based format matches.\n" | |
| "Send new format or `-` to clear." | |
| ), | |
| "audioorder": ( | |
| f"π΅ **Set Audio Order:**{current_text}\n\n" | |
| "Comma-separated track indices e.g. `1,0,2`\n" | |
| "Send order or `-` to reset." | |
| ), | |
| "audiodefault": ( | |
| f"π΅ **Set Default Audio Track:**{current_text}\n\n" | |
| "E.g. `0` = first track, `1` = second.\n" | |
| "Send index or `-` to reset." | |
| ), | |
| "mergeaudioorder": ( | |
| f"π΅ **Set Merge Audio Order:**{current_text}\n\n" | |
| "Separate from normal Audio Order - only used for **Auto-Merge (zip)** output.\n" | |
| "Comma-separated track indices e.g. `1,0,2`\n" | |
| "Any track NOT listed here still gets kept (appended after), so nothing is ever removed.\n" | |
| "Send order or `-` to reset." | |
| ), | |
| "keepaudio": ( | |
| f"π§ **Keep Audio Tracks:**{current_text}\n\n" | |
| "Keep ONLY the audio tracks you list here. The rest will be permanently removed (deleted) from the output video.\n" | |
| "Examples: `0` (first track), `0,2` (first and third tracks), or `Tamil` (match embedded language/name).\n" | |
| "Send indexes or language/name values, comma-separated if needed; send `-` to keep all tracks." | |
| ), | |
| } | |
| if action not in prompts: | |
| return | |
| await query.message.edit_text( | |
| prompts[action], | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="settings_back")]]) | |
| ) | |
| try: | |
| response = await client.listen( | |
| chat_id=query.message.chat.id, | |
| user_id=user_id, | |
| filters=filters.text, | |
| timeout=300 | |
| ) | |
| if response and response.text: | |
| text_value = response.text.strip() | |
| if text_value.startswith('/'): | |
| await response.delete() | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| return | |
| val = None if text_value == "-" else text_value | |
| if action == "caption": | |
| await codeflixbots.set_caption(user_id, val) | |
| elif action == "prefix": | |
| await codeflixbots.set_prefix(user_id, val) | |
| elif action == "suffix": | |
| await codeflixbots.set_suffix(user_id, val) | |
| elif action == "format": | |
| await codeflixbots.set_format_template(user_id, val) | |
| elif action == "audioorder": | |
| await codeflixbots.set_audio_order(user_id, val) | |
| elif action == "audiodefault": | |
| await codeflixbots.set_audio_default(user_id, val) | |
| elif action == "mergeaudioorder": | |
| await codeflixbots.set_merge_audio_order(user_id, val) | |
| elif action == "keepaudio": | |
| await codeflixbots.set_keep_audio(user_id, val) | |
| await response.delete() | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| except ListenerTimeout: | |
| try: | |
| await query.message.edit_text( | |
| "β³ Timed out.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]]) | |
| ) | |
| except (MessageNotModified, MessageIdInvalid): | |
| pass | |
| # βββ Import / Export Config βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def export_settings_cb(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| settings = await codeflixbots.get_all_settings(user_id) | |
| if not settings: | |
| return await query.answer("No settings found!", show_alert=True) | |
| import json | |
| import io | |
| settings_json = json.dumps(settings, indent=4) | |
| file_io = io.BytesIO(settings_json.encode("utf-8")) | |
| file_io.name = "RenameBot_Settings.json" | |
| await query.message.reply_document( | |
| document=file_io, | |
| caption="π€ **Your Bot Settings Configuration**\n\nYou can restore these settings anytime using the **Import Config** button in settings.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Close", callback_data="close")]]) | |
| ) | |
| await query.answer() | |
| async def import_settings_cb(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| await query.message.edit_text( | |
| "π₯ **Import Settings**\n\nPlease send me the `RenameBot_Settings.json` file you previously exported.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="settings_back")]]) | |
| ) | |
| try: | |
| response = await client.listen( | |
| chat_id=query.message.chat.id, | |
| user_id=user_id, | |
| filters=filters.document, | |
| timeout=300 | |
| ) | |
| if response and response.document: | |
| if not response.document.file_name.endswith(".json"): | |
| await query.message.edit_text("β Invalid file format! Please send a valid JSON config file.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]])) | |
| await response.delete() | |
| return | |
| import json | |
| import os | |
| file_path = await client.download_media(response) | |
| try: | |
| with open(file_path, "r") as f: | |
| data = json.load(f) | |
| success = await codeflixbots.set_all_settings(user_id, data) | |
| if success: | |
| await query.message.edit_text("β **Settings imported successfully!**", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β¬ οΈ Back to Settings", callback_data="settings_back")]])) | |
| else: | |
| await query.message.edit_text("β Failed to update settings in database.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]])) | |
| except Exception as e: | |
| await query.message.edit_text(f"β Failed to parse JSON file: {e}", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]])) | |
| finally: | |
| if os.path.exists(file_path): | |
| os.remove(file_path) | |
| await response.delete() | |
| except ListenerTimeout: | |
| try: | |
| await query.message.edit_text( | |
| "β³ Timed out.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]]) | |
| ) | |
| except (MessageNotModified, MessageIdInvalid): | |
| pass | |
| # βββ Rename Formats Panel ββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def show_rename_formats(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| formats = await codeflixbots.get_rename_formats(user_id) | |
| text = f"**π Rename Formats** ({len(formats)})\n\nHint keyword β Template\n\n" | |
| for i, f in enumerate(formats): | |
| hint = html.escape(f.get("hint", "")) | |
| template = html.escape(f.get("template", "")) | |
| text += f"`{i+1}.` π `{hint}`\n β `{template}`\n\n" | |
| if not formats: | |
| text += "_No formats added yet._\n\nAdd a format with a hint keyword to auto-detect which template to use based on filename." | |
| markup = InlineKeyboardMarkup([ | |
| [InlineKeyboardButton("β Add Format", callback_data="add_rename_format")], | |
| [InlineKeyboardButton("π Remove by Index", callback_data="del_rename_format_prompt"), | |
| InlineKeyboardButton("π Clear All", callback_data="clear_rename_formats")], | |
| [InlineKeyboardButton("β¬ οΈ Back", callback_data="settings_back")] | |
| ]) | |
| await query.message.edit_text(text, reply_markup=markup) | |
| async def add_rename_format_cb(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| await query.message.edit_text( | |
| "π **Add Rename Format β Step 1/2**\n\n" | |
| "Send the **hint keyword** (part of the filename to detect):\n\n" | |
| "Example: `One Piece` or `Naruto`", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="ui_rename_formats")]]) | |
| ) | |
| try: | |
| r1 = await client.listen(chat_id=query.message.chat.id, user_id=user_id, timeout=300) | |
| hint = r1.text.strip() | |
| await r1.delete() | |
| await query.message.edit_text( | |
| f"π **Add Rename Format β Step 2/2**\n\n" | |
| f"Hint: `{html.escape(hint)}`\n\n" | |
| "Now send the **rename template**:\n\n" | |
| "Use `{season}`, `{episode}`, `{quality}` as variables.\n" | |
| "Example: `One Piece S{season}E{episode} {quality} Multi Audio.mkv`", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="ui_rename_formats")]]) | |
| ) | |
| r2 = await client.listen(chat_id=query.message.chat.id, user_id=user_id, timeout=300) | |
| template = r2.text.strip() | |
| await r2.delete() | |
| await codeflixbots.add_rename_format(user_id, hint, template) | |
| await query.message.edit_text( | |
| f"β **Format Added!**\n\nHint: `{html.escape(hint)}`\nTemplate: `{html.escape(template)}`", | |
| reply_markup=InlineKeyboardMarkup([ | |
| [InlineKeyboardButton("π View Formats", callback_data="ui_rename_formats")], | |
| [InlineKeyboardButton("β¬ οΈ Back to Settings", callback_data="settings_back")] | |
| ]) | |
| ) | |
| except ListenerTimeout: | |
| try: | |
| await query.message.edit_text( | |
| "β³ Timed out.", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Back", callback_data="settings_back")]]) | |
| ) | |
| except (MessageNotModified, MessageIdInvalid): | |
| pass | |
| async def del_rename_format_prompt(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| formats = await codeflixbots.get_rename_formats(user_id) | |
| if not formats: | |
| return await safe_answer(query, "No formats to remove!", show_alert=True) | |
| await query.message.edit_text( | |
| f"π **Remove Rename Format**\n\nSend the **index number** to remove (1 to {len(formats)}):", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="ui_rename_formats")]]) | |
| ) | |
| try: | |
| r = await client.listen(chat_id=query.message.chat.id, user_id=user_id, timeout=60) | |
| idx = int(r.text.strip()) - 1 | |
| await r.delete() | |
| removed = await codeflixbots.remove_rename_format(user_id, idx) | |
| if removed: | |
| await safe_answer(query, "β Format removed!", show_alert=True) | |
| else: | |
| await safe_answer(query, "β οΈ Invalid index!", show_alert=True) | |
| query.data = "ui_rename_formats" | |
| await show_rename_formats(client, query) | |
| except (ListenerTimeout, ValueError): | |
| await safe_answer(query, "Invalid input or timeout.", show_alert=True) | |
| query.data = "ui_rename_formats" | |
| await show_rename_formats(client, query) | |
| async def clear_rename_formats_cb(client, query: CallbackQuery): | |
| await codeflixbots.clear_rename_formats(query.from_user.id) | |
| await safe_answer(query, "β All rename formats cleared!", show_alert=True) | |
| query.data = "ui_rename_formats" | |
| await show_rename_formats(client, query) | |
| # βββ RemName Rules Panel βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def add_remname_rule_cb(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| await query.message.edit_text( | |
| "π **Add RemName Rule**\n\n" | |
| "Send in format: `find | replace`\n\n" | |
| "Supports Python Regex!\n" | |
| "Examples:\n" | |
| "β’ `S\\d+E\\d+ | ` β remove episode tags\n" | |
| "β’ `@OldChannel | @NewChannel` β swap channel\n" | |
| "β’ `KatmovieHD\\.[a-z]+ | ` β remove site name", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β Cancel", callback_data="set_ui_remnames")]]) | |
| ) | |
| try: | |
| response = await client.listen(chat_id=query.message.chat.id, user_id=user_id, timeout=300) | |
| if response.text and "|" in response.text: | |
| parts = response.text.split("|", 1) | |
| rule = {"find": parts[0].strip(), "replace": parts[1].strip()} | |
| await codeflixbots.add_remname_rule(user_id, rule) | |
| await response.delete() | |
| await safe_answer(query, "β Rule added!", show_alert=True) | |
| else: | |
| await safe_answer(query, "β οΈ Invalid format β must contain `|`.", show_alert=True) | |
| query.data = "set_ui_remnames" | |
| await handle_set_ui(client, query) | |
| except ListenerTimeout: | |
| await safe_answer(query, "Timed out.", show_alert=True) | |
| async def clear_remnames_cb(client, query: CallbackQuery): | |
| await codeflixbots.clear_remname_rules(query.from_user.id) | |
| await safe_answer(query, "All RemName rules cleared!", show_alert=True) | |
| query.data = "set_ui_remnames" | |
| await handle_set_ui(client, query) | |
| # βββ Metadata & Rename Toggles ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def toggle_metadata(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_metadata(user_id) | |
| await codeflixbots.set_metadata(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Audio Metadata β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_autorename(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_is_auto_rename(user_id) | |
| await codeflixbots.set_is_auto_rename(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Auto-Rename Engine β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_audioreorder(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_is_audio_reorder(user_id) | |
| await codeflixbots.set_is_audio_reorder(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Audio Reorder β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_mediainfo(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_is_mediainfo(user_id) | |
| await codeflixbots.set_is_mediainfo(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"MediaInfo Upload β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_automerge(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_auto_merge(user_id) | |
| await codeflixbots.set_auto_merge(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Auto-Merge (zip) β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_mergeaudioreorder(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_merge_audio_reorder(user_id) | |
| await codeflixbots.set_merge_audio_reorder(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Merge Audio Reorder β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def cycle_upload_format(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_upload_format(user_id) | |
| cycle = {"auto": "video", "video": "document", "document": "auto"} | |
| next_fmt = cycle.get(current, "auto") | |
| await codeflixbots.set_upload_format(user_id, next_fmt) | |
| labels = {"auto": "π Auto (follow original)", "video": "π¬ Force Video", "document": "π Force Document"} | |
| await safe_answer(query, f"Upload Format β {labels[next_fmt]}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| async def toggle_autoupload(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_auto_upload(user_id) | |
| await codeflixbots.set_auto_upload(user_id, not current) | |
| state = "ON β " if not current else "OFF β" | |
| await safe_answer(query, f"Auto Upload to Channels β {state}", show_alert=True) | |
| await show_main_menu(client, query.message.chat.id, query.message.id, user_id, cb=query) | |
| # βββ View All Settings βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def view_settings(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| prefix = await codeflixbots.get_prefix(user_id) | |
| suffix = await codeflixbots.get_suffix(user_id) | |
| caption = await codeflixbots.get_caption(user_id) | |
| fmt = await codeflixbots.get_format_template(user_id) | |
| remnames = await codeflixbots.get_remname_rules(user_id) | |
| rename_formats = await codeflixbots.get_rename_formats(user_id) | |
| audio_order = await codeflixbots.get_audio_order(user_id) | |
| audio_default = await codeflixbots.get_audio_default(user_id) | |
| metadata = await codeflixbots.get_metadata(user_id) | |
| is_auto = await codeflixbots.get_is_auto_rename(user_id) | |
| is_reorder = await codeflixbots.get_is_audio_reorder(user_id) | |
| is_mediainfo = await codeflixbots.get_is_mediainfo(user_id) | |
| auto_merge = await codeflixbots.get_auto_merge(user_id) | |
| merge_audio_order = await codeflixbots.get_merge_audio_order(user_id) | |
| merge_audio_reorder = await codeflixbots.get_merge_audio_reorder(user_id) | |
| keep_audio = await codeflixbots.get_keep_audio(user_id) | |
| auto_upload = await codeflixbots.get_auto_upload(user_id) | |
| def e(v, max_len=60): | |
| if not v: | |
| return "_None_" | |
| s = html.escape(str(v)) | |
| return f"`{s[:max_len]}{'...' if len(s) > max_len else ''}`" | |
| text = "βοΈ **Your Settings:**\n\n" | |
| text += f"**Auto-Rename:** `{'ON' if is_auto else 'OFF'}`\n" | |
| text += f"**Prefix:** {e(prefix)}\n" | |
| text += f"**Suffix:** {e(suffix)}\n" | |
| text += f"**Caption:** {e(caption)}\n" | |
| text += f"**Default Format:** {e(fmt)}\n" | |
| text += f"**Audio Order:** {e(audio_order)}\n" | |
| text += f"**Default Track:** {e(audio_default)}\n" | |
| text += f"**Keep Audio:** {e(keep_audio)}\n" | |
| text += f"**Metadata:** `{'ON' if metadata else 'OFF'}`\n" | |
| text += f"**Audio Reorder:** `{'ON' if is_reorder else 'OFF'}`\n" | |
| text += f"**MediaInfo Upload:** `{'ON' if is_mediainfo else 'OFF'}`\n" | |
| text += f"**Auto-Merge (zip):** `{'ON' if auto_merge else 'OFF'}`\n" | |
| text += f"**Merge Audio Order:** {e(merge_audio_order)}\n" | |
| text += f"**Merge Audio Reorder:** `{'ON' if merge_audio_reorder else 'OFF'}`\n" | |
| text += f"**Auto Upload to Channels:** `{'ON' if auto_upload else 'OFF'}`\n" | |
| text += f"**RemName Rules:** `{len(remnames)} active`\n" | |
| text += f"**Rename Formats:** `{len(rename_formats)} hints configured`\n" | |
| await query.message.edit_text( | |
| text, | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β¬ οΈ Back", callback_data="settings_back")]]) | |
| ) | |
| # βββ Navigation ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| async def settings_back(client, query: CallbackQuery): | |
| await show_main_menu(client, query.message.chat.id, query.message.id, query.from_user.id, cb=query) | |
| async def close_menu(client, query: CallbackQuery): | |
| try: | |
| await query.message.delete() | |
| except: | |
| pass | |
| # βββ Thumbnail Layout Picker βββββββββββββββββββββββββββββββββββββββββββββββ | |
| THUMB_SIZES = [ | |
| (160, "π¦ Tiny (160px)"), | |
| (240, "π© Small (240px)"), | |
| (320, "π¨ Medium (320px) β Default"), | |
| (480, "π§ Large (480px)"), | |
| (720, "π₯ HD (720px)"), | |
| ] | |
| async def ui_thumb_layout(client, query: CallbackQuery): | |
| user_id = query.from_user.id | |
| current = await codeflixbots.get_thumb_size(user_id) | |
| buttons = [] | |
| for size, label in THUMB_SIZES: | |
| tick = "β " if current == size else "β‘" | |
| buttons.append([InlineKeyboardButton(f"{tick} {label}", callback_data=f"set_thumb_{size}")]) | |
| buttons.append([InlineKeyboardButton("β¬ οΈ Back", callback_data="settings_back")]) | |
| await query.message.edit_text( | |
| "πΌοΈ **Thumbnail Size**\n\nChoose the max thumbnail dimension." | |
| "\nSmaller = faster upload, larger = crisper preview.", | |
| reply_markup=InlineKeyboardMarkup(buttons) | |
| ) | |
| async def set_thumb_size_cb(client, query: CallbackQuery): | |
| import re | |
| m = re.match(r"^set_thumb_(\d+)$", query.data) | |
| if not m: | |
| return | |
| size = int(m.group(1)) | |
| await codeflixbots.set_thumb_size(query.from_user.id, size) | |
| await safe_answer(query, f"β Thumbnail size set to {size}px!", show_alert=True) | |
| # Re-render the picker with the updated tick | |
| query.data = "ui_thumb_layout" | |
| await ui_thumb_layout(client, query) | |
| # βββ Trim Info (redirect to /trim) βββββββββββββββββββββββββββββββββββββββββββ | |
| async def ui_trim_info(client, query: CallbackQuery): | |
| await safe_answer(query) | |
| await query.message.edit_text( | |
| "βοΈ **Trim / Split**\n\n" | |
| "To trim or split a video/audio file:\n\n" | |
| "1οΈβ£ **Reply** to any video / audio message\n" | |
| "2οΈβ£ Send the command `/trim`\n\n" | |
| "The bot will ask whether you want to\n" | |
| "β’ **Split by Parts** β number of equal chunks\n" | |
| "β’ **Trim by Time** β start & end timestamps (`HH:MM:SS`)", | |
| reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("β¬ οΈ Back", callback_data="settings_back")]]) | |
| ) | |