def __list_all_modules(): import glob from os.path import basename, dirname, isfile # This generates a list of modules in this folder for the * in __main__ to work. mod_paths = glob.glob(dirname(__file__) + "/*.py") all_modules = [ basename(f)[:-3] for f in mod_paths if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") ] if LOAD or NO_LOAD: to_load = LOAD if to_load: if not all( any(mod == module_name for module_name in all_modules) for mod in to_load): LOGGER.error("Invalid loadorder names. Quitting.") quit(1) all_modules = sorted(set(all_modules) - set(to_load)) to_load = list(all_modules) + to_load else: to_load = all_modules if NO_LOAD: LOGGER.info("Not loading: {}".format(NO_LOAD)) return [item for item in to_load if item not in NO_LOAD] return to_load return all_modules
def send(msg, bot, update): if len(str(msg)) > 2000: with io.BytesIO(str.encode(msg)) as out_file: out_file.name = "output.txt" bot.send_document(chat_id=update.effective_chat.id, document=out_file) else: LOGGER.info(f"OUT: '{msg}'") bot.send_message( chat_id=update.effective_chat.id, text=f"`{msg}`", parse_mode=ParseMode.MARKDOWN, )
def migrate_chats(update: Update, context: CallbackContext): msg = update.effective_message # type: Optional[Message] if msg.migrate_to_chat_id: old_chat = update.effective_chat.id new_chat = msg.migrate_to_chat_id elif msg.migrate_from_chat_id: old_chat = msg.migrate_from_chat_id new_chat = update.effective_chat.id else: return LOGGER.info("Migrating from %s, to %s", str(old_chat), str(new_chat)) for mod in MIGRATEABLE: mod.__migrate__(old_chat, new_chat) LOGGER.info("Successfully migrated!") raise DispatcherHandlerStop
def main(): test_handler = CommandHandler("test", test, run_async=True) start_handler = CommandHandler("start", start, run_async=True) help_handler = CommandHandler("help", get_help, run_async=True) help_callback_handler = CallbackQueryHandler(help_button, pattern=r"help_.*", run_async=True) settings_handler = CommandHandler("settings", get_settings, run_async=True) settings_callback_handler = CallbackQueryHandler(settings_button, pattern=r"stngs_", run_async=True) donate_handler = CommandHandler("donate", donate, run_async=True) migrate_handler = MessageHandler(Filters.status_update.migrate, migrate_chats) # dispatcher.add_handler(test_handler) dispatcher.add_handler(start_handler) dispatcher.add_handler(help_handler) dispatcher.add_handler(settings_handler) dispatcher.add_handler(help_callback_handler) dispatcher.add_handler(settings_callback_handler) dispatcher.add_handler(migrate_handler) dispatcher.add_handler(donate_handler) dispatcher.add_error_handler(error_callback) if WEBHOOK: LOGGER.info("Using webhooks.") updater.start_webhook(listen="0.0.0.0", port=PORT, url_path=TOKEN) if CERT_PATH: updater.bot.set_webhook(url=URL + TOKEN, certificate=open(CERT_PATH, "rb")) else: updater.bot.set_webhook(url=URL + TOKEN) else: LOGGER.info("Using long polling.") updater.start_polling(timeout=15, read_latency=4, drop_pending_updates=True) if len(argv) not in (1, 3, 4): telethn.disconnect() else: telethn.run_until_disconnected() updater.idle()
def shell(update: Update, context: CallbackContext): message = update.effective_message cmd = message.text.split(" ", 1) if len(cmd) == 1: message.reply_text("No command to execute was given.") return cmd = cmd[1] process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True ) stdout, stderr = process.communicate() msg = "" stderr = stderr.decode() stdout = stdout.decode() if stdout: msg += f"*Stdout*\n`{stdout}`\n" LOGGER.info(f"Shell - {cmd} - {stdout}") if stderr: msg += f"*Stderr*\n`{stderr}`\n" LOGGER.error(f"Shell - {cmd} - {stderr}") if len(msg) > 3000: with open("shell_output.txt", "w") as file: file.write(msg) with open("shell_output.txt", "rb") as doc: message.reply_document( document = doc, filename = doc.name, reply_to_message_id = message.message_id, ) else: message.reply_text( text = msg, parse_mode = ParseMode.MARKDOWN, disable_web_page_preview = True, )
def term(cmd, info): process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout, stderr = process.communicate() stderr = stderr.decode() stdout = stdout.decode() if stdout: log.info(f"{info} successful!") log.info(f"{stdout}") if stderr: log.error(f"error while running {info}") log.info(f"{stderr}")
if isfile(f) and f.endswith(".py") and not f.endswith("__init__.py") ] if LOAD or NO_LOAD: to_load = LOAD if to_load: if not all( any(mod == module_name for module_name in all_modules) for mod in to_load): LOGGER.error("Invalid loadorder names. Quitting.") quit(1) all_modules = sorted(set(all_modules) - set(to_load)) to_load = list(all_modules) + to_load else: to_load = all_modules if NO_LOAD: LOGGER.info("Not loading: {}".format(NO_LOAD)) return [item for item in to_load if item not in NO_LOAD] return to_load return all_modules ALL_MODULES = __list_all_modules() LOGGER.info("Modules to load: %s", str(ALL_MODULES)) __all__ = ALL_MODULES + ["ALL_MODULES"]
def backup_db(_: CallbackContext): bot = dispatcher.bot tmpmsg = "Performing backup, Please wait..." tmp = bot.send_message(OWNER_ID, tmpmsg) datenow = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") dbbkpname = "db_{}_{}.tar".format(bot.username, datenow) bkplocation = "backups/{}".format(datenow) bkpcmd = "pg_dump {} --format=tar > {}/{}".format(DB_NAME, bkplocation, dbbkpname) if not os.path.exists(bkplocation): os.makedirs(bkplocation) log.info("performing db backup") loginfo = "db backup" term(bkpcmd, loginfo) if not os.path.exists('{}/{}'.format(bkplocation, dbbkpname)): bot.send_message(OWNER_ID, "An error occurred during the db backup") tmp.edit_text("Backup Failed!") sleep(8) tmp.delete() return else: log.info("copying config, and logs to backup location") if os.path.exists('log.txt'): print("logs copied") shutil.copyfile('log.txt', '{}/log.txt'.format(bkplocation)) if os.path.exists('AnnaBot/config.py'): print("config copied") shutil.copyfile('AnnaBot/config.py', '{}/config.py'.format(bkplocation)) log.info("zipping the backup") zipcmd = "zip --password '{}' {} {}/*".format(zip_pass, bkplocation, bkplocation) zipinfo = "zipping db backup" log.info("zip started") term(zipcmd, zipinfo) log.info("zip done") sleep(1) with open('backups/{}'.format(f'{datenow}.zip'), 'rb') as bkp: nm = "{} backup \n".format(bot.username) + datenow bot.send_document(OWNER_ID, document=bkp, caption=nm, timeout=20) log.info("removing zipped files") shutil.rmtree("backups/{}".format(datenow)) log.info("backup done") tmp.edit_text("Backup complete!") sleep(5) tmp.delete()
dispatcher.add_handler(migrate_handler) dispatcher.add_handler(donate_handler) dispatcher.add_error_handler(error_callback) if WEBHOOK: LOGGER.info("Using webhooks.") updater.start_webhook(listen="0.0.0.0", port=PORT, url_path=TOKEN) if CERT_PATH: updater.bot.set_webhook(url=URL + TOKEN, certificate=open(CERT_PATH, "rb")) else: updater.bot.set_webhook(url=URL + TOKEN) else: LOGGER.info("Using long polling.") updater.start_polling(timeout=15, read_latency=4, drop_pending_updates=True) if len(argv) not in (1, 3, 4): telethn.disconnect() else: telethn.run_until_disconnected() updater.idle() if __name__ == "__main__": LOGGER.info("Successfully loaded modules: " + str(ALL_MODULES)) telethn.start(bot_token=TOKEN) main()
def log_input(update): user = update.effective_user.id chat = update.effective_chat.id LOGGER.info(f"IN: {update.effective_message.text} (user={user}, chat={chat})")