From 29c35be8a5a77fd0040fa6e4ebcf68c1a03747d9 Mon Sep 17 00:00:00 2001 From: b3yond Date: Thu, 29 Mar 2018 01:50:05 +0200 Subject: [PATCH] reworked mailbot to implement bot.py --- active_bots/mailbot.py | 81 +++++++++++------------------------------- 1 file changed, 20 insertions(+), 61 deletions(-) diff --git a/active_bots/mailbot.py b/active_bots/mailbot.py index b5a57ed..995b390 100644 --- a/active_bots/mailbot.py +++ b/active_bots/mailbot.py @@ -8,7 +8,6 @@ import datetime import email import imaplib import report -from user import User from bot import Bot @@ -21,25 +20,17 @@ class Mailbot(Bot): other bots that it received mails. """ - def __init__(self, uid): - """ - Creates a Bot who listens to mails and forwards them to other - bots. - - """ - try: - self.mailinglist = self.user.get_mailinglist() - except TypeError: - self.mailinglist = None - - self.mailbox = imaplib.IMAP4_SSL(config["mail"]["imapserver"]) + def login(self, user): + # change to use mailbox of local system + mailinglist = user.get_mailinglist() + mailbox = imaplib.IMAP4_SSL(mailinglist) context = ssl.create_default_context() try: - self.mailbox.starttls(ssl_context=context) + mailbox.starttls(ssl_context=context) except: logger.error('StartTLS failed', exc_info=True) try: - self.mailbox.login(config["mail"]["user"], + mailbox.login(config["mail"]["user"], config["mail"]["passphrase"]) except imaplib.IMAP4.error: logger.error("Login to mail server failed", exc_info=True) @@ -51,41 +42,32 @@ class Mailbot(Bot): except: logger.error('Mail sending failed', exc_info=True) - def repost(self, status): - """ - E-Mails don't have to be reposted - they already reached everyone on the mailing list. - The function still needs to be here because backend.py assumes it, and take the - report object they want to give us. - - :param status: (report.Report object) - """ - pass - def crawl(self, user): """ crawl for new mails. :return: msgs: (list of report.Report objects) """ - mailinglist = user.get_mailinglist() + mailbox = self.login(user) try: - rv, data = self.mailbox.select("Inbox") + rv, data = mailbox.select("Inbox") except imaplib.IMAP4.abort: logger.error("Crawling Mail failed", exc_info=True) rv = False msgs = [] if rv == 'OK': - rv, data = self.mailbox.search(None, "ALL") + rv, data = mailbox.search(None, "ALL") if rv != 'OK': return msgs for num in data[0].split(): - rv, data = self.mailbox.fetch(num, '(RFC822)') + rv, data = mailbox.fetch(num, '(RFC822)') if rv != 'OK': logger.error("Couldn't fetch mail %s %s" % (rv, str(data))) return msgs msg = email.message_from_bytes(data[0][1]) - if not self.user.get_mailinglist() in msg['From']: + # check if email was sent by the bot itself. Different solution? + if not user.get_mailinglist() in msg['From']: # get a comparable date out of the email date_tuple = email.utils.parsedate_tz(msg['Date']) date_tuple = datetime.datetime.fromtimestamp( @@ -93,25 +75,21 @@ class Mailbot(Bot): ) date = int((date_tuple - datetime.datetime(1970, 1, 1)).total_seconds()) - if date > self.user.get_seen_mail(): - self.last_mail = date - self.save_last() + if date > user.get_seen_mail(): msgs.append(self.make_report(msg)) return msgs - def save_last(self): - """ Saves the last retweeted tweet in the db. """ - self.user.save_seen_mail(self.last_mail) - - def post(self, status): + def post(self, user, report): """ sends reports by other sources to a mailing list. - :param status: (report.Report object) + :param report: (report.Report object) """ - mailer = sendmail.Mailer() - mailer.send(status.format(), self.mailinglist, - "Warnung: Kontrolleure gesehen") + mailinglist = self.login(user) + if report.source is not self: + mailer = sendmail.Mailer() + mailer.send(report.text, mailinglist, + "Warnung: Kontrolleure gesehen") def make_report(self, msg): """ @@ -133,23 +111,4 @@ class Mailbot(Bot): text = msg.get_payload() post = report.Report(author, "mail", text, None, date) self.last_mail = date - self.save_last() return post - - def flow(self, trigger, statuses): - """ - to be iterated. uses trigger to separate the sheep from the goats - - :param statuses: (list of report.Report objects) - :return: statuses: (list of report.Report objects) - """ - for status in statuses: - self.post(status) - - msgs = self.crawl() - - statuses = [] - for msg in msgs: - if trigger.is_ok(msg.get_payload()): - statuses.append(msg) - return statuses