async def export_chat_data(message, chat, strings): chat_id = chat['chat_id'] key = 'export_lock:' + str(chat_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta(timedelta(seconds=redis.ttl( key)), strings['language_info']['babel']) await message.reply(strings['exports_locked'] % ttl) return redis.set(key, 1) redis.expire(key, 7200) msg = await message.reply(strings['started_exporting']) data = { 'general': { 'chat_name': chat['chat_title'], 'chat_id': chat_id, 'date': datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 'version': VERSION } } for module in [m for m in LOADED_MODULES if hasattr(m, '__export__')]: await asyncio.sleep(0) # Switch to other events before continue if k := await module.__export__(chat_id): data.update(k)
async def importfbans_cmd(message, fed, strings): fed_id = fed['fed_id'] key = 'importfbans_lock:' + str(fed_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta(timedelta(seconds=redis.ttl(key)), strings['language_info']['babel']) await message.reply(strings['importfbans_locked'] % ttl) return redis.set(key, 1) redis.expire(key, 600) if 'document' in message: document = message.document else: if 'reply_to_message' not in message: await ImportFbansFileWait.waiting.set() await message.reply(strings['send_import_file']) return elif 'document' not in message.reply_to_message: await message.reply(strings['rpl_to_file']) return document = message.reply_to_message.document await importfbans_func(message, fed, document=document)
async def get_chat_lang(chat_id): r = redis.get('lang_cache_{}'.format(chat_id)) if r: return r else: db_lang = await db.lang.find_one({'chat_id': chat_id}) if db_lang: # Rebuild lang cache redis.set('lang_cache_{}'.format(chat_id), db_lang['lang']) return db_lang['lang'] user_lang = await db.user_list.find_one({'user_id': chat_id}) if user_lang and user_lang['user_lang'] in LANGUAGES: # Add telegram language in lang cache redis.set('lang_cache_{}'.format(chat_id), user_lang['user_lang']) return user_lang['user_lang'] else: return 'en'
async def import_fun(message, document, chat, strings): chat_id = chat['chat_id'] key = 'import_lock:' + str(chat_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta(timedelta(seconds=redis.ttl( key)), strings['language_info']['babel']) await message.reply(strings['imports_locked'] % ttl) return redis.set(key, 1) redis.expire(key, 7200) msg = await message.reply(strings['started_importing']) if document['file_size'] > 52428800: await message.reply(strings['big_file']) return data = await bot.download_file_by_id(document.file_id, io.BytesIO()) try: data = rapidjson.load(data) except ValueError: return await message.reply(strings['invalid_file']) if 'general' not in data: await message.reply(strings['bad_file']) return file_version = data['general']['version'] if file_version > VERSION: await message.reply(strings['file_version_so_new']) return imported = [] for module in [m for m in LOADED_MODULES if hasattr(m, '__import__')]: module_name = module.__name__.replace('utah.modules.', '') if module_name not in data: continue if not data[module_name]: continue imported.append(module_name) await asyncio.sleep(0) # Switch to other events before continue await module.__import__(chat_id, data[module_name]) await msg.edit_text(strings['import_done'])
async def fban_export(message, fed, strings): fed_id = fed['fed_id'] key = 'fbanlist_lock:' + str(fed_id) if redis.get(key) and message.from_user.id not in OPERATORS: ttl = format_timedelta(timedelta(seconds=redis.ttl(key)), strings['language_info']['babel']) await message.reply(strings['fbanlist_locked'] % ttl) return redis.set(key, 1) redis.expire(key, 600) msg = await message.reply(strings['creating_fbanlist']) fields = ['user_id', 'reason', 'by', 'time', 'banned_chats'] with io.StringIO() as f: writer = csv.DictWriter(f, fields) writer.writeheader() async for banned_data in db.fed_bans.find({'fed_id': fed_id}): await asyncio.sleep(0) data = {'user_id': banned_data['user_id']} if 'reason' in banned_data: data['reason'] = banned_data['reason'] if 'time' in banned_data: data['time'] = int(time.mktime( banned_data['time'].timetuple())) if 'by' in banned_data: data['by'] = banned_data['by'] if 'banned_chats' in banned_data: data['banned_chats'] = banned_data['banned_chats'] writer.writerow(data) text = strings['fbanlist_done'] % html.escape(fed['fed_name'], False) f.seek(0) await message.answer_document(InputFile(f, filename='fban_export.csv'), text) await msg.delete()
async def all_errors_handler(update: Update, error): if update.message is not None: message = update.message elif update.callback_query is not None: message = update.callback_query.message elif update.edited_message is not None: message = update.edited_message else: return True # we don't want other guys in playground chat_id = message.chat.id err_tlt = sys.exc_info()[0].__name__ err_msg = str(sys.exc_info()[1]) log.warn('Error caused update is: \n' + html.escape(str(parse_update(message)), quote=False)) if redis.get(chat_id) == str(error): # by err_tlt we assume that it is same error return True if err_tlt == 'BadRequest' and err_msg == 'Have no rights to send a message': return True ignored_errors = ('FloodWaitError', 'RetryAfter', 'SlowModeWaitError', 'InvalidQueryID') if err_tlt in ignored_errors: return True if err_tlt in ('NetworkError', 'TelegramAPIError', 'RestartingTelegram'): log.error("Conn/API error detected", exc_info=error) return True text = "<b>Sorry, I encountered a error!</b>\n" text += f'<code>{html.escape(err_tlt, quote=False)}: {html.escape(err_msg, quote=False)}</code>' redis.set(chat_id, str(error), ex=600) await bot.send_message(chat_id, text)
content_types=ContentType.TEXT, allow_kwargs=True) @chat_connection() @get_strings_dec('antiflood') async def antiflood_expire_proc(message: Message, chat: dict, strings: dict, state, **_): try: if (time := message.text) not in (0, "0"): # just call for making sure its valid parsed_time = convert_time(time) else: time, parsed_time = None, None except (TypeError, ValueError): await message.reply(strings['invalid_time']) else: if not (data := redis.get(f'antiflood_setup:{chat["chat_id"]}')): await message.reply(strings['setup_corrupted']) else: await db.antiflood.update_one( {"chat_id": chat['chat_id']}, {"$set": { "time": time, "count": int(data) }}, upsert=True) await get_data.reset_cache(chat['chat_id']) kw = {'count': data} if time is not None: kw.update({ 'time': format_timedelta(parsed_time,
async def leave_silent(message): if not message.from_user.id == BOT_ID: return if redis.get('leave_silent:' + str(message.chat.id)) == message.left_chat_member.id: await message.delete()
async def connected_start_state(message, strings, chat): key = 'texas_connected_start_state:' + str(message.from_user.id) if redis.get(key): await message.reply(strings['pm_connected'].format(chat_name=chat['chat_title'])) redis.delete(key)
async def welcome_security_passed(message: Union[CallbackQuery, Message], state, strings): user_id = message.from_user.id async with state.proxy() as data: chat_id = data['chat_id'] msg_id = data['msg_id'] verify_msg_id = data['verify_msg_id'] to_delete = data['to_delete'] with suppress(ChatAdminRequired): await unmute_user(chat_id, user_id) with suppress(MessageToDeleteNotFound, MessageCantBeDeleted): if to_delete: await bot.delete_message(chat_id, msg_id) await bot.delete_message(user_id, verify_msg_id) await state.finish() with suppress(MessageToDeleteNotFound, MessageCantBeDeleted): message_id = redis.get(f"welcome_security_users:{user_id}:{chat_id}") # Delete the person's real security button if exists! if message_id: await bot.delete_message(chat_id, message_id) redis.delete(f"welcome_security_users:{user_id}:{chat_id}") with suppress(JobLookupError): scheduler.remove_job(f"wc_expire:{chat_id}:{user_id}") title = (await db.chat_list.find_one({'chat_id': chat_id}))['chat_title'] if 'data' in message: await message.answer(strings['passed_no_frm'] % title, show_alert=True) else: await message.reply(strings['passed'] % title) db_item = await get_greetings_data(chat_id) if 'message' in message: message = message.message # Welcome if 'note' in db_item and not db_item.get("welcome_disabled", False): text, kwargs = await t_unparse_note_item( message.reply_to_message if message.reply_to_message is not None else message, db_item['note'], chat_id) await send_note(user_id, text, **kwargs) # Welcome mute if 'welcome_mute' in db_item and db_item['welcome_mute'][ 'enabled'] is not False: user = await bot.get_chat_member(chat_id, user_id) if 'can_send_messages' not in user or user['can_send_messages'] is True: await restrict_user(chat_id, user_id, until_date=convert_time( db_item['welcome_mute']['time'])) chat = await db.chat_list.find_one({'chat_id': chat_id}) buttons = None if chat_nick := chat['chat_nick'] if chat.get('chat_nick', None) else None: buttons = InlineKeyboardMarkup().add( InlineKeyboardButton(text=strings['click_here'], url=f"t.me/{chat_nick}"))
# Welcome if 'note' not in db_item: db_item['note'] = { 'text': strings['default_welcome'], 'parse_mode': 'md' } reply_to = (message.message_id if 'clean_welcome' in db_item and db_item['clean_welcome']['enabled'] is not False else None) text, kwargs = await t_unparse_note_item(message, db_item['note'], chat_id) msg = await send_note(chat_id, text, reply_to=reply_to, **kwargs) # Clean welcome if 'clean_welcome' in db_item and db_item['clean_welcome'][ 'enabled'] is not False: if 'last_msg' in db_item['clean_welcome']: with suppress(MessageToDeleteNotFound, MessageCantBeDeleted): if value := redis.get(_clean_welcome.format(chat=chat_id)): await bot.delete_message(chat_id, value) redis.set(_clean_welcome.format(chat=chat_id), msg.id) # Welcome mute if user_id == BOT_ID: return if 'welcome_mute' in db_item and db_item['welcome_mute'][ 'enabled'] is not False: user = await bot.get_chat_member(chat_id, user_id) if 'can_send_messages' not in user or user['can_send_messages'] is True: if not await check_admin_rights(message, chat_id, BOT_ID, ['can_restrict_members']): await message.reply(strings['not_admin_wm']) return