async def kick_self(event, chat, user): K = await is_user_admin(chat, user) if K is True: await event.reply(get_string("bans", "kickme_admin", chat)) return False if str(user) in WHITELISTED: logger.error(str(user)) await event.reply(get_string("bans", "whitelisted", chat)) return False banned_rights = ChatBannedRights(until_date=None, send_messages=True, view_messages=True) unbanned_rights = ChatBannedRights(until_date=None, view_messages=False, send_messages=False) try: await event.client(EditBannedRequest(chat, user, banned_rights)) await event.client(EditBannedRequest(chat, user, unbanned_rights)) except Exception: return False return True
async def kick_user(event, user_id, chat_id): banned_rights = ChatBannedRights(until_date=None, send_messages=True, view_messages=True) unbanned_rights = ChatBannedRights(until_date=None, view_messages=False, send_messages=False) bot_id = await bot.get_me() bot_id = bot_id.id if user_id == bot_id: await event.reply( get_string("bans", "bot_cant_be_kicked", event.chat_id)) return False if await is_user_admin(chat_id, user_id) is True: await event.reply(get_string("bans", "user_admin_kick", event.chat_id)) return False try: await event.client(EditBannedRequest(chat_id, user_id, banned_rights)) await event.client(EditBannedRequest(chat_id, user_id, unbanned_rights)) except Exception as err: logger.error(str(err)) return False return True
async def blacklist_user(event): user, reason = await get_user_and_text(event) if not reason: await event.reply("You can't blacklist user without a reason blyat!") return try: await ban_user(event, user['user_id'], event.chat_id, None) except Exception as err: await event.reply(err) logger.error(err) return old = mongodb.blacklisted_users.find_one({'user': user['user_id']}) if old: new = { 'user': user['user_id'], 'date': old['date'], 'by': old['by'], 'reason': reason } mongodb.blacklisted_users.update_one({'_id': old['_id']}, {"$set": new}, upsert=False) await event.reply("This user already blacklisted! I'll update the reason.") return date = strftime("%Y-%m-%d %H:%M:%S", gmtime()) new = { 'user': user['user_id'], 'date': date, 'reason': reason, 'by': event.from_id } user_id = user['user_id'] logger.info(f'user {user_id} gbanned by {event.from_id}') mongodb.blacklisted_users.insert_one(new) await event.reply("Sudo {} blacklisted {}.\nDate: `{}`\nReason: `{}`".format( await user_link(event.from_id), await user_link(user['user_id']), date, reason))
def exit_gracefully(signum, frame): logger.info("Bye!") try: redis.bgsave() except Exception as err: logger.info("Redis error, exiting immediately!") logger.error(err) exit(1) logger.info("----------------------") sys.exit(1)
async def unfban_user(event, user, fed, reason, strings): from_id = event.from_id bot_id = await bot.get_me() bot_id = bot_id.id if user == bot_id: await event.reply(strings['unfban_self']) return check = mongodb.fbanned_users.find_one({ 'user': user['user_id'], 'fed_id': fed['fed_id'] }) if not check: await event.reply(strings['user_not_fbanned'].format( user=await user_link(user['user_id']))) return fed_chats = mongodb.fed_groups.find({'fed_id': fed['fed_id']}) msg = await event.reply(strings["unfban_started"].format( user=await user_link(user['user_id']), fed_name=fed["fed_name"], admin=await user_link(from_id))) for chat in fed_chats: await asyncio.sleep(1) # Do not slow down other updates try: unbanned_rights = ChatBannedRights( until_date=None, view_messages=False, send_messages=False, send_media=False, send_stickers=False, send_gifs=False, send_games=False, send_inline=False, embed_links=False, ) await event.client( EditBannedRequest(chat['chat_id'], user['user_id'], unbanned_rights)) except Exception as err: logger.error(err) mongodb.fbanned_users.delete_one({'_id': check['_id']}) await msg.edit(strings["unfban_completed"].format(user=await user_link(user['user_id'] ), fed_name=fed["fed_name"], admin=await user_link(from_id)))
async def gban_trigger(event): user_id = event.from_id K = mongodb.blacklisted_users.find_one({'user': user_id}) if K: try: await ban_user(event, K['user_id'], event.chat_id, None) except Exception as err: await event.reply(str(err)) logger.error(err) await event.reply(get_string("gbans", "user_is_blacklisted", event.chat_id).format( await user_link(user_id), K['reason']))
async def un_blacklist_user(event): chat_id = event.chat_id user = await get_user(event) try: await unban_user(event, user['user_id'], chat_id) except Exception as err: await event.reply(err) logger.error(err) old = mongodb.blacklisted_users.find_one({'user': user['user_id']}) if not old: await event.reply("This user isn't blacklisted!") return user_id = user['user_id'] logger.info(f'user {user_id} ungbanned by {event.from_id}') mongodb.blacklisted_users.delete_one({'_id': old['_id']}) await event.reply("Sudo {} unblacklisted {}.".format( await user_link(event.from_id), await user_link(user_id)))
async def un_blacklist_user(event): chat_id = event.chat_id user = await get_user(event, send_text=False) probably_id = event.pattern_match.group(1).split(" ")[0] if user: user_id = int(user['user_id']) if not user and probably_id.isdigit(): user_id = int(probably_id) try: unbanned_rights = ChatBannedRights( until_date=None, view_messages=False, send_messages=False, send_media=False, send_stickers=False, send_gifs=False, send_games=False, send_inline=False, embed_links=False, ) precheck = mongodb.gbanned_groups.find({'user': user}) if precheck: chats = mongodb.gbanned_groups.find({'user': user}) else: chats = chat_id for chat in chats: await event.client( EditBannedRequest(chat['chat'], user_id, unbanned_rights)) except Exception as err: logger.error(str(err)) old = mongodb.blacklisted_users.find_one({'user': user_id}) if not old: await event.reply("This user isn't blacklisted!") return logger.info(f'user {user_id} ungbanned by {event.from_id}') mongodb.blacklisted_users.delete_one({'_id': old['_id']}) await event.reply("Sudo {} unblacklisted {}.".format( await user_link(event.from_id), await user_link(user_id)))
async def mute_user(event, user_id, chat_id, time_val): muted_rights = ChatBannedRights(until_date=time_val, send_messages=True) bot_id = await bot.get_me() bot_id = bot_id.id if user_id == bot_id: await event.reply( get_string("bans", "bot_cant_be_muted", event.chat_id)) return False if await is_user_admin(chat_id, user_id) is None: await event.reply(get_string("bans", "user_admin_mute", event.chat_id)) return False try: await event.client(EditBannedRequest(chat_id, user_id, muted_rights)) except Exception as err: logger.error(str(err)) return False return True
async def check_message_for_smartbroadcast(event): chat_id = event.chat_id match = mongodb.sbroadcast_list.find_one({'chat_id': chat_id}) if match: try: raw_text = mongodb.sbroadcast_settings.find_one({})['text'] text, buttons = button_parser(event.chat_id, raw_text) if len(buttons) == 0: buttons = None await bot.send_message(chat_id, text, buttons=buttons) except Exception as err: logger.error(err) mongodb.sbroadcast_list.delete_one({'chat_id': chat_id}) old = mongodb.sbroadcast_settings.find_one({}) num = old['recived_chats'] + 1 mongodb.sbroadcast_settings.update( {'_id': old['_id']}, { 'text': old['text'], 'all_chats': old['all_chats'], 'recived_chats': num }, upsert=False)
async def report_error(event, telethon=False): if telethon is True: msg = event chat_id = msg.chat_id lib = 'Telethon' else: msg = event.message chat_id = msg.chat.id lib = 'Aiogram' date = strftime("%Y-%m-%d %H:%M:%S", gmtime()) logger.error("Error: " + date) logger.error("Lib: " + lib) if telethon is True: logger.error(traceback.format_exc()) if DEBUG_MODE is True: await msg.reply(str(sys.exc_info()[1])) return new = {'error': str(sys.exc_info()[1]), 'date': datetime.datetime.now()} mongodb.errors.insert_one(new) text = "<b>Sorry, I encountered a error!</b>\n" link = "<a href=\"https://t.me/YanaBotGroup\">Sophie support chat</a>" text += f"If you wanna you can report it - just forward this file to {link}.\n" text += "I won't log anything except the fact of error and date\n" ftext = "Sophie error log file." ftext += "\n______________________\n" ftext += "\nNotice:\nThis file uploaded ONLY here, we logged only fact of error and date, " ftext += "we respect your privacy, you may not report this error if you've " ftext += "any confidential data here, noone will see your data\n\n" ftext += "\nDate: " + date ftext += "\nLib: " + lib ftext += "\nGroup ID: " + str(chat_id) ftext += "\nSender ID: " + str(msg.from_user.id if lib == "Aiogram" else msg.from_id) ftext += "\n\nRaw update text:\n" ftext += str(event) ftext += "\n\nFormatted update text:\n" ftext += str(ujson.dumps(msg, indent=2)) ftext += "\n\nTraceback info:\n" ftext += str(traceback.format_exc()) ftext += "\n\nError text:\n" ftext += str(sys.exc_info()[1]) command = "git log --pretty=format:\"%an: %s\" -5" ftext += "\n\n\nLast 5 commits:\n" ftext += await term(command) await bot.send_document(chat_id, types.InputFile(io.StringIO(ftext), filename="Error.txt"), caption=text, reply_to_message_id=msg.message_id if lib == "Aiogram" else msg.message.id) return
async def unban_user(event, user_id, chat_id): unbanned_rights = ChatBannedRights( until_date=None, view_messages=False, send_messages=False, send_media=False, send_stickers=False, send_gifs=False, send_games=False, send_inline=False, embed_links=False, ) bot_id = await bot.get_me() bot_id = bot_id.id if user_id == bot_id: await event.reply( get_string("bans", "bot_cant_be_unbanned", event.chat_id)) return False try: peep = await bot(GetParticipantRequest(chat_id, user_id)) if not isinstance(peep.participant, ChannelParticipantBanned): await event.reply(get_string('bans', 'usernt_banned', chat_id)) return False except Exception: pass try: await event.client(EditBannedRequest(chat_id, user_id, unbanned_rights)) except Exception as err: logger.error(str(err)) return False return True
logger.debug("Importing " + module_name) imported_module = import_module("sophie_bot.modules.components." + module_name) logger.info("Components loaded!") else: logger.info("Components disabled!") # Catch up missed updates if CONFIG["advanced"]["catch_up"] is True: logger.info("Catch up missed updates..") try: asyncio.ensure_future(bot.catch_up()) except Exception as err: logger.error(err) def exit_gracefully(signum, frame): logger.info("Bye!") try: redis.bgsave() except Exception as err: logger.info("Redis error, exiting immediately!") logger.error(err) exit(1) logger.info("----------------------") sys.exit(1) # Run loop
async def blacklist_user(event): user, reason = await get_user_and_text(event, send_text=False) probably_id = event.pattern_match.group(1).split()[0] if user: user_id = int(user['user_id']) if not user and probably_id.isdigit(): probably_reason = event.pattern_match.group(1).split()[1] user_id = int(probably_id) reason = probably_reason if user_id in WHITELISTED: await event.reply("You can't blacklist a Whitelisted user") return if not reason: await event.reply("You can't blacklist user without a reason blyat!") return try: banned_rights = ChatBannedRights( until_date=None, view_messages=True, send_messages=True, send_media=True, send_stickers=True, send_gifs=True, send_games=True, send_inline=True, embed_links=True, ) await event.client( EditBannedRequest(event.chat_id, user_id, banned_rights)) except Exception as err: logger.error(str(err)) await event.reply(str(err)) old = mongodb.blacklisted_users.find_one({'user': user_id}) if old: new = { 'user': user_id, 'date': old['date'], 'by': old['by'], 'reason': reason } mongodb.blacklisted_users.update_one({'_id': old['_id']}, {"$set": new}, upsert=False) await event.reply( "This user already blacklisted! I'll update the reason.") return date = strftime("%Y-%m-%d %H:%M:%S", gmtime()) new = { 'user': user_id, 'date': date, 'reason': reason, 'by': event.from_id } logger.info(f'user {user_id} gbanned by {event.from_id}') mongodb.blacklisted_users.insert_one(new) await event.reply( "Sudo {} blacklisted {}.\nDate: `{}`\nReason: `{}`".format( await user_link(event.from_id), await user_link(user_id), date, reason))
async def send_note(chat_id, group_id, msg_id, note_name, show_none=False, no_format=False, preview=False, from_id=""): file_id = None note_name = note_name.lower() note = await db.notes.find_one({ 'chat_id': int(group_id), 'name': note_name }) if not note and show_none is True: text = get_string("notes", "note_not_found", chat_id) all_notes = await db.notes.find({'chat_id': group_id}) if all_notes.count() > 0: check = difflib.get_close_matches(note_name, [d['name'] for d in all_notes]) if len(check) > 0: text += "\nDid you mean `#{}`?".format(check[0]) await tbot.send_message(chat_id, text, reply_to=msg_id) return elif not note: return None if note['file_id']: file_id = note['file_id'] if not file_id: file_id = None if 'encrypted' not in note or note['encrypted'] is False: raw_note_text = note['text'] elif 'encrypted' in note: if note['encrypted'] == 'particle-v1': raw_note_text = bz2.decompress( base64.urlsafe_b64decode(note['text'])).decode() if no_format is True: parse_format = None string = raw_note_text buttons = "" else: string, buttons = button_parser(group_id, raw_note_text) h = re.search(r"(\[format:(markdown|md|html|none)\])", string) if h: string = string.replace(h.group(1), "") format_raw = h.group(2).lower() if format_raw == 'markdown' or format_raw == 'md': parse_format = 'md' elif format_raw == 'html': parse_format = 'html' elif format_raw == 'none': parse_format = None else: parse_format = 'md' r = re.search(r"(\[preview:(yes|no)\])", string) if r: string = string.replace(r.group(1), "") preview_raw = r.group(2).lower() if preview_raw == "yes": preview = True elif preview_raw == "no": preview = False if len(string.rstrip()) == 0: if no_format is True: string = "Note {}\n\n".format(note_name) else: string = "**Note {}**\n\n".format(note_name) if not buttons: buttons = None if from_id: user = await db.user_list.find_one({"user_id": from_id}) if not user: user = await add_user_to_db(await tbot(GetFullUserRequest(from_id))) if 'last_name' in user: last_name = user['last_name'] if not last_name: last_name = "" full_name = user['first_name'] + " " + last_name else: last_name = None full_name = user['first_name'] if 'username' in user and user['username']: username = "******" + user['username'] else: username = None chat_name = await db.chat_list.find_one({'chat_id': group_id}) if chat_name: chat_name = chat_name['chat_title'] else: chat_name = "None" if no_format is False: if parse_format == "md": mention_str = await user_link(from_id) elif parse_format == "html": mention_str = await user_link_html(from_id) else: mention_str = full_name try: string = string.format(first=user['first_name'], last=last_name, fullname=full_name, username=username, id=from_id, mention=mention_str, chatname=chat_name) except KeyError as var: await tbot.send_message( chat_id, f"variable `{var}` not supported! Please delete it from note.", reply_to=msg_id) return try: return await tbot.send_message(chat_id, string, buttons=buttons, parse_mode=parse_format, reply_to=msg_id, file=file_id, link_preview=preview) except Exception as err: await tbot.send_message(chat_id, str(err)) logger.error("Error in send_note/send_message: " + str(err))
async def releasing(query, state): async with state.proxy() as data: file_id = data['file_id'] codename = data['device_codename'] build_type = data['build_type'] file_name = data['file_name'] build_date = data['build_date'] device = mongodb.ofox_devices.find_one({'codename': codename}) build_info_file_txt = "OrangeFox Recovery build info" build_info_file_txt += "\nBuild version: " + data['build_ver'] build_info_file_txt += "\nBuild type: " + data['build_type'] build_info_file_txt += "\nFile name: " + file_name build_info_file_txt += "\nFile size: " + data['file_size'] build_info_file_txt += "\nFile MD5: " + data['file_md5'] build_info_file_txt += "\nFile SHA256: " + data['file_sha256'] if 'special_notes' in data: build_info_file_txt += "\nBuild notes:\n" + data['special_notes'] if 'build_bugs' not in data: build_info_file_txt += "\nBuild bugs: Nothing" else: build_info_file_txt += "\nBuild bugs:\n" + data['build_bugs'] build_info_file_txt += "\nChangelog:\n" + data['changelog_text'] if build_type == 'stable': files_dir = 'OrangeFox-Stable/' release_text = "<b>OrangeFox Recovery</b>" channel = FOX_STABLE_CHANNEL sdir = 'OrangeFox-Stable/' else: files_dir = 'OrangeFox-Beta/' release_text = "<b>OrangeFox Recovery Beta</b>" channel = FOX_BETA_CHANNEL sdir = 'OrangeFox-Beta/' # OwO release_text += f"\n📱 <b>{device['fullname']}</b> (<code>{device['codename']}</code>)" release_text += f"\n🔺 Version: <code>{data['build_ver']}</code>" release_text += f"\n👨🔬 Maintainer: {device['maintainer']}" if 'file_md5' in data: release_text += f"\n✅ File MD5: <code>{data['file_md5']}</code>" release_text += f'\n🗒Changelog:\n' + data['changelog_text'] new = { f'{build_type}_ver': data['build_ver'], f'{build_type}_build': file_name, f'{build_type}_date': build_date, f'{build_type}_md5': data['file_md5'], f'{build_type}_sha256': data['file_sha256'], f'{build_type}_changelog': data['changelog_text'] } if 'build_bugs' in data: new[f'{build_type}_build_bugs'] = data['build_bugs'] release_text += f'\n🐞 Build Bugs:\n' + data['build_bugs'] else: mongodb.ofox_devices.update_one( {'codename': codename}, {'$unset': { f'{build_type}_build_bugs': 1 }}) if 'special_notes' in data: new[f'{build_type}_special_notes'] = data['special_notes'] release_text += '\n📝 Build Notes:\n' + data['special_notes'] else: mongodb.ofox_devices.update_one( {'codename': codename}, {'$unset': { f'{build_type}_special_notes': 1 }}) if build_type == 'stable': release_text += '\n<a href="https://t.me/OrangeFoxChat">OrangeFox Recovery Support chat</a>' else: release_text += '\n<a href="https://t.me/joinchat/HNZTNkxOlyslccxryvKeeQ">OrangeFox Beta chat</a>' await query.message.edit_text( "Releasing. Moving files, uploading to SourceForge and making magic, please wait..." ) # Copy file to stable dir if not os.path.exists(FOX_FILES_LOCAL + sdir): os.makedirs(FOX_FILES_LOCAL + sdir) path = FOX_FILES_LOCAL + sdir + codename + '/' if not os.path.exists(path): os.makedirs(path) local_file = path + file_name subprocess.call(f'mv OrangeFox-temp-builds/{file_name} {local_file}', shell=True) with open(local_file[:-3] + 'txt', 'w') as f: f.write(build_info_file_txt) sf = False if build_type == 'stable': # SourceForge try: cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection(host=SF_host, username=SF_user, password=SF_pass, cnopts=cnopts) as sftp: with sftp.cd('/home/frs/project/orangefox'): if not sftp.isdir(codename): sftp.mkdir(codename) with sftp.cd('/home/frs/project/orangefox/' + codename): sftp.put(local_file) new[f'{build_type}_sf'] = True sf = True except Exception as err: await query.message.answer("Can't connect to SF, skipping!") new[f'{build_type}_sf'] = False sf = False logger.error(err) mongodb.ofox_devices.update_one({'codename': codename}, {'$set': new}) mongodb.ofox_devices.update_one({'codename': codename}, {'$unset': { f'{build_type}_migrated': 1 }}) build_json_file() buttons = InlineKeyboardMarkup().add( InlineKeyboardButton("⬇️ Direct download", url=FOX_DOMAIN + files_dir + codename + '/' + file_name)) if sf is True: sf_url = 'https://sourceforge.net/projects/orangefox/files/' + codename + '/' + file_name buttons.add(InlineKeyboardButton("☁️ Cloud", url=sf_url)) # Send sticker await bot.send_document(channel, "CAADAgADAwAD6rr0F491IJH_DoTNFgQ") # Send release await bot.send_document(channel, file_id, caption=release_text, reply_markup=buttons) await query.message.edit_text("All done!") await state.finish()
async def send_note(chat_id, group_id, msg_id, note_name, show_none=False, noformat=False, preview=False, from_id="", key=False): file_id = None note_name = note_name.lower() note = mongodb.notes.find_one({'chat_id': int(group_id), 'name': note_name}) if not note and show_none is True: text = get_string("notes", "note_not_found", chat_id) all_notes = mongodb.notes.find({'chat_id': group_id}) if all_notes.count() > 0: check = difflib.get_close_matches(note_name, [d['name'] for d in all_notes]) if len(check) > 0: text += "\nDid you mean `#{}`?".format(check[0]) await tbot.send_message(chat_id, text, reply_to=msg_id) return elif not note: return None if note['file_id']: file_id = note['file_id'] if not file_id: file_id = None if 'encrypted' not in note or note['encrypted'] is False: raw_note_text = note['text'] elif 'encrypted' in note: if note['encrypted'] == 'particle-v1': raw_note_text = bz2.decompress(base64.urlsafe_b64decode(note['text'])).decode() else: if not key: await tbot.send_message(chat_id, "This note encrypted! Please write a password!", reply_to=msg_id) return salt = note['encrypted'] kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=default_backend() ) key = base64.urlsafe_b64encode(kdf.derive(key.encode())) f = Fernet(key) try: raw_note_text = f.decrypt(note['text']).decode() if file_id: file_id = f.decrypt(file_id).decode() except InvalidToken: await tbot.send_message(chat_id, "Invalid password!", reply_to=msg_id) return if noformat is True: format = None string = raw_note_text buttons = "" else: string, buttons = button_parser(group_id, raw_note_text) h = re.search(r"(\[format:(markdown|md|html|none)\])", string) if h: string = string.replace(h.group(1), "") format_raw = h.group(2).lower() if format_raw == 'markdown' or format_raw == 'md': format = 'md' elif format_raw == 'html': format = 'html' elif format_raw == 'none': format = None else: format = 'md' r = re.search(r"(\[preview:(yes|no)\])", string) if r: string = string.replace(r.group(1), "") preview_raw = r.group(2).lower() if preview_raw == "yes": preview = True elif preview_raw == "no": preview = False if len(string.rstrip()) == 0: if noformat is True: string = "Note {}\n\n".format(note_name) else: string = "**Note {}**\n\n".format(note_name) if not buttons: buttons = None if from_id: user = mongodb.user_list.find_one({"user_id": from_id}) if not user: user = await add_user_to_db(await tbot(GetFullUserRequest(int(from_id)))) if 'last_name' in user: last_name = user['last_name'] if not last_name: last_name = "" full_name = user['first_name'] + " " + last_name else: last_name = None full_name = user['first_name'] if 'username' in user and user['username']: username = "******" + user['username'] else: username = None chatname = mongodb.chat_list.find_one({'chat_id': group_id}) if chatname: chatname = chatname['chat_title'] else: chatname = "None" if noformat is True: string = string.format( first="{first}", last="{last}", fullname="{fullname}", username="******", mention="{mention}", id="{id}", chatname="{chatname}", ) else: if format == "md": mention_str = await user_link(from_id) elif format == "html": mention_str = await user_link_html(from_id) elif format == "none": mention_str = full_name string = string.format( first=user['first_name'], last=last_name, fullname=full_name, username=username, id=from_id, mention=mention_str, chatname=chatname ) try: return await tbot.send_message( chat_id, string, buttons=buttons, parse_mode=format, reply_to=msg_id, file=file_id, link_preview=preview ) except Exception as err: await tbot.send_message(chat_id, str(err)) logger.error("Error in send_note/send_message: " + str(err))
async def update_users(event): chat_id = event.chat_id user_id = event.from_id user = await bot.get_entity(user_id) chat = await bot.get_entity(chat_id) old_chat = mongodb.chat_list.find_one({'chat_id': chat_id}) old_user = mongodb.user_list.find_one({'user_id': user_id}) new_chat = [chat_id] if old_user: if 'chats' in old_user: new_chat = old_user['chats'] if chat_id not in new_chat: new_chat.append(chat_id) if not hasattr(chat, 'username'): chatnick = None else: chatnick = chat.username # Chats with no title is pm if hasattr(chat, 'title'): chat_new = { "chat_id": chat_id, "chat_title": chat.title, "chat_nick": chatnick } if old_chat: mongodb.user_list.update_one({'_id': old_chat['_id']}, {"$set": chat_new}, upsert=False) else: mongodb.chat_list.insert_one(chat_new) logger.debug(f"chat {chat_id} updated") user_new = { 'user_id': user_id, 'first_name': user.first_name, 'last_name': user.last_name, 'username': user.username, 'user_lang': user.lang_code, 'chats': new_chat } if old_user: mongodb.user_list.update_one({'_id': old_user['_id']}, {"$set": user_new}, upsert=False) else: mongodb.user_list.insert_one(user_new) logger.debug(f"user {user_id} updated") try: if event.message.reply_to_msg_id: msg = await event.get_reply_message() user_id = msg.from_id user = await bot.get_entity(user_id) old_user = mongodb.user_list.find_one({'user_id': user_id}) new_user = { 'user_id': user_id, 'first_name': user.first_name, 'last_name': user.last_name, 'username': user.username, 'user_lang': user.lang_code } if old_user: mongodb.notes.update_one({'_id': old_user['_id']}, {"$set": user_new}, upsert=False) else: mongodb.user_list.insert_one(new_user) logger.debug(f"replied user {user_id} updated") except Exception as err: logger.error(err) if event.message.fwd_from: user_id = event.message.fwd_from.from_id user = await bot.get_entity(user_id) old_user = mongodb.user_list.find_one({'user_id': user_id}) new_user = { 'user_id': user_id, 'first_name': user.first_name, 'last_name': user.last_name, 'username': user.username, 'user_lang': user.lang_code } if old_user: mongodb.notes.update_one({'_id': old_user['_id']}, {"$set": user_new}, upsert=False) else: mongodb.user_list.insert_one(new_user) logger.debug(f"forwarded user {user_id} updated")
async def send_note(chat_id, group_id, msg_id, note_name, show_none=False, noformat=False, preview=False, from_id=""): file_id = None note = mongodb.notes.find_one({ 'chat_id': int(group_id), 'name': note_name }) if not note and show_none is True: await bot.send_message(chat_id, get_string("notes", "note_not_found", chat_id), reply_to=msg_id) return elif not note: return None if note['file_id']: file_id = note['file_id'] if not file_id: file_id = None if noformat is True: format = None string = note['text'] buttons = "" else: string, buttons = button_parser(group_id, note['text']) h = re.search(r"(\[format:(markdown|md|html|none)\])", string) if h: string = string.replace(h.group(1), "") format_raw = h.group(2).lower() if format_raw == 'markdown' or format_raw == 'md': format = 'md' elif format_raw == 'html': format = 'html' elif format_raw == 'none': format = None else: format = 'md' r = re.search(r"(\[preview:(yes|no)\])", string) if r: string = string.replace(r.group(1), "") preview_raw = r.group(2).lower() if preview_raw == "yes": preview = True elif preview_raw == "no": preview = False if len(string.rstrip()) == 0: if noformat is True: string = "Note {}\n\n".format(note_name) else: string = "**Note {}**\n\n".format(note_name) if not buttons: buttons = None if from_id: user = mongodb.user_list.find_one({"user_id": from_id}) if not user: user = await add_user_to_db(await bot(GetFullUserRequest(int(from_id)))) if 'last_name' in user: last_name = user['last_name'] if not last_name: last_name = "" full_name = user['first_name'] + " " + last_name else: last_name = None full_name = user['first_name'] if 'username' in user: username = user['username'] else: username = None chatname = mongodb.chat_list.find_one({'chat_id': group_id}) # Format vars string = string.format(first=user['first_name'], last=last_name, fullname=full_name, username=username, mention=await user_link(from_id), id=from_id, chatname=chatname['chat_title'], rules='Will be later') try: return await bot.send_message(chat_id, string, buttons=buttons, parse_mode=format, reply_to=msg_id, file=file_id, link_preview=preview) except Exception as err: await bot.send_message(chat_id, str(err)) logger.error("Error in send_note/send_message: " + str(err))
async def get_user(event): msg = event.message.raw_text.split() if event.reply_to_msg_id: msg = await event.get_reply_message() user = mongodb.user_list.find_one( {'user_id': msg.from_id}) # Will ask Telegram for help with it. if not user: try: user = await event.client(GetFullUserRequest(int(msg.from_id))) # Add user in database if user: user = add_user_to_db(user) except Exception as err: logger.error(err) else: if len(msg) > 1: msg_1 = msg[1] else: # Wont tagged any user, lets use sender user = mongodb.user_list.find_one({'user_id': event.from_id}) return user input_str = event.pattern_match.group(1) mention_entity = event.message.entities if input_str and input_str.isdigit(): input_str = int(input_str) # Search user in database if '@' in msg_1: # Remove '@' user = mongodb.user_list.find_one( {'username': msg_1[1:]} ) elif msg_1.isdigit(): # User id msg_1 = int(msg_1) user = mongodb.user_list.find_one( {'user_id': int(msg_1)} ) else: user = mongodb.user_list.find_one( {'username': input_str} ) # If we didn't find user in database will ask Telegram. if not user: try: user = await event.client(GetFullUserRequest(msg_1)) # Add user in database user = await add_user_to_db(user) except Exception as err: logger.error(err) # Still didn't find? Lets try get entities if mention_entity: if len(mention_entity) > 1: probable_user_mention_entity = mention_entity[1] else: probable_user_mention_entity = mention_entity[0] if not user: if not isinstance(probable_user_mention_entity, MessageEntityMentionName): user_id = await event.client.get_entity(input_str) return else: user_id = probable_user_mention_entity.user_id if user_id: userf = await event.client(GetFullUserRequest(int(user_id))) user = mongodb.user_list.find_one( {'user_id': int(userf.user.id)} ) if not user and userf: user = await add_user_to_db(userf) if not user: # Last try before fail try: user = await event.client.get_entity(input_str) if user: user = await add_user_to_db(user) except Exception as err: logger.error(err) return None if not user: await event.reply("I can't find this user in whole Telegram.") return None return user
async def report_error(event, telethon=False): error = str(sys.exc_info()[1]) class_error = sys.exc_info()[0].__name__ if class_error == 'ChatWriteForbiddenError': # This error mean bot is muted in chat return elif class_error == 'BadRequest' and error == 'Have no rights to send a message': return elif class_error == 'RetryAfter': return if telethon is True: msg = event chat_id = msg.chat_id lib = 'Telethon' else: msg = event.message chat_id = msg.chat.id lib = 'Aiogram' date = strftime("%Y-%m-%d %H:%M:%S", gmtime()) logger.error("Error: " + date) logger.error("Lib: " + lib) if telethon is True: logger.error(traceback.format_exc()) if DEBUG_MODE is True: await msg.reply(error) return new = { 'error_class_name': class_error, 'error': error, 'date': datetime.datetime.now() } mongodb.errors.insert_one(new) text = "<b>Sorry, I encountered a error!</b>\n" text += f"If you wanna you can report it - just press the \"Report error\" button.\n" text += "Till you press report button your data will be only here.\n" text += "<a href=\"https://t.me/YanaBotGroup\">Sophie support chat</a>" ftext = "Sophie error log file." ftext += "\n______________________\n" ftext += "\nDate: " + date ftext += "\nLib: " + lib ftext += "\nGroup ID: " + str(chat_id) ftext += "\nSender ID: " + str(msg.from_user.id if lib == "Aiogram" else msg.from_id) ftext += "\nText: " + str(msg.text or "") ftext += "\n\nRaw update text:\n" ftext += str(event) ftext += "\n\nTraceback info:\n" ftext += str(traceback.format_exc()) ftext += "\n\nFormatted update text:\n" ftext += str(ujson.dumps(msg, indent=2)) command = "git log --pretty=format:\"%an: %s\" -5" ftext += "\n\n\nLast 5 commits:\n" ftext += await term(command) buttons = InlineKeyboardMarkup(row_width=1).add( InlineKeyboardButton( "Delete message", callback_data='get_delete_msg_{}_admin'.format(chat_id))) if CONFIG['advanced']['errors_channel_enabled'] is True: buttons.insert( InlineKeyboardButton("Report error", callback_data='report_error')) await bot.send_document(chat_id, types.InputFile(io.StringIO(ftext), filename="Error.txt"), caption=text, reply_to_message_id=msg.message_id if lib == "Aiogram" else msg.message.id, reply_markup=buttons) return
def update_devices(): global DEVICES_STABLE global DEVICES_BETA response_stable = requests.get(stable_url, params={}) if not response_stable.ok: logger.error(response_stable.raise_for_status()) return response_beta = requests.get(beta_url, params={}) if not response_beta.ok: logger.error(response_beta.raise_for_status()) return soup_stable = BeautifulSoup(response_stable.text, 'html.parser') soup_beta = BeautifulSoup(response_beta.text, 'html.parser') stable_devices_list = re.findall( r'<a href="/OrangeFox-Stable/(.+?)/">.+?</a>', str(soup_stable)) beta_devices_list = re.findall(r'<a href="/OrangeFox%20Beta/(.+?)/">.+?</a>', str(soup_beta)) for device in stable_devices_list: link = stable_url + device raw = requests.get(link, params={}) if not raw.ok: logger.error(raw) continue text = BeautifulSoup(raw.text, 'html.parser') builds = re.search(r"OrangeFox-(\w*)-(\w*)-(\w*)-(\w*)\.zip", str(text)) if not builds: builds = re.search(r"OrangeFox-(\w*)-(\w*)-(\w*)\.zip", str(text)) if not builds: builds = re.search(r">OrangeFox-(.*)\.zip", str(text)) if builds[0] == ">": builds = builds[1:] link = stable_url + device + '/device_info.txt' raw = requests.get(link, params={}) if not raw.ok: logger.error(raw) continue text = BeautifulSoup(raw.text, 'html.parser') codename = re.search(r"Codename: (.*)", str(text)).group(1) fullname = re.search(r"Device name: (.*)", str(text)).group(1) maintainer = re.search(r"Maintainer: (.*)", str(text)).group(1) DEVICES_STABLE[device] = { "codename": codename, "fullname": fullname, "maintainer": maintainer, "ver": builds.group() } for device in beta_devices_list: link = beta_url + device raw = requests.get(link, params={}) if not raw.ok: logger.error(raw) continue text = BeautifulSoup(raw.text, 'html.parser') builds = re.search(r"OrangeFox-(\w*)-(\w*)-(\w*)-(\w*)\.zip", str(text)) if not builds: builds = re.search(r"OrangeFox-(\w*)-(\w*)-(\w*)\.zip", str(text)) link = beta_url + device + '/device_info.txt' raw = requests.get(link, params={}) if not raw.ok: logger.error(raw) continue text = BeautifulSoup(raw.text, 'html.parser') codename = re.search(r"Codename: (.*)", str(text)).group(1) fullname = re.search(r"Device name: (.*)", str(text)).group(1) maintainer = re.search(r"Maintainer: (.*)", str(text)).group(1) DEVICES_BETA[device] = { "codename": codename, "fullname": fullname, "maintainer": maintainer, "ver": builds.group() }