Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 4 additions & 14 deletions Script.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ class script(object):

START_TXT = """<b>ʜᴇʏ {}, <i>{}</i>

ɪ ᴀᴍ ᴘᴏᴡᴇʀғᴜʟ ᴀᴜᴛᴏ ғɪʟᴛᴇʀ ᴡɪᴛʜ ʟɪɴᴋ sʜᴏʀᴛᴇɴᴇʀ ʙᴏᴛ. ʏᴏᴜ ᴄᴀɴ ᴜꜱᴇ ᴀꜱ ᴀᴜᴛᴏ ғɪʟᴛᴇʀ ᴡɪᴛʜ ʟɪɴᴋ sʜᴏʀᴛᴇɴᴇʀ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ... ɪᴛ'ꜱ ᴇᴀꜱʏ ᴛᴏ ᴜꜱᴇ ᴊᴜsᴛ ᴀᴅᴅ ᴍᴇ ᴀꜱ ᴀᴅᴍɪɴ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪ ᴡɪʟʟ ᴘʀᴏᴠɪᴅᴇ ᴛʜᴇʀᴇ ᴍᴏᴠɪᴇꜱ ᴡɪᴛʜ ʏᴏᴜʀ ʟɪɴᴋ ꜱʜᴏʀᴛᴇɴᴇʀ... ♻️</b>"""
ɪ ᴀᴍ ᴘᴏᴡᴇʀғᴜʟ ᴀᴜᴛᴏ ғɪʟᴛᴇʀ ʙᴏᴛ. ʏᴏᴜ ᴄᴀɴ ᴜꜱᴇ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ. ɪᴛ'ꜱ ᴇᴀꜱʏ ᴛᴏ ᴜꜱᴇ ᴊᴜsᴛ ᴀᴅᴅ ᴍᴇ ᴀꜱ ᴀᴅᴍɪɴ ɪɴ ʏᴏᴜʀ ɢʀᴏᴜᴘ ɪ ᴡɪʟʟ ᴘʀᴏᴠɪᴅᴇ ᴛʜᴇʀᴇ ᴍᴏᴠɪᴇꜱ</b>"""

MY_ABOUT_TXT = """★ Server: <a href=https://www.heroku.com>Heroku</a>
★ Database: <a href=https://www.mongodb.com>MongoDB</a>
Expand Down Expand Up @@ -44,21 +44,11 @@ class script(object):
👉 Please read the Instructions to get better results.
👉 Or not been released yet."""

IMDB_TEMPLATE = """✅ I Found: <code>{query}</code>

🏷 Title: <a href={url}>{title}</a>
IMDB_TEMPLATE = """🏷 Title: <a href={url}>{title}</a>
🎭 Genres: {genres}
📆 Year: <a href={url}/releaseinfo>{year}</a>
🌟 Rating: <a href={url}/ratings>{rating} / 10</a>
☀️ Languages: {languages}
📀 RunTime: {runtime} Minutes

🗣 Requested by: {message.from_user.mention}
©️ Powered by: <b>{message.chat.title}</b>"""

FILE_CAPTION = """<i>{file_name}</i>
🌟 Rating: <a href={url}/ratings>{rating} / 10</a></b>"""

🚫 ᴘʟᴇᴀsᴇ ᴄʟɪᴄᴋ ᴏɴ ᴛʜᴇ ᴄʟᴏsᴇ ʙᴜᴛᴛᴏɴ ɪꜰ ʏᴏᴜ ʜᴀᴠᴇ sᴇᴇɴ ᴛʜᴇ ᴍᴏᴠɪᴇ 🚫"""
FILE_CAPTION = """<b><a href='https://t.me/MovieCabanBot'>{file_name}</a></b>"""

WELCOME_TEXT = """👋 Hello {mention}, Welcome to {title} group! 💞"""

Expand Down
Binary file added database/__pycache__/ia_filterdb.cpython-313.pyc
Binary file not shown.
111 changes: 100 additions & 11 deletions database/ia_filterdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ async def save_file(media):
file_id = unpack_new_file_id(media.file_id)
file_name = re.sub(r"@\w+|(_|\-|\.|\+)", " ", str(media.file_name))
file_caption = re.sub(r"@\w+|(_|\-|\.|\+)", " ", str(media.caption))

document = {
'_id': file_id,
'file_name': file_name,
'file_size': media.file_size,
'caption': file_caption
}

try:
collection.insert_one(document)
logger.info(f'Saved - {file_name}')
Expand Down Expand Up @@ -78,7 +78,7 @@ async def get_search_results(query, max_results=MAX_BTN, offset=0, lang=None):
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')

