Skip to content

Commit 5a633c7

Browse files
committed
Feat: Add QR code generation & link shortener support & bug fixes
1 parent 1874984 commit 5a633c7

File tree

19 files changed

+2727
-1746
lines changed

19 files changed

+2727
-1746
lines changed

bot/__main__.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525

2626

2727
# Method 2: Aggressive suppression using custom warning handler
28-
def custom_warning_handler(
29-
message, category, filename, lineno, file=None, line=None
30-
):
28+
def custom_warning_handler(message, category, filename, lineno, file=None, line=None):
3129
"""Custom warning handler that suppresses md2tgmd and latex2unicode warnings."""
3230
# Convert message to string for checking
3331
msg_str = str(message)
@@ -104,6 +102,8 @@ def custom_warning_handler(
104102
"GenSessionCommand": "- Generate Pyrogram session string",
105103
"VirusTotalCommand": "- Scan files or URLs for viruses using VirusTotal",
106104
"PasteCommand": "- Paste text to katb.in website",
105+
"ShortnerCommand": "- Shorten URLs with Bitly API and generate QR codes",
106+
"QRCodeCommand": "- Generate QR codes from text or URLs with customizable options",
107107
"NSFWStatsCommand": "- Get NSFW detection statistics",
108108
"NSFWTestCommand": "- Test NSFW detection on images",
109109
# QuickInfo Commands
@@ -175,9 +175,11 @@ def custom_warning_handler(
175175
# Setup Commands
176176
COMMAND_OBJECTS = [
177177
BotCommand(
178-
getattr(BotCommands, cmd)[0]
179-
if isinstance(getattr(BotCommands, cmd), list)
180-
else getattr(BotCommands, cmd),
178+
(
179+
getattr(BotCommands, cmd)[0]
180+
if isinstance(getattr(BotCommands, cmd), list)
181+
else getattr(BotCommands, cmd)
182+
),
181183
description,
182184
)
183185
for cmd, description in COMMANDS.items()
@@ -386,9 +388,9 @@ def handle_loop_exception(loop, context):
386388
exception = context.get("exception")
387389
if exception:
388390
# Filter out common handler removal errors that are harmless
389-
if isinstance(
390-
exception, ValueError
391-
) and "list.remove(x): x not in list" in str(exception):
391+
if isinstance(exception, ValueError) and "list.remove(x): x not in list" in str(
392+
exception
393+
):
392394
LOGGER.debug(f"Handler removal error (harmless): {exception}")
393395
# Filter out aria2 RPC exceptions for missing GIDs (these are expected during rapid downloads)
394396
elif "Aria2rpcException" in str(type(exception)) and "is not found" in str(

bot/core/config_manager.py

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ def _cleanup_expired(self):
9090
def get_stats(self) -> dict:
9191
"""Get cache performance statistics"""
9292
total_requests = self._hit_count + self._miss_count
93-
hit_rate = (
94-
(self._hit_count / total_requests * 100) if total_requests > 0 else 0
95-
)
93+
hit_rate = (self._hit_count / total_requests * 100) if total_requests > 0 else 0
9694

9795
return {
9896
"hit_count": self._hit_count,
@@ -188,12 +186,12 @@ class Config:
188186
BOT_PM: bool = True # Enable/disable sending media to user's bot PM
189187

190188
# Forwarding Settings
191-
FORWARD_SOURCE: ClassVar[
192-
list[str]
193-
] = [] # Source chat IDs/usernames for automatic forwarding (comma-separated)
194-
FORWARD_DESTINATION: ClassVar[
195-
list[str]
196-
] = [] # Destination chat IDs/usernames for automatic forwarding (comma-separated)
189+
FORWARD_SOURCE: ClassVar[list[str]] = (
190+
[]
191+
) # Source chat IDs/usernames for automatic forwarding (comma-separated)
192+
FORWARD_DESTINATION: ClassVar[list[str]] = (
193+
[]
194+
) # Destination chat IDs/usernames for automatic forwarding (comma-separated)
197195

198196
LEECH_FILENAME_PREFIX: str = ""
199197
LEECH_SUFFIX: str = ""
@@ -398,16 +396,18 @@ class Config:
398396
ZOTIFY_OUTPUT_PLAYLIST_TRACK: str = "{playlist}/{artists} - {title}"
399397
ZOTIFY_OUTPUT_PLAYLIST_EPISODE: str = "{playlist}/{episode_number} - {title}"
400398
ZOTIFY_OUTPUT_PODCAST: str = "{podcast}/{episode_number} - {title}"
401-
ZOTIFY_OUTPUT_SINGLE: str = (
402-
"{artists} - {title}" # For single tracks not in albums
403-
)
399+
ZOTIFY_OUTPUT_SINGLE: str = "{artists} - {title}" # For single tracks not in albums
404400

405401
# Zotify Quality and Format Settings (Optimized for free accounts)
406402
ZOTIFY_DOWNLOAD_QUALITY: str = (
407403
"normal" # auto, normal, high, very_high (normal=160kbps max for free)
408404
)
409-
ZOTIFY_AUDIO_FORMAT: str = "mp3" # vorbis, mp3, flac, aac, fdk_aac, opus, wav, wavpack (mp3 most compatible)
410-
ZOTIFY_ARTWORK_SIZE: str = "medium" # small, medium, large (medium to reduce bandwidth for free accounts)
405+
ZOTIFY_AUDIO_FORMAT: str = (
406+
"mp3" # vorbis, mp3, flac, aac, fdk_aac, opus, wav, wavpack (mp3 most compatible)
407+
)
408+
ZOTIFY_ARTWORK_SIZE: str = (
409+
"medium" # small, medium, large (medium to reduce bandwidth for free accounts)
410+
)
411411
ZOTIFY_TRANSCODE_BITRATE: int = -1 # -1 to use download rate
412412

413413
# Zotify Download Settings
@@ -440,9 +440,7 @@ class Config:
440440
ZOTIFY_PRINT_SKIPS: bool = False # Default False in Zotify
441441

442442
# Zotify Match Functionality (from CONFIG_VALUES)
443-
ZOTIFY_MATCH_EXISTING: bool = (
444-
False # Match existing files for skip functionality
445-
)
443+
ZOTIFY_MATCH_EXISTING: bool = False # Match existing files for skip functionality
446444

447445
# Missing CONFIG_VALUES from Zotify (exact 25 total)
448446
# Note: We already have most, but these were missing or incorrectly named
@@ -496,7 +494,9 @@ class Config:
496494

497495
# Streamrip Filepaths Configuration
498496
STREAMRIP_FILEPATHS_ADD_SINGLES_TO_FOLDER: bool = False
499-
STREAMRIP_FILEPATHS_FOLDER_FORMAT: str = "{albumartist} - {title} ({year}) [{container}] [{bit_depth}B-{sampling_rate}kHz]"
497+
STREAMRIP_FILEPATHS_FOLDER_FORMAT: str = (
498+
"{albumartist} - {title} ({year}) [{container}] [{bit_depth}B-{sampling_rate}kHz]"
499+
)
500500
STREAMRIP_FILEPATHS_TRACK_FORMAT: str = (
501501
"{tracknumber:02}. {artist} - {title}{explicit}"
502502
)
@@ -583,9 +583,7 @@ class Config:
583583
# DevUploads Settings
584584
DEVUPLOADS_API_KEY: str = "" # Default DevUploads API key
585585
DEVUPLOADS_FOLDER_NAME: str = "" # Default folder name for uploads
586-
DEVUPLOADS_PUBLIC_FILES: bool = (
587-
True # Default public/private setting for uploads
588-
)
586+
DEVUPLOADS_PUBLIC_FILES: bool = True # Default public/private setting for uploads
589587

590588
# MediaFire API Settings
591589
MEDIAFIRE_API_KEY: str = "" # MediaFire API key for authenticated access
@@ -742,24 +740,18 @@ class Config:
742740
TRIM_VIDEO_ENABLED: bool = False
743741
TRIM_VIDEO_CODEC: str = "none" # none, copy, libx264, etc.
744742
TRIM_VIDEO_PRESET: str = "none" # none, fast, medium, slow
745-
TRIM_VIDEO_FORMAT: str = (
746-
"none" # Output format for video trimming (e.g., mp4, mkv)
747-
)
743+
TRIM_VIDEO_FORMAT: str = "none" # Output format for video trimming (e.g., mp4, mkv)
748744

749745
# Audio Trim Settings
750746
TRIM_AUDIO_ENABLED: bool = False
751747
TRIM_AUDIO_CODEC: str = "none" # none, copy, aac, etc.
752748
TRIM_AUDIO_PRESET: str = "none" # none, fast, medium, slow
753-
TRIM_AUDIO_FORMAT: str = (
754-
"none" # Output format for audio trimming (e.g., mp3, aac)
755-
)
749+
TRIM_AUDIO_FORMAT: str = "none" # Output format for audio trimming (e.g., mp3, aac)
756750

757751
# Image Trim Settings
758752
TRIM_IMAGE_ENABLED: bool = False
759753
TRIM_IMAGE_QUALITY: int = 90
760-
TRIM_IMAGE_FORMAT: str = (
761-
"none" # Output format for image trimming (e.g., jpg, png)
762-
)
754+
TRIM_IMAGE_FORMAT: str = "none" # Output format for image trimming (e.g., jpg, png)
763755

764756
# Document Trim Settings
765757
TRIM_DOCUMENT_ENABLED: bool = False
@@ -800,9 +792,7 @@ class Config:
800792
EXTRACT_VIDEO_QUALITY: str = (
801793
"none" # Quality setting for video extraction (e.g., crf value)
802794
)
803-
EXTRACT_VIDEO_PRESET: str = (
804-
"none" # Preset for video encoding (e.g., medium, slow)
805-
)
795+
EXTRACT_VIDEO_PRESET: str = "none" # Preset for video encoding (e.g., medium, slow)
806796
EXTRACT_VIDEO_BITRATE: str = "none" # Bitrate for video encoding (e.g., 5M)
807797
EXTRACT_VIDEO_RESOLUTION: str = (
808798
"none" # Resolution for video extraction (e.g., 1920x1080)
@@ -1091,16 +1081,16 @@ class Config:
10911081
MERGE_METADATA_COMMENT: str = "none"
10921082

10931083
# Resource Management Settings
1094-
PIL_MEMORY_LIMIT: int = 2048
1084+
PIL_MEMORY_LIMIT: int = (
1085+
1024 # Reduced from 2048MB to 1024MB for better memory management
1086+
)
10951087

10961088
# Auto Restart Settings - Optimized for better resource management
10971089
AUTO_RESTART_ENABLED: bool = False # Disabled by default for better stability
1098-
AUTO_RESTART_INTERVAL: int = (
1099-
48 # Increased to 48 hours to reduce restart frequency
1100-
)
1090+
AUTO_RESTART_INTERVAL: int = 48 # Increased to 48 hours to reduce restart frequency
11011091

11021092
# Garbage Collection Settings
1103-
GC_ENABLED: bool = True # Enable/disable garbage collection completely
1093+
GC_ENABLED: bool = False # Enable/disable garbage collection completely
11041094
GC_INTERVAL: int = 60 # Minimum interval between GC operations in seconds
11051095
GC_THRESHOLD_MB: int = 150 # Memory threshold in MB to trigger GC
11061096
GC_AGGRESSIVE_MODE: bool = False # Enable aggressive GC by default
@@ -1119,9 +1109,7 @@ class Config:
11191109
TASK_MONITOR_COMPLETION_THRESHOLD: int = 86400 # in seconds (24 hours)
11201110
TASK_MONITOR_CPU_HIGH: int = 85 # Reduced threshold for better responsiveness
11211111
TASK_MONITOR_CPU_LOW: int = 50 # Reduced threshold
1122-
TASK_MONITOR_MEMORY_HIGH: int = (
1123-
70 # Reduced threshold for better memory management
1124-
)
1112+
TASK_MONITOR_MEMORY_HIGH: int = 70 # Reduced threshold for better memory management
11251113
TASK_MONITOR_MEMORY_LOW: int = 50 # Reduced threshold
11261114

11271115
# Limits Settings
@@ -1148,9 +1136,7 @@ class Config:
11481136
)
11491137
STATUS_UPDATE_INTERVAL: int = 3 # Status update interval in seconds (minimum 2)
11501138
STATUS_LIMIT: int = 10 # Number of tasks to display in status message
1151-
SEARCH_LIMIT: int = (
1152-
0 # Maximum number of search results to display (0 = unlimited)
1153-
)
1139+
SEARCH_LIMIT: int = 0 # Maximum number of search results to display (0 = unlimited)
11541140
SHOW_CLOUD_LINK: bool = True # Show cloud links in upload completion message
11551141

11561142
# Truecaller API Settings
@@ -1210,7 +1196,9 @@ class Config:
12101196
AI_ENABLED: bool = True # Master toggle for AI functionality
12111197

12121198
# Default AI Model (replaces separate provider and model configs)
1213-
DEFAULT_AI_MODEL: str = "gpt-4o-mini" # Use most reliable model as default - All supported models: gpt-4o, gpt-4o-mini, gpt-4, gpt-3.5-turbo, o1-preview, o1-mini, claude-3.5-sonnet, claude-3-sonnet, claude-3-haiku, claude-3-opus, claude-2.1, gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash-exp, mixtral-8x7b-32768, llama-3.1-70b-versatile, llama-3.1-8b-instant, llama2-70b-4096, vertex-gemini-1.5-pro, vertex-gemini-1.5-flash, vertex-claude-3-sonnet, vertex-claude-3-haiku, whisper-1, mistral, deepseek
1199+
DEFAULT_AI_MODEL: str = (
1200+
"gpt-4o-mini" # Use most reliable model as default - All supported models: gpt-4o, gpt-4o-mini, gpt-4, gpt-3.5-turbo, o1-preview, o1-mini, claude-3.5-sonnet, claude-3-sonnet, claude-3-haiku, claude-3-opus, claude-2.1, gemini-1.5-pro, gemini-1.5-flash, gemini-2.0-flash-exp, mixtral-8x7b-32768, llama-3.1-70b-versatile, llama-3.1-8b-instant, llama2-70b-4096, vertex-gemini-1.5-pro, vertex-gemini-1.5-flash, vertex-claude-3-sonnet, vertex-claude-3-haiku, whisper-1, mistral, deepseek
1201+
)
12141202

12151203
# GPT/OpenAI Settings
12161204
OPENAI_API_KEY: str = ""
@@ -1228,9 +1216,7 @@ class Config:
12281216

12291217
# Gemini/Google AI Settings
12301218
GOOGLE_AI_API_KEY: str = ""
1231-
GOOGLE_AI_API_URL: str = (
1232-
"https://generativelanguage.googleapis.com/v1beta/models"
1233-
)
1219+
GOOGLE_AI_API_URL: str = "https://generativelanguage.googleapis.com/v1beta/models"
12341220
GEMINI_MODELS: str = "gemini-1.5-pro,gemini-1.5-flash,gemini-2.0-flash-exp"
12351221

12361222
# Vertex AI Settings
@@ -1243,7 +1229,9 @@ class Config:
12431229
# Groq Settings
12441230
GROQ_API_KEY: str = ""
12451231
GROQ_API_URL: str = "https://api.groq.com/openai/v1/chat/completions"
1246-
GROQ_MODELS: str = "mixtral-8x7b-32768,llama2-70b-4096,llama-3.1-70b-versatile,llama-3.1-8b-instant"
1232+
GROQ_MODELS: str = (
1233+
"mixtral-8x7b-32768,llama2-70b-4096,llama-3.1-70b-versatile,llama-3.1-8b-instant"
1234+
)
12471235

12481236
# Legacy AI Settings (for backward compatibility)
12491237
MISTRAL_API_URL: str = ""
@@ -1275,13 +1263,9 @@ class Config:
12751263
AI_DOCUMENT_PROCESSING_ENABLED: bool = (
12761264
True # Enable document processing (PDF, text)
12771265
)
1278-
AI_FOLLOW_UP_QUESTIONS_ENABLED: bool = (
1279-
True # Enable automatic follow-up questions
1280-
)
1266+
AI_FOLLOW_UP_QUESTIONS_ENABLED: bool = True # Enable automatic follow-up questions
12811267
AI_CONVERSATION_EXPORT_ENABLED: bool = True # Enable conversation export
1282-
AI_TYPEWRITER_EFFECT_ENABLED: bool = (
1283-
True # Enable typewriter effect for streaming
1284-
)
1268+
AI_TYPEWRITER_EFFECT_ENABLED: bool = True # Enable typewriter effect for streaming
12851269
AI_CONTEXT_PRUNING_ENABLED: bool = True # Enable intelligent context pruning
12861270

12871271
# AI Performance Settings
@@ -1295,12 +1279,12 @@ class Config:
12951279
AI_DAILY_TOKEN_LIMIT: int = 0 # Daily token limit per user (0 = unlimited)
12961280
AI_MONTHLY_TOKEN_LIMIT: int = 0 # Monthly token limit per user (0 = unlimited)
12971281
AI_DAILY_COST_LIMIT: float = 0.0 # Daily cost limit per user (0.0 = unlimited)
1298-
AI_MONTHLY_COST_LIMIT: float = (
1299-
0.0 # Monthly cost limit per user (0.0 = unlimited)
1300-
)
1282+
AI_MONTHLY_COST_LIMIT: float = 0.0 # Monthly cost limit per user (0.0 = unlimited)
13011283

13021284
# AI Model Grouping
1303-
AI_MODEL_GROUPS: str = "GPT:gpt-3.5-turbo,gpt-4,gpt-4o|Claude:claude-3-haiku,claude-3-sonnet|Gemini:gemini-1.5-pro,gemini-1.5-flash|Groq:mixtral-8x7b-32768,llama2-70b-4096|Others:mistral,deepseek"
1285+
AI_MODEL_GROUPS: str = (
1286+
"GPT:gpt-3.5-turbo,gpt-4,gpt-4o|Claude:claude-3-haiku,claude-3-sonnet|Gemini:gemini-1.5-pro,gemini-1.5-flash|Groq:mixtral-8x7b-32768,llama2-70b-4096|Others:mistral,deepseek"
1287+
)
13041288

13051289
# Shortener Settings
13061290
SHORTENER_MIN_TIME: int = 10 # Minimum time in seconds for shortener to process
@@ -1379,9 +1363,7 @@ class Config:
13791363
)
13801364
WEATHER_UNITS: str = "metric" # Units: standard, metric, imperial
13811365
WEATHER_LANGUAGE: str = "en" # Language code for weather descriptions
1382-
WEATHER_UPDATE_TIME: str = (
1383-
"08:00" # Time for daily weather updates (HH:MM format)
1384-
)
1366+
WEATHER_UPDATE_TIME: str = "08:00" # Time for daily weather updates (HH:MM format)
13851367
WEATHER_TIMEZONE: str = "UTC" # Timezone for weather updates
13861368

13871369
# Advanced Weather Features
@@ -1408,9 +1390,7 @@ class Config:
14081390
WEATHER_ALERT_WIND_SPEED: float = 15.0 # High wind speed alert threshold (m/s)
14091391
WEATHER_ALERT_VISIBILITY: int = 1000 # Low visibility alert threshold (meters)
14101392
WEATHER_ALERT_AQI: int = 3 # Air quality alert threshold (1-5 scale)
1411-
WEATHER_ALERT_FIRE_DANGER: int = (
1412-
3 # Fire weather index alert threshold (0-5 scale)
1413-
)
1393+
WEATHER_ALERT_FIRE_DANGER: int = 3 # Fire weather index alert threshold (0-5 scale)
14141394

14151395
# Weather Map Settings
14161396
WEATHER_MAP_LAYERS: list = [
@@ -1421,9 +1401,7 @@ class Config:
14211401
"clouds_new", # Clouds
14221402
] # Available weather map layers
14231403
WEATHER_MAP_OPACITY: float = 0.6 # Map layer opacity (0.0-1.0)
1424-
WEATHER_USE_ADVANCED_MAPS: bool = (
1425-
False # Use Weather Maps 2.0 (requires paid plan)
1426-
)
1404+
WEATHER_USE_ADVANCED_MAPS: bool = False # Use Weather Maps 2.0 (requires paid plan)
14271405
WEATHER_USE_HOURLY_MAPS: bool = (
14281406
False # Use Weather Maps 2.0 with 1-hour step (requires paid plan)
14291407
)
@@ -1459,17 +1437,17 @@ class Config:
14591437
True # Use backup weather data sources if primary fails
14601438
)
14611439
WEATHER_DATA_VALIDATION: bool = True # Validate weather data before displaying
1462-
WEATHER_METRIC_CONVERSION: bool = (
1463-
True # Auto-convert units based on user location
1464-
)
1440+
WEATHER_METRIC_CONVERSION: bool = True # Auto-convert units based on user location
14651441

14661442
# Enhanced NSFW Detection Settings
14671443
NSFW_DETECTION_ENABLED: bool = True # Master toggle for NSFW detection
14681444
NSFW_DETECTION_SENSITIVITY: str = "moderate" # strict, moderate, permissive
14691445
NSFW_KEYWORD_DETECTION: bool = True # Enable enhanced keyword detection
14701446
NSFW_VISUAL_DETECTION: bool = False # Enable AI-powered visual analysis
14711447
NSFW_AUDIO_DETECTION: bool = False # Enable audio content analysis
1472-
NSFW_FUZZY_MATCHING: bool = False # Enable fuzzy keyword matching (disabled by default to reduce false positives)
1448+
NSFW_FUZZY_MATCHING: bool = (
1449+
False # Enable fuzzy keyword matching (disabled by default to reduce false positives)
1450+
)
14731451
NSFW_LEETSPEAK_DETECTION: bool = True # Enable leetspeak detection
14741452
NSFW_MULTI_LANGUAGE: bool = (
14751453
False # Enable multi-language keyword support (disabled by default)
@@ -1516,14 +1494,23 @@ class Config:
15161494
PASTEBIN_API_KEY: str = "" # Pastebin Developer API Key
15171495
PASTEBIN_ENABLED: bool = False # Enable/disable Pastebin functionality
15181496

1497+
# Bitly API Settings
1498+
BITLY_ACCESS_TOKEN: str = "" # Bitly API access token for link shortening
1499+
BITLY_GROUP_GUID: str = "" # Optional Bitly group GUID for organization
1500+
1501+
# TinyURL API Settings
1502+
TINYURL_API_TOKEN: str = "" # TinyURL API token for link shortening
1503+
15191504
HEROKU_APP_NAME: str = ""
15201505
HEROKU_API_KEY: str = ""
15211506

15221507
# Branding Settings
15231508
CREDIT: str = (
15241509
"Powered by @aimmirror" # Credit text shown in status messages and RSS feeds
15251510
)
1526-
OWNER_THUMB: str = "https://graph.org/file/80b7fb095063a18f9e232.jpg" # Default thumbnail URL for owner
1511+
OWNER_THUMB: str = (
1512+
"https://graph.org/file/80b7fb095063a18f9e232.jpg" # Default thumbnail URL for owner
1513+
)
15271514

15281515
@classmethod
15291516
def _convert(cls, key, value):

0 commit comments

Comments
 (0)