From 1fd46d9a8f893badb409b7172584eda19b800c0c Mon Sep 17 00:00:00 2001 From: Andreas Bielawski Date: Sat, 5 Jan 2019 15:14:54 +0100 Subject: [PATCH] Faster startup time and replace ' with " --- bot.py | 173 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 86 insertions(+), 87 deletions(-) diff --git a/bot.py b/bot.py index 32d6db2..1cfb337 100644 --- a/bot.py +++ b/bot.py @@ -11,6 +11,7 @@ from urllib.parse import urlparse import feedparser import redis import telegram +from telegram.error import Unauthorized from telegram.ext import CommandHandler, Updater from telegram.ext.dispatcher import run_async @@ -18,9 +19,9 @@ import utils config = ConfigParser() try: - config.read_file(open('config.ini')) + config.read_file(open("config.ini")) except FileNotFoundError: - logging.critical('Config.ini nicht gefunden') + logging.critical("Config.ini nicht gefunden") sys.exit(1) # Logging @@ -43,35 +44,35 @@ logger = logging.getLogger(__name__) # Bot token try: - bot_token = config['DEFAULT']['token'] + bot_token = config["DEFAULT"]["token"] except KeyError: - logger.error('Kein Bot-Token gesetzt, bitte config.ini prüfen') + logger.error("Kein Bot-Token gesetzt, bitte config.ini prüfen") sys.exit(1) if not bot_token: - logger.error('Kein Bot-Token gesetzt, bitte config.ini prüfen') + logger.error("Kein Bot-Token gesetzt, bitte config.ini prüfen") sys.exit(1) # Admins try: admins = loads(config["ADMIN"]["id"]) except KeyError: - logger.error('Keine Admin-IDs gesetzt, bitte config.ini prüfen.') + logger.error("Keine Admin-IDs gesetzt, bitte config.ini prüfen.") sys.exit(1) if not admins: - logger.error('Keine Admin-IDs gesetzt, bitte config.ini prüfen.') + logger.error("Keine Admin-IDs gesetzt, bitte config.ini prüfen.") sys.exit(1) for admin in admins: if not isinstance(admin, int): - logger.error('Admin-IDs müssen Integer sein.') + logger.error("Admin-IDs müssen Integer sein.") sys.exit(1) # Redis -redis_conf = config['REDIS'] -redis_db = redis_conf.get('db', 0) -redis_host = redis_conf.get('host', '127.0.0.1') -redis_port = redis_conf.get('port', 6379) -redis_socket = redis_conf.get('socket_path') +redis_conf = config["REDIS"] +redis_db = redis_conf.get("db", 0) +redis_host = redis_conf.get("host", "127.0.0.1") +redis_port = redis_conf.get("port", 6379) +redis_socket = redis_conf.get("socket_path") if redis_socket: r = redis.Redis(unix_socket_path=redis_socket, db=int(redis_db), decode_responses=True) else: @@ -81,7 +82,7 @@ if not r.ping(): logging.getLogger("Redis").critical("Redis-Verbindungsfehler, config.ini prüfen") sys.exit(1) -feed_hash = 'pythonbot:rss:{0}' +feed_hash = "pythonbot:rss:{0}" @run_async @@ -89,7 +90,7 @@ def start(bot, update): if not utils.can_use_bot(update): return update.message.reply_text( - text='Willkommen beim RSS-Bot!\nSende /help, um zu starten.', + text="Willkommen beim RSS-Bot!\nSende /help, um zu starten.", parse_mode=telegram.ParseMode.HTML ) @@ -99,9 +100,9 @@ def help_text(bot, update): if not utils.can_use_bot(update): return update.message.reply_text( - text='/rss [Chat]: Abonnierte Feeds anzeigen\n' - '/sub Feed-URL [Chat]: Feed abonnieren\n' - '/del n [Chat]: Feed löschen', + text="/rss [Chat]: Abonnierte Feeds anzeigen\n" + "/sub Feed-URL [Chat]: Feed abonnieren\n" + "/del n [Chat]: Feed löschen", parse_mode=telegram.ParseMode.HTML ) @@ -115,24 +116,24 @@ def list_feeds(bot, update, args): try: resp = bot.getChat(chat_name) except telegram.error.BadRequest: - update.message.reply_text('❌ Dieser Kanal existiert nicht.') + update.message.reply_text("❌ Dieser Kanal existiert nicht.") return chat_id = str(resp.id) chat_title = resp.title else: chat_id = str(update.message.chat.id) - if update.message.chat.type == 'private': + if update.message.chat.type == "private": chat_title = update.message.chat.first_name else: chat_title = update.message.chat.title subs = r.smembers(feed_hash.format(chat_id)) if not subs: - text = '❌ Keine Feeds abonniert.' + text = "❌ Keine Feeds abonniert." else: - text = '' + html.escape(chat_title) + ' hat abonniert:\n' + text = "" + html.escape(chat_title) + " hat abonniert:\n" for n, feed in enumerate(subs): - text += '' + str(n + 1) + ') ' + feed + '\n' + text += "" + str(n + 1) + ") " + feed + "\n" update.message.reply_text( text=text, @@ -145,11 +146,11 @@ def subscribe(bot, update, args): if not utils.can_use_bot(update): return if not args: - update.message.reply_text('❌ Keine Feed-URL angegeben.') + update.message.reply_text("❌ Keine Feed-URL angegeben.") return feed_url = args[0] if not re.match("^http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&~+]|[!*(),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+$", feed_url): - update.message.reply_text('❌ Das ist keine URL.') + update.message.reply_text("❌ Das ist keine URL.") return # Get Chat ID from name if given @@ -158,45 +159,45 @@ def subscribe(bot, update, args): try: resp = bot.getChat(chat_name) except telegram.error.BadRequest: - update.message.reply_text('❌ Dieser Kanal existiert nicht.') + update.message.reply_text("❌ Dieser Kanal existiert nicht.") return chat_id = str(resp.id) resp = bot.getChatMember(chat_id, bot.id) - if resp.status != 'administrator': - update.message.reply_text('❌ Bot ist kein Administrator in diesem Kanal.') + if resp.status != "administrator": + update.message.reply_text("❌ Bot ist kein Administrator in diesem Kanal.") return else: chat_id = str(update.message.chat.id) bot.sendChatAction(update.message.chat.id, action=telegram.ChatAction.TYPING) data = feedparser.parse(feed_url) - if 'link' not in data.feed: - update.message.reply_text('❌ Kein gültiger Feed.') + if "link" not in data.feed: + update.message.reply_text("❌ Kein gültiger Feed.") return feed_url = data.href # Follow all redirects if r.sismember(feed_hash.format(chat_id), feed_url): - update.message.reply_text('✅ Dieser Feed wurde bereits abonniert.') + update.message.reply_text("✅ Dieser Feed wurde bereits abonniert.") return - if 'title' not in data.feed: + if "title" not in data.feed: feed_title = feed_url else: - feed_title = html.escape(data.feed['title']) + feed_title = html.escape(data.feed["title"]) # Save the last entry in Redis, if it doesn't exist if data.entries: - last_entry_hash = feed_hash.format(feed_url + ':last_entry') + last_entry_hash = feed_hash.format(feed_url + ":last_entry") if not r.exists(last_entry_hash): - if 'id' not in data.entries[0]: - last_entry = data.entries[0]['link'] + if "id" not in data.entries[0]: + last_entry = data.entries[0]["link"] else: - last_entry = data.entries[0]['id'] + last_entry = data.entries[0]["id"] r.set(last_entry_hash, last_entry) - r.sadd(feed_hash.format(feed_url + ':subs'), chat_id) + r.sadd(feed_hash.format(feed_url + ":subs"), chat_id) r.sadd(feed_hash.format(chat_id), feed_url) update.message.reply_text( - text='✅ ' + feed_title + ' hinzugefügt!', + text="✅ " + feed_title + " hinzugefügt!", parse_mode=telegram.ParseMode.HTML ) @@ -206,7 +207,7 @@ def unsubscribe(bot, update, args): if not utils.can_use_bot(update): return if not args: - update.message.reply_text('❌ Keine Nummer angegeben.') + update.message.reply_text("❌ Keine Nummer angegeben.") return # Get Chat ID from name if given @@ -215,7 +216,7 @@ def unsubscribe(bot, update, args): try: resp = bot.getChat(chat_name) except telegram.error.BadRequest: - update.message.reply_text('❌ Dieser Kanal existiert nicht.') + update.message.reply_text("❌ Dieser Kanal existiert nicht.") return chat_id = str(resp.id) else: @@ -224,78 +225,78 @@ def unsubscribe(bot, update, args): try: n = int(args[0]) except ValueError: - update.message.reply_text('❌ Keine Nummer angegeben.') + update.message.reply_text("❌ Keine Nummer angegeben.") return chat_hash = feed_hash.format(chat_id) subs = r.smembers(chat_hash) if n < 1: - update.message.reply_text('❌ Nummer muss größer als 0 sein!') + update.message.reply_text("❌ Nummer muss größer als 0 sein!") return elif n > len(subs): - update.message.reply_text('❌ Feed-ID zu hoch.') + update.message.reply_text("❌ Feed-ID zu hoch.") return feed_url = list(subs)[n - 1] - sub_hash = feed_hash.format(feed_url + ':subs') + sub_hash = feed_hash.format(feed_url + ":subs") r.srem(chat_hash, feed_url) r.srem(sub_hash, chat_id) if not r.smembers(sub_hash): # no one subscribed, remove it - r.delete(feed_hash.format(feed_url + ':last_entry')) + r.delete(feed_hash.format(feed_url + ":last_entry")) update.message.reply_text( - text='✅ ' + feed_url + ' entfernt.', + text="✅ " + feed_url + " entfernt.", parse_mode=telegram.ParseMode.HTML ) @run_async def check_feed(bot, key): - feed_url = re.match('^' + feed_hash.format('(.+):subs$'), key).group(1) + feed_url = re.match("^" + feed_hash.format("(.+):subs$"), key).group(1) logger.info(feed_url) data = feedparser.parse(feed_url) - if 'link' not in data.feed: - if 'status' in data and data["status"] != 200: - logger.warning(feed_url + ' - Kein gültiger Feed, HTTP-Status-Code ' + str(data["status"])) + if "link" not in data.feed: + if "status" in data and data["status"] != 200: + logger.warning(feed_url + " - Kein gültiger Feed, HTTP-Status-Code " + str(data["status"])) else: - logger.warning(feed_url + ' - Kein gültiger Feed: ' + str(data.bozo_exception)) + logger.warning(feed_url + " - Kein gültiger Feed: " + str(data.bozo_exception)) return None - if 'title' not in data.feed: - feed_title = data.feed['link'] + if "title" not in data.feed: + feed_title = data.feed["link"] else: - feed_title = data.feed['title'] - last_entry_hash = feed_hash.format(feed_url + ':last_entry') + feed_title = data.feed["title"] + last_entry_hash = feed_hash.format(feed_url + ":last_entry") last_entry = r.get(last_entry_hash) new_entries = utils.get_new_entries(data.entries, last_entry) for entry in reversed(new_entries): - if 'title' not in entry: - post_title = 'Kein Titel' + if "title" not in entry: + post_title = "Kein Titel" else: - post_title = utils.remove_html_tags(entry['title']).strip() - post_title = post_title.replace('<', '<').replace('>', '>') - if 'link' not in entry: + post_title = utils.remove_html_tags(entry["title"]).strip() + post_title = post_title.replace("<", "<").replace(">", ">") + if "link" not in entry: post_link = data.link link_name = post_link else: post_link = entry.link - feedproxy = re.search('^https?://feedproxy\.google\.com/~r/(.+?)/.*', post_link) # feedproxy.google.com + feedproxy = re.search("^https?://feedproxy\.google\.com/~r/(.+?)/.*", post_link) # feedproxy.google.com if feedproxy: link_name = feedproxy.group(1) else: link_name = urlparse(post_link).netloc - link_name = re.sub('^www\d?\.', '', link_name) # remove www. - if 'content' in entry: - content = utils.get_content(entry.content[0]['value']) - elif 'summary' in entry: + link_name = re.sub("^www\d?\.", "", link_name) # remove www. + if "content" in entry: + content = utils.get_content(entry.content[0]["value"]) + elif "summary" in entry: content = utils.get_content(entry.summary) else: - content = '' - text = '{post_title}\n{feed_title}\n{content}'.format( + content = "" + text = "{post_title}\n{feed_title}\n{content}".format( post_title=post_title, feed_title=feed_title, content=content ) - text += '\nAuf {link_name} weiterlesen\n'.format( + text += "\nAuf {link_name} weiterlesen\n".format( post_link=post_link, link_name=link_name ) @@ -308,12 +309,12 @@ def check_feed(bot, key): disable_web_page_preview=True ) except telegram.error.Unauthorized: - logger.warning('Chat ' + member + ' existiert nicht mehr, wird gelöscht.') + logger.warning("Chat " + member + " existiert nicht mehr, wird gelöscht.") r.srem(key, member) r.delete(feed_hash.format(member)) except telegram.error.ChatMigrated as new_chat: new_chat_id = new_chat.new_chat_id - logger.info('Chat migriert: ' + member + ' -> ' + str(new_chat_id)) + logger.info("Chat migriert: " + member + " -> " + str(new_chat_id)) r.srem(key, member) r.sadd(key, new_chat_id) r.rename(feed_hash.format(member), feed_hash.format(new_chat_id)) @@ -334,7 +335,7 @@ def check_feed(bot, key): # Set the new last entry if there are any if new_entries: - if 'id' not in new_entries[0]: + if "id" not in new_entries[0]: new_last_entry = new_entries[0].link else: new_last_entry = new_entries[0].id @@ -343,8 +344,8 @@ def check_feed(bot, key): @run_async def run_job(bot, job=None): - logger.info('================================') - keys = r.keys(feed_hash.format('*:subs')) + logger.info("================================") + keys = r.keys(feed_hash.format("*:subs")) for key in keys: check_feed(bot, key) @@ -358,27 +359,25 @@ def main(): # Setup the updater and show bot info updater = Updater(token=bot_token) try: - bot_info = updater.bot.getMe() - except telegram.error.Unauthorized: - logger.error('Anmeldung nicht möglich, Bot-Token falsch?') + logger.info("Starte {0}, AKA @{1} ({2})".format(updater.bot.first_name, updater.bot.username, updater.bot.id)) + except Unauthorized: + logger.critical("Anmeldung nicht möglich, Bot-Token falsch?") sys.exit(1) - logger.info('Starte ' + bot_info.first_name + ', AKA @' + bot_info.username + ' (' + str(bot_info.id) + ')') - # Register Handlers handlers = [ - CommandHandler('start', start), - CommandHandler('help', help_text), - CommandHandler('rss', list_feeds, pass_args=True), - CommandHandler('sub', subscribe, pass_args=True), - CommandHandler('del', unsubscribe, pass_args=True), - CommandHandler('sync', run_job) + CommandHandler("start", start), + CommandHandler("help", help_text), + CommandHandler("rss", list_feeds, pass_args=True), + CommandHandler("sub", subscribe, pass_args=True), + CommandHandler("del", unsubscribe, pass_args=True), + CommandHandler("sync", run_job) ] for handler in handlers: updater.dispatcher.add_handler(handler) # Hide "Error while getting Updates" because it's not our fault - updater.logger.addFilter((lambda log: not log.msg.startswith('Error while getting Updates:'))) + updater.logger.addFilter((lambda log: not log.msg.startswith("Error while getting Updates:"))) # Fix for Python <= 3.5 updater.dispatcher.add_error_handler(onerror) @@ -401,5 +400,5 @@ def main(): updater.idle() -if __name__ == '__main__': +if __name__ == "__main__": main()