try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
Expand Down Expand Up @@ -109,7 +109,7 @@ async def get_search_results(query, max_results=MAX_BTN, offset=0, lang=None):
files = results[offset:][:max_results]
next_offset = offset + max_results
if next_offset >= total_results:
next_offset = ''
next_offset = ''
return files, next_offset, total_results

async def delete_files(query):
Expand All @@ -120,24 +120,24 @@ async def delete_files(query):
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')

try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
regex = query

filter = {'file_name': regex}

result1 = collection.delete_many(filter)

result2 = None
if SECOND_FILES_DATABASE_URL:
result2 = second_collection.delete_many(filter)

total_deleted = result1.deleted_count
if result2:
total_deleted += result2.deleted_count

return total_deleted

async def get_file_details(query):
Expand Down Expand Up @@ -170,4 +170,93 @@ def unpack_new_file_id(new_file_id):
decoded.access_hash
)
)
return file_id
return file_id

def clean_title(filename):
"""Clean filename to extract just the movie/show title"""
title = filename

# Remove file extensions first
title = re.sub(r'\.(mkv|mp4|avi|mov|wmv|flv|webm|m4v|3gp|ts|m2ts)$', '', title, flags=re.IGNORECASE)

# Strategy: Extract title from beginning until we hit dates or season markers
# Most titles are clean alphanumeric at the start, noise comes after

# Find where the title likely ends by looking for:
# 1. Year patterns (1900-2099)
# 2. Season/Episode patterns (S01, S1, Season 1, etc.)
# 3. Quality indicators that commonly appear after titles

# Look for year patterns (movies): "Title.2023" or "Title (2023)" or "Title 2023"
year_match = re.search(r'[\.\s\-_\(]+(19|20)\d{2}[\.\s\-_\)]', title)
if year_match:
title = title[:year_match.start()]

# Look for season/episode patterns (series): "Title.S01E02" or "Title S1 E1"
season_match = re.search(r'[\.\s\-_]+(S\d{1,2}|Season\s*\d{1,2})', title, flags=re.IGNORECASE)
if season_match:
title = title[:season_match.start()]

# Look for common quality indicators that appear after titles
quality_match = re.search(r'[\.\s\-_]+(480p|720p|1080p|2160p|4k|HD|FHD|UHD|BluRay|WEB|HDCAM|DVDRip|BDRip|WEBRip)', title, flags=re.IGNORECASE)
if quality_match:
title = title[:quality_match.start()]

# Convert common separators to spaces
title = re.sub(r'[\.\-_]+', ' ', title)

# Clean up multiple spaces
title = re.sub(r'\s+', ' ', title)

# Remove leading/trailing whitespace
title = title.strip()

# Remove common prefixes that might appear at the start
title = re.sub(r'^(www\.|download\s+|free\s+)', '', title, flags=re.IGNORECASE)

# Handle special cases where title might have colons (like "Avengers: Endgame")
# Keep colons as they're part of legitimate titles

return title

async def get_distinct_titles(query):
"""Get distinct titles matching the search query"""
query = str(query).strip()
if not query:
raw_pattern = '.'
elif ' ' not in query:
raw_pattern = r'(\b|[\.\+\-_])' + query + r'(\b|[\.\+\-_])'
else:
raw_pattern = query.replace(' ', r'.*[\s\.\+\-_]')

try:
regex = re.compile(raw_pattern, flags=re.IGNORECASE)
except:
regex = query

# Get distinct titles from both databases
titles = set()

# Search in primary database
cursor = collection.find({'file_name': regex})
for doc in cursor:
# Clean the filename to extract just the title
clean_title_text = clean_title(doc['file_name'])
if clean_title_text and len(clean_title_text.strip()) > 2: # Only add non-empty titles
titles.add(clean_title_text)

# Search in secondary database if available
if SECOND_FILES_DATABASE_URL:
cursor2 = second_collection.find({'file_name': regex})
for doc in cursor2:
clean_title_text = clean_title(doc['file_name'])
if clean_title_text and len(clean_title_text.strip()) > 2: # Only add non-empty titles
titles.add(clean_title_text)

# Filter out very short or meaningless titles
filtered_titles = []
for title in titles:
if len(title.strip()) > 2 and not title.lower() in ['the', 'and', 'or', 'of', 'in', 'on', 'at', 'to', 'for']:
filtered_titles.append(title.strip())

