reworked mailbot to implement bot.py

This commit is contained in:
b3yond 2018-03-29 01:50:05 +02:00
parent c9fd91de74
commit 29c35be8a5

View file

@ -8,7 +8,6 @@ import datetime
import email import email
import imaplib import imaplib
import report import report
from user import User
from bot import Bot from bot import Bot
@ -21,25 +20,17 @@ class Mailbot(Bot):
other bots that it received mails. other bots that it received mails.
""" """
def __init__(self, uid): def login(self, user):
""" # change to use mailbox of local system
Creates a Bot who listens to mails and forwards them to other mailinglist = user.get_mailinglist()
bots. mailbox = imaplib.IMAP4_SSL(mailinglist)
"""
try:
self.mailinglist = self.user.get_mailinglist()
except TypeError:
self.mailinglist = None
self.mailbox = imaplib.IMAP4_SSL(config["mail"]["imapserver"])
context = ssl.create_default_context() context = ssl.create_default_context()
try: try:
self.mailbox.starttls(ssl_context=context) mailbox.starttls(ssl_context=context)
except: except:
logger.error('StartTLS failed', exc_info=True) logger.error('StartTLS failed', exc_info=True)
try: try:
self.mailbox.login(config["mail"]["user"], mailbox.login(config["mail"]["user"],
config["mail"]["passphrase"]) config["mail"]["passphrase"])
except imaplib.IMAP4.error: except imaplib.IMAP4.error:
logger.error("Login to mail server failed", exc_info=True) logger.error("Login to mail server failed", exc_info=True)
@ -51,41 +42,32 @@ class Mailbot(Bot):
except: except:
logger.error('Mail sending failed', exc_info=True) 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): def crawl(self, user):
""" """
crawl for new mails. crawl for new mails.
:return: msgs: (list of report.Report objects) :return: msgs: (list of report.Report objects)
""" """
mailinglist = user.get_mailinglist() mailbox = self.login(user)
try: try:
rv, data = self.mailbox.select("Inbox") rv, data = mailbox.select("Inbox")
except imaplib.IMAP4.abort: except imaplib.IMAP4.abort:
logger.error("Crawling Mail failed", exc_info=True) logger.error("Crawling Mail failed", exc_info=True)
rv = False rv = False
msgs = [] msgs = []
if rv == 'OK': if rv == 'OK':
rv, data = self.mailbox.search(None, "ALL") rv, data = mailbox.search(None, "ALL")
if rv != 'OK': if rv != 'OK':
return msgs return msgs
for num in data[0].split(): for num in data[0].split():
rv, data = self.mailbox.fetch(num, '(RFC822)') rv, data = mailbox.fetch(num, '(RFC822)')
if rv != 'OK': if rv != 'OK':
logger.error("Couldn't fetch mail %s %s" % (rv, str(data))) logger.error("Couldn't fetch mail %s %s" % (rv, str(data)))
return msgs return msgs
msg = email.message_from_bytes(data[0][1]) 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 # get a comparable date out of the email
date_tuple = email.utils.parsedate_tz(msg['Date']) date_tuple = email.utils.parsedate_tz(msg['Date'])
date_tuple = datetime.datetime.fromtimestamp( date_tuple = datetime.datetime.fromtimestamp(
@ -93,24 +75,20 @@ class Mailbot(Bot):
) )
date = int((date_tuple - date = int((date_tuple -
datetime.datetime(1970, 1, 1)).total_seconds()) datetime.datetime(1970, 1, 1)).total_seconds())
if date > self.user.get_seen_mail(): if date > user.get_seen_mail():
self.last_mail = date
self.save_last()
msgs.append(self.make_report(msg)) msgs.append(self.make_report(msg))
return msgs return msgs
def save_last(self): def post(self, user, report):
""" Saves the last retweeted tweet in the db. """
self.user.save_seen_mail(self.last_mail)
def post(self, status):
""" """
sends reports by other sources to a mailing list. sends reports by other sources to a mailing list.
:param status: (report.Report object) :param report: (report.Report object)
""" """
mailinglist = self.login(user)
if report.source is not self:
mailer = sendmail.Mailer() mailer = sendmail.Mailer()
mailer.send(status.format(), self.mailinglist, mailer.send(report.text, mailinglist,
"Warnung: Kontrolleure gesehen") "Warnung: Kontrolleure gesehen")
def make_report(self, msg): def make_report(self, msg):
@ -133,23 +111,4 @@ class Mailbot(Bot):
text = msg.get_payload() text = msg.get_payload()
post = report.Report(author, "mail", text, None, date) post = report.Report(author, "mail", text, None, date)
self.last_mail = date self.last_mail = date
self.save_last()
return post 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