diff --git a/config.toml.example b/config.toml.example index 6257146..ab040ce 100644 --- a/config.toml.example +++ b/config.toml.example @@ -10,14 +10,14 @@ server = 'yourmastodoninstance' # Instance where you have your Mastodon account [tapp] # You get those keys when you follow these steps: # https://developer.twitter.com/en/docs/basics/authentication/guides/access-tokens -consumer_key = "OD0CLn6twBxHjN2DqMkKuSvli" -consumer_secret = "XkvbViwjBWoWoJzIlseJLXmg2fqluq4HYqvwOwoSHGwxdTNi4l" +consumer_key = "your_consumer_key" +consumer_secret = "your_consumer_secret" [tuser] # You get those keys when you follow these steps: # https://developer.twitter.com/en/docs/basics/authentication/guides/access-tokens -access_token_key = "876046057721008128-J35moxFXUvLb24MnaMVbVpqiEtxBlcc" -access_token_secret = "I7PQZMHuJDS5WslgUhqEeZbEWGhwLhmOetvwFoTn8YDKW" +access_token_key = "your_access_token_key" +access_token_secret = "your_acces_token_secret" [mail] # This is the mail the bot uses to send emails. diff --git a/logger.py b/logger.py deleted file mode 100644 index 29c4a00..0000000 --- a/logger.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 - -import os -import datetime -import traceback -import sys -import sendmail - - -class Logger(object): - """ - builds log files, writes the log messages. - If a critical error occurs, handles the bugtracking and error - messages. - """ - - def __init__(self, config): - """ - logs everything & sends bugtracking messages. - - :param config: config file - """ - self.config = config - - # initialize logging - if config["logging"]["logpath"]: - self.logpath = os.path.join(self.config["logging"]["logpath"], str(datetime.datetime.now())) - else: - self.logpath = os.path.join("logs", str(datetime.datetime.now())) - print("Path of logfile: " + self.logpath) - - # intialize shutdown contact - try: - self.no_shutdown_contact = False - self.contact = self.config['mail']['contact'] - except KeyError: - self.no_shutdown_contact = True - - def log(self, message): - """ - Writing an error message & sometimes a traceback to a logfile in logs/ - and prints it. - - :param message: (string) Logger message to be displayed - """ - time = str(datetime.datetime.now()) - line = "[" + time + "] " + message + "\n" - with open(self.logpath, 'a') as f: - try: - f.write(line) - except UnicodeEncodeError: - message = "Failed to save log message due to UTF-8 error. " - message = message + self.generate_tb(sys.exc_info()) - self.log(message) - print(line, end="") - - def generate_tb(self, exc): - tb = traceback.extract_tb(exc[2]) # returns StackSummary object - tb = "\n".join(tb.format()) # string of the actual traceback - message = ("Traceback (most recent call last):\n", - tb, - exc[0].__name__) # the type of the Exception - message = "".join(message) # concatenate to full traceback message - return message - - def shutdown(self, tb): - """ If something breaks, it shuts down the bot and messages the owner. - - :param tb: (string) traceback - """ - logmessage = "Shit went wrong, closing down.\n" + tb + "\n\n" - if self.no_shutdown_contact: - self.log(logmessage) - return - logmessage = logmessage + "Sending message to " + self.contact - self.log(logmessage) - try: - mailer = sendmail.Mailer(self.config) - mailer.send(tb, self.contact, "Ticketfrei Crash Report", attachment=self.logpath) - except: - self.log("Error while shutdown: " + self.generate_tb(sys.exc_info())) - print() diff --git a/mailbot.py b/mailbot.py index ec440ec..b53cf14 100644 --- a/mailbot.py +++ b/mailbot.py @@ -6,10 +6,11 @@ import time import trigger import datetime import email -import logger +import logging import pytoml as toml import imaplib -import sys + +logger = logging.getLogger(__name__) class Mailbot(object): @@ -18,7 +19,7 @@ class Mailbot(object): other bots that it received mails. """ - def __init__(self, config, trigger, logger, history_path="last_mail"): + def __init__(self, config, trigger, history_path="last_mail"): """ Creates a Bot who listens to mails and forwards them to other bots. @@ -27,7 +28,6 @@ class Mailbot(object): """ self.config = config self.trigger = trigger - self.logger = logger self.history_path = history_path self.last_mail = self.get_history(self.history_path) @@ -42,15 +42,18 @@ class Mailbot(object): try: self.mailbox.starttls(ssl_context=context) except: - logmsg = logger.generate_tb(sys.exc_info()) - logger.log(logmsg) + logger.error('StartTLS failed', exc_info=True) try: self.mailbox.login(self.config["mail"]["user"], self.config["mail"]["passphrase"]) except imaplib.IMAP4.error: - logmsg = "Login to mail server failed." - logmsg = logmsg + logger.generate_tb(sys.exc_info()) - logger.log(logmsg) - logger.shutdown(logmsg) + logger.error("Login to mail server failed", exc_info=True) + try: + mailer = sendmail.Mailer(config) + mailer.send('', config['mail']['contact'], + 'Ticketfrei Crash Report', + attachment=config['logging']['logpath']) + except: + logger.error('Mail sending failed', exc_info=True) def listen(self): """ @@ -67,8 +70,7 @@ class Mailbot(object): for num in data[0].split(): rv, data = self.mailbox.fetch(num, '(RFC822)') if rv != 'OK': - logmsg = "Didn't receive mail. Error: " + rv + str(data) - self.logger.log(logmsg) + logger.error("Couldn't fetch mail %s %s" % (rv, str(data))) return msgs msg = email.message_from_bytes(data[0][1]) @@ -157,10 +159,12 @@ if __name__ == "__main__": with open('config.toml') as configfile: config = toml.load(configfile) - logger = logger.Logger(config) - trigger = trigger.Trigger(config) + fh = logging.FileHandler(config['logging']['logpath']) + fh.setLevel(logging.DEBUG) + logger.addHandler(fh) - m = Mailbot(config, trigger, logger) + trigger = trigger.Trigger(config) + m = Mailbot(config, trigger) statuses = [] try: while 1: @@ -169,8 +173,12 @@ if __name__ == "__main__": except KeyboardInterrupt: print("Good bye. Remember to restart the bot!") except: - exc = sys.exc_info() # returns tuple [Exception type, Exception object, Traceback object] - message = logger.generate_tb(exc) - m.logger.log(message) + logger.error('Shutdown', exc_info=True) m.save_last_mail() - m.logger.shutdown(message) + try: + mailer = sendmail.Mailer(config) + mailer.send('', config['mail']['contact'], + 'Ticketfrei Crash Report', + attachment=config['logging']['logpath']) + except: + logger.error('Mail sending failed', exc_info=True) diff --git a/retootbot.py b/retootbot.py index bfd2e1e..be15756 100755 --- a/retootbot.py +++ b/retootbot.py @@ -7,12 +7,14 @@ import pickle import re import time import trigger -import logger -import sys +import logging +import sendmail + +logger = logging.getLogger(__name__) class RetootBot(object): - def __init__(self, config, trigger, logger): + def __init__(self, config, trigger): self.config = config self.trigger = trigger self.client_id = self.register() @@ -25,8 +27,6 @@ class RetootBot(object): except IOError: self.seen_toots = set() - self.logger = logger - def register(self): client_id = os.path.join( 'appkeys', @@ -68,8 +68,7 @@ class RetootBot(object): notification['status']['content']) if not self.trigger.is_ok(text_content): continue - self.logger.log('Boosting toot from %s: %s' % ( - # notification['status']['id'], + logger.info('Boosting toot from %s: %s' % ( notification['status']['account']['acct'], notification['status']['content'])) self.m.status_reblog(notification['status']['id']) @@ -92,10 +91,12 @@ if __name__ == '__main__': with open('config.toml') as configfile: config = toml.load(configfile) - trigger = trigger.Trigger(config) - logger = logger.Logger(config) + fh = logging.FileHandler(config['logging']['logpath']) + fh.setLevel(logging.DEBUG) + logger.addHandler(fh) - bot = RetootBot(config, trigger, logger) + trigger = trigger.Trigger(config) + bot = RetootBot(config, trigger) try: while True: @@ -104,7 +105,11 @@ if __name__ == '__main__': except KeyboardInterrupt: print("Good bye. Remember to restart the bot!") except: - exc = sys.exc_info() # returns tuple [Exception type, Exception object, Traceback object] - message = logger.generate_tb(exc) - bot.logger.log(message) - bot.logger.shutdown(message) + logger.error('Shutdown', exc_info=True) + try: + mailer = sendmail.Mailer(config) + mailer.send('', config['mail']['contact'], + 'Ticketfrei Crash Report', + attachment=config['logging']['logpath']) + except: + logger.error('Mail sending failed', exc_info=True) diff --git a/retweetbot.py b/retweetbot.py index 92861c8..84f3b56 100755 --- a/retweetbot.py +++ b/retweetbot.py @@ -1,12 +1,14 @@ #!/usr/bin/env python3 import tweepy -import sys import requests import pytoml as toml import trigger from time import sleep -import logger +import logging +import sendmail + +logger = logging.getLogger(__name__) class RetweetBot(object): @@ -22,7 +24,7 @@ class RetweetBot(object): last_mention: the ID of the last tweet which mentioned you """ - def __init__(self, trigger, config, logger, history_path="last_mention"): + def __init__(self, trigger, config, history_path="last_mention"): """ Initializes the bot and loads all the necessary data. @@ -47,8 +49,6 @@ class RetweetBot(object): self.trigger = trigger self.waitcounter = 0 - self.logger = logger - def get_api_keys(self): """ How to get these keys is described in doc/twitter_api.md @@ -127,14 +127,10 @@ class RetweetBot(object): mentions = self.api.mentions_timeline(since_id=self.last_mention) return mentions except tweepy.RateLimitError: - logmsg = "Twitter API Error: Rate Limit Exceeded." - logmsg = logmsg + self.logger.generate_tb(sys.exc_info()) - self.logger.log(logmsg) + logger.error("Twitter API Error: Rate Limit Exceeded", exc_info=True) self.waitcounter += 60*15 + 1 except requests.exceptions.ConnectionError: - logmsg = "Twitter API Error: Bad Connection." - logmsg = logmsg + self.logger.generate_tb(sys.exc_info()) - self.logger.log(logmsg) + logger.error("Twitter API Error: Bad Connection", exc_info=True) self.waitcounter += 10 return [] @@ -148,21 +144,16 @@ class RetweetBot(object): while 1: try: self.api.retweet(status.id) - self.logger.log("Retweeted: " + self.format_mastodon(status)) + logger.info("Retweeted: " + self.format_mastodon(status)) if status.id > self.last_mention: self.last_mention = status.id return self.format_mastodon(status) except requests.exceptions.ConnectionError: - logmsg = "Twitter API Error: Bad Connection." - logmsg = logmsg + self.logger.generate_tb(sys.exc_info()) - self.logger.log(logmsg) + logger.error("Twitter API Error: Bad Connection", exc_info=True) sleep(10) # maybe one day we get rid of this error: except tweepy.TweepError: - logmsg = "Twitter Error." - logmsg = logmsg + self.logger.generate_tb(sys.exc_info()) - self.logger.log(logmsg) - # self.log.log("Twitter API Error: You probably already retweeted this tweet: " + status.text) + logger.error("Twitter Error", exc_info=True) if status.id > self.last_mention: self.last_mention = status.id return None @@ -180,9 +171,7 @@ class RetweetBot(object): self.api.update_status(status=post) return except requests.exceptions.ConnectionError: - logmsg = "Twitter API Error: Bad Connection." - logmsg = logmsg + self.logger.generate_tb(sys.exc_info()) - self.logger.log(logmsg) + logger.error("Twitter API Error: Bad Connection", exc_info=True) sleep(10) def flow(self, to_tweet=()): @@ -221,10 +210,12 @@ if __name__ == "__main__": with open('config.toml') as configfile: config = toml.load(configfile) - trigger = trigger.Trigger(config) - logger = logger.Logger(config) + fh = logging.FileHandler(config['logging']['logpath']) + fh.setLevel(logging.DEBUG) + logger.addHandler(fh) - bot = RetweetBot(trigger, config, logger) + trigger = trigger.Trigger(config) + bot = RetweetBot(trigger, config) try: while True: bot.flow() @@ -232,8 +223,12 @@ if __name__ == "__main__": except KeyboardInterrupt: print("Good bye. Remember to restart the bot!") except: - exc = sys.exc_info() # returns tuple [Exception type, Exception object, Traceback object] - message = logger.generate_tb(exc) - bot.logger.log(message) + logger.error('Shutdown', exc_info=True) bot.save_last_mention() - bot.logger.shutdown(message) + try: + mailer = sendmail.Mailer(config) + mailer.send('', config['mail']['contact'], + 'Ticketfrei Crash Report', + attachment=config['logging']['logpath']) + except: + logger.error('Mail sending failed', exc_info=True) diff --git a/ticketfrei.py b/ticketfrei.py index 9dc23f7..a796689 100755 --- a/ticketfrei.py +++ b/ticketfrei.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 +import logging import pytoml as toml -import logger import time -import sys +import sendmail from retootbot import RetootBot from retweetbot import RetweetBot @@ -15,12 +15,14 @@ if __name__ == '__main__': with open('config.toml') as configfile: config = toml.load(configfile) + logger = logging.getLogger() + fh = logging.FileHandler(config['logging']['logpath']) + fh.setLevel(logging.DEBUG) + logger.addHandler(fh) + trigger = Trigger(config) - - logger = logger.Logger(config) - - mbot = RetootBot(config, trigger, logger) - tbot = RetweetBot(trigger, config, logger) + mbot = RetootBot(config, trigger) + tbot = RetweetBot(trigger, config) try: statuses = [] @@ -31,8 +33,12 @@ if __name__ == '__main__': except KeyboardInterrupt: print("Good bye. Remember to restart the bot!") except: - exc = sys.exc_info() # returns tuple [Exception type, Exception object, Traceback object] - message = logger.generate_tb(exc) - tbot.logger.log(message) + logger.error('Shutdown', exc_info=True) tbot.save_last_mention() - tbot.logger.shutdown(message) + try: + mailer = sendmail.Mailer(config) + mailer.send('', config['mail']['contact'], + 'Ticketfrei Crash Report', + attachment=config['logging']['logpath']) + except: + logger.error('Mail sending failed', exc_info=True)