return sorted(list(set(filtered_titles)))
7 changes: 4 additions & 3 deletions info.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,11 @@ def is_valid_ip(ip):
USE_CAPTION_FILTER = is_enabled('USE_CAPTION_FILTER', False)
IS_VERIFY = is_enabled('IS_VERIFY', False)
AUTO_DELETE = is_enabled('AUTO_DELETE', False)
WELCOME = is_enabled('WELCOME', False)
WELCOME = is_enabled('WELCOME', True)
PROTECT_CONTENT = is_enabled('PROTECT_CONTENT', False)
LONG_IMDB_DESCRIPTION = is_enabled("LONG_IMDB_DESCRIPTION", False)
LINK_MODE = is_enabled("LINK_MODE", True)
LINK_MODE = is_enabled("LINK_MODE", False)
AUTO_FILTER = is_enabled('AUTO_FILTER', True)
IMDB = is_enabled('IMDB', True)
SPELL_CHECK = is_enabled("SPELL_CHECK", True)
SHORTLINK = is_enabled('SHORTLINK', False)
Expand Down Expand Up @@ -158,4 +159,4 @@ def is_valid_ip(ip):
if len(UPI_ID) == 0 or len(UPI_NAME) == 0:
logger.info('IS_PREMIUM disabled due to empty UPI_ID or UPI_NAME')
IS_PREMIUM = False


25 changes: 6 additions & 19 deletions plugins/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ async def start(client, message):
wish = get_wish()
user = message.from_user.mention if message.from_user else "Dear"
btn = [[
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ⚡️', url=UPDATES_LINK),
InlineKeyboardButton('💡 sᴜᴘᴘᴏʀᴛ ɢʀᴏᴜᴘ 💡', url=SUPPORT_LINK)
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs ᴄʜᴀɴɴᴇʟ ⚡️', url=UPDATES_LINK)
]]
await message.reply(text=f"<b>ʜᴇʏ {user}, <i>{wish}</i>\nʜᴏᴡ ᴄᴀɴ ɪ ʜᴇʟᴘ ʏᴏᴜ??</b>", reply_markup=InlineKeyboardMarkup(btn))
return
Expand All @@ -54,7 +53,7 @@ async def start(client, message):

if (len(message.command) != 2) or (len(message.command) == 2 and message.command[1] == 'start'):
buttons = [[
InlineKeyboardButton("+ ᴀᴅᴅ ᴍᴇ ᴛᴏ ʏᴏᴜʀ ɢʀᴏᴜᴘ +", url=f'http://t.me/{temp.U_NAME}?startgroup=start')
InlineKeyboardButton('ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK)
],[
InlineKeyboardButton('ℹ️ ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK),
InlineKeyboardButton('🧑‍💻 sᴜᴘᴘᴏʀᴛ', url=SUPPORT_LINK)
Expand Down Expand Up @@ -161,17 +160,11 @@ async def start(client, message):
btn = [[
InlineKeyboardButton("✛ ᴡᴀᴛᴄʜ & ᴅᴏᴡɴʟᴏᴀᴅ ✛", callback_data=f"stream#{file['_id']}")
],[
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK),
InlineKeyboardButton('💡 ꜱᴜᴘᴘᴏʀᴛ', url=SUPPORT_LINK)
],[
InlineKeyboardButton('⁉️ ᴄʟᴏsᴇ ⁉️', callback_data='close_data')
InlineKeyboardButton('❌ Delete Files ❌', callback_data='close_data')
]]
else:
btn = [[
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK),
InlineKeyboardButton('💡 ꜱᴜᴘᴘᴏʀᴛ', url=SUPPORT_LINK)
],[
InlineKeyboardButton('⁉️ ᴄʟᴏsᴇ ⁉️', callback_data='close_data')
InlineKeyboardButton('❌ Delete Files ❌', callback_data='close_data')
]]

msg = await client.send_cached_media(
Expand Down Expand Up @@ -220,17 +213,11 @@ async def start(client, message):
btn = [[
InlineKeyboardButton("✛ ᴡᴀᴛᴄʜ & ᴅᴏᴡɴʟᴏᴀᴅ ✛", callback_data=f"stream#{file_id}")
],[
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK),
InlineKeyboardButton('💡 ꜱᴜᴘᴘᴏʀᴛ', url=SUPPORT_LINK)
],[
InlineKeyboardButton('⁉️ ᴄʟᴏsᴇ ⁉️', callback_data='close_data')
InlineKeyboardButton('❌ Delete Files ❌', callback_data='close_data')
]]
else:
btn = [[
InlineKeyboardButton('⚡️ ᴜᴘᴅᴀᴛᴇs', url=UPDATES_LINK),
InlineKeyboardButton('💡 ꜱᴜᴘᴘᴏʀᴛ', url=SUPPORT_LINK)
],[
InlineKeyboardButton('⁉️ ᴄʟᴏsᴇ ⁉️', callback_data='close_data')
InlineKeyboardButton('❌ Delete Files ❌', callback_data='close_data')
]]
vp = await client.send_cached_media(
chat_id=message.from_user.id,
Expand Down
Loading