import logging, re, asyncio
from pyrogram import Client, filters, enums
from pyrogram.errors import FloodWait
from pyrogram.errors.exceptions.bad_request_400 import ChannelInvalid, ChatAdminRequired, UsernameInvalid, UsernameNotModified
from info import CHANNELS, LOG_CHANNEL, ADMINS
from database.ia_filterdb import save_file
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from utils import temp
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
lock = asyncio.Lock()
@Client.on_message(filters.chat(CHANNELS) & (filters.document | filters.video | filters.audio))
async def media(bot, message):
for file_type in ("document", "video", "audio"):
media = getattr(message, file_type, None)
if media is not None: break
else: return
media.file_type = file_type
media.caption = message.caption
await save_file(media)
@Client.on_callback_query(filters.regex(r'^index'))
async def index_files(bot, query):
if query.data.startswith('index_cancel'):
temp.CANCEL = True
return await query.answer("Cᴀɴᴄᴇʟʟɪɴɢ Iɴᴅᴇxɪɴɢ", show_alert=True)
perfx, chat, lst_msg_id = query.data.split("#")
if lock.locked():
return await query.answer('Wᴀɪᴛ Uɴᴛɪʟ Pʀᴇᴠɪᴏᴜs Pʀᴏᴄᴇss Cᴏᴍᴘʟᴇᴛᴇ', show_alert=True)
msg = query.message
button = InlineKeyboardMarkup([[
InlineKeyboardButton('🚫 ᴄᴀɴᴄᴇʟʟ', "index_cancel")
]])
await msg.edit("ɪɴᴅᴇxɪɴɢ ɪs sᴛᴀʀᴛᴇᴅ ✨", reply_markup=button)
try: chat = int(chat)
except: chat = chat
await index_files_to_db(int(lst_msg_id), chat, msg, bot)
@Client.on_message((filters.forwarded | (filters.regex("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")) & filters.text ) & filters.private & filters.incoming & filters.user(ADMINS))
async def send_for_index(bot, message):
if message.text:
regex = re.compile("(https://)?(t\.me/|telegram\.me/|telegram\.dog/)(c/)?(\d+|[a-zA-Z_0-9]+)/(\d+)$")
match = regex.match(message.text)
if not match: return await message.reply('Invalid link')
chat_id = match.group(4)
last_msg_id = int(match.group(5))
if chat_id.isnumeric(): chat_id = int(("-100" + chat_id))
elif message.forward_from_chat.type == enums.ChatType.CHANNEL:
last_msg_id = message.forward_from_message_id
chat_id = message.forward_from_chat.username or message.forward_from_chat.id
else: return
try: await bot.get_chat(chat_id)
except ChannelInvalid: return await message.reply('This may be a private channel / group. Make me an admin over there to index the files.')
except (UsernameInvalid, UsernameNotModified): return await message.reply('Invalid Link specified.')
except Exception as e: return await message.reply(f'Errors - {e}')
try: k = await bot.get_messages(chat_id, last_msg_id)
except: return await message.reply('Make Sure That Iam An Admin In The Channel, if channel is private')
if k.empty: return await message.reply('This may be group and iam not a admin of the group.')
buttons = InlineKeyboardMarkup([[
InlineKeyboardButton('✨ ʏᴇꜱ', callback_data=f'index#{chat_id}#{last_msg_id}')
],[
InlineKeyboardButton('🚫 ᴄʟᴏꜱᴇ', callback_data='close_data')
]])
await message.reply(f'Do You Want To Index This Channel/ Group ?\n\nChat ID/ Username: {chat_id}
\nLast Message ID: {last_msg_id}
', reply_markup=buttons)
@Client.on_message(filters.command('setskip') & filters.user(ADMINS))
async def set_skip_number(bot, message):
if len(message.command) == 2:
try: skip = int(message.text.split(" ", 1)[1])
except: return await message.reply("Skip Number Should Be An Integer.")
await message.reply(f"Successfully Set Skip Number As {skip}")
temp.CURRENT = int(skip)
else:
await message.reply("Give Me A Skip Number")
async def index_files_to_db(lst_msg_id, chat, msg, bot):
total_files = 0
duplicate = 0
errors = 0
deleted = 0
no_media = 0
unsupported = 0
async with lock:
try:
current = temp.CURRENT
temp.CANCEL = False
async for message in bot.iter_messages(chat, lst_msg_id, temp.CURRENT):
if temp.CANCEL:
await msg.edit(f"Successfully Cancelled!!\n\nSaved {total_files}
files to dataBase!\nDuplicate Files Skipped: {duplicate}
\nDeleted Messages Skipped: {deleted}
\nNon-Media messages skipped: {no_media + unsupported}
(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}
")
break
current += 1
if current % 100 == 0:
can = [[InlineKeyboardButton('Cancel', callback_data='index_cancel')]]
reply = InlineKeyboardMarkup(can)
try:
await msg.edit_text(text=f"Total Messages Fetched: {current}
\nTotal Messages Saved: {total_files}
\nDuplicate Files Skipped: {duplicate}
\nDeleted Messages Skipped: {deleted}
\nNon-Media messages skipped: {no_media + unsupported}
(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}
", reply_markup=reply)
except FloodWait as t:
await asyncio.sleep(t.value)
await msg.edit_text(text=f"Total Messages Fetched: {current}
\nTotal Messages Saved: {total_files}
\nDuplicate Files Skipped: {duplicate}
\nDeleted Messages Skipped: {deleted}
\nNon-Media messages skipped: {no_media + unsupported}
(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}
", reply_markup=reply)
if message.empty:
deleted += 1
continue
elif not message.media:
no_media += 1
continue
elif message.media not in [enums.MessageMediaType.VIDEO, enums.MessageMediaType.AUDIO, enums.MessageMediaType.DOCUMENT]:
unsupported += 1
continue
media = getattr(message, message.media.value, None)
if not media:
unsupported += 1
continue
media.file_type = message.media.value
media.caption = message.caption
aynav, vnay = await save_file(media)
if aynav:
total_files += 1
elif vnay == 0:
duplicate += 1
elif vnay == 2:
errors += 1
except Exception as e:
logger.exception(e)
await msg.edit(f'Error: {e}')
else:
await msg.edit(f'Succesfully Saved {total_files}
To Database!\nDuplicate Files Skipped: {duplicate}
\nDeleted Messages Skipped: {deleted}
\nNon-Media Messages Skipped: {no_media + unsupported}
(Unsupported Media - `{unsupported}` )\nErrors Occurred: {errors}
')