Source code for hauberk.core
# -*- coding: utf-8 -*-
"""Main module."""
import logging
from collections import namedtuple
from imapclient import IMAPClient
from hauberk.flags import FetchFlags
logger = logging.getLogger(__name__)
Rule = namedtuple('Rule', ['filters', 'actions'])
[docs]class Message():
def __init__(self, envelope, body):
self.envelope = envelope
self.body = body
self.date = envelope.date
self.subject = envelope.subject
self.from_ = envelope.from_
self.sender = envelope.sender
self.reply_to = envelope.reply_to
self.to = envelope.to
self.cc = envelope.cc
self.bcc = envelope.bcc
self.in_reply_to = envelope.in_reply_to
self.message_id = envelope.message_id
[docs]class Hauberk():
def __init__(self, dry_run=False):
self.rules = list()
self.dry = dry_run
[docs] def login(self, username, password, server):
logger.info("Connecting to Server")
self.client = IMAPClient(server, use_uid=True)
self.client.login(username, password)
logger.info("Connected")
[docs] def add_rule(self, filters, actions):
self.rules.append(Rule(filters=filters, actions=actions))
if not filters:
raise Exception("Must define filters in rule")
if not actions:
raise Exception("Must define actions in rule")
logger.info("Added rule number %s", len(self.rules))
[docs] def run(self):
messages = self.client.search()
logger.info("%s messages to process", len(messages))
for msgid, data in self.client.fetch(messages, [FetchFlags.ENVELOPE.value,
FetchFlags.BODY.value]).items():
envelope = data[FetchFlags.ENVELOPE.value]
body = data[FetchFlags.BODY.value]
message = Message(envelope, body)
logger.debug("Processing message %s: %s", msgid, message.subject)
done = False
for rule in self.rules:
for _filter in rule.filters:
logger.debug("Running filter %s", _filter)
if _filter(message):
logger.debug("Match found!")
# log here that there was a match
for action in rule.actions:
logger.debug("Running action %s", action)
action(self.client, msgid, self.dry)
done = True
break
if done:
break
[docs] def select_folder(self, folder):
"""Select working folder.
:param folder: Folder rules should be applied to
"""
logger.info("Running in folder %s", folder)
self.client.select_folder(folder)
[docs] def existing_folders(self, folders):
"""Make sure certain folders exist client side.
:param folders: List of folder names
"""
logger.info("Checking for existing folders")
if not isinstance(folders, list):
folders = [folders]
for folder in folders:
logger.debug("Checking for existance of folder %s" % folder)
if not self.client.folder_exists(folder):
logger.warning("Folder %s does not exist, creating" % folder)
if not self.dry:
self.client.create_folder(folder)