Пример #1
0
    def maildir_source(self):
        from mailbox import Maildir
        import codecs

        def get_encoding(enc, default='latin1'):
            """Return *enc* if *enc* is a valid encoding,
               *default* otherwise.
            """

            if not enc:
                return default
            try:
                codecs.lookup(enc)
                return enc
            except LookupError:
                return default

        m = Maildir(self._infile, create=False)
        if self._folder:
            m = m.get_folder(self._folder)

        for _, msg in m.iteritems():
            for part in self.get_plaintext_parts(msg):
                enc = get_encoding(part.get_content_charset())
                content_bytes = part.get_payload(decode=True)
                content = content_bytes.decode(encoding=enc, errors='ignore')
                yield from self.filter_text(content)
Пример #2
0
 def create(self, path, mails, compression='xz', server=None):
     path = Path.cwd() / path
     with TemporaryDirectory(prefix="mailarchive-") as tmpdir:
         with tmp_chdir(tmpdir), tmp_umask(0o077):
             basedir = Path(path.name.split('.')[0])
             maildir = Maildir(basedir, create=True)
             self.mailindex = MailIndex(server=server)
             last_folder = None
             for folder, msgbytes in mails:
                 if folder != last_folder:
                     mailfolder = maildir.add_folder(folder)
                     last_folder = folder
                 sha256 = hashlib.sha256(msgbytes).hexdigest()
                 key = mailfolder.add(msgbytes)
                 msg = mailfolder.get_message(key)
                 idx_item = {
                     "Date": msg.get("Date"),
                     "From": msg.get("From"),
                     "MessageId": msg.get("Message-Id"),
                     "Subject": msg.get("Subject"),
                     "To": msg.get("To"),
                     "checksum": {
                         "sha256": sha256
                     },
                     "folder": folder,
                     "key": key,
                 }
                 self.mailindex.append(idx_item)
             with TemporaryFile(dir=tmpdir) as tmpf:
                 self.mailindex.write(tmpf)
                 tmpf.seek(0)
                 self.add_metadata(".mailindex.yaml", tmpf)
                 super().create(path, compression, [basedir])
     return self
Пример #3
0
    def test_maildir(self):
        tmpdir = mkdtemp('archweb')
        mdir = tmpdir + '/maildir'

        maildir = Maildir(mdir)
        msg = Message()
        msg['subject'] = 'John Doe'
        msg['to'] = 'John Doe <*****@*****.**>'
        maildir.add(msg)

        # Invalid
        call_command('donor_import', mdir)
        self.assertEqual(len(Donor.objects.all()), 0)

        # Valid
        msg = Message()
        msg['subject'] = 'Receipt [$25.00] By: David Doe [[email protected]]'
        msg['to'] = 'John Doe <*****@*****.**>'
        maildir.add(msg)
        call_command('donor_import', mdir)
        self.assertEqual(len(Donor.objects.all()), 1)

        # Re-running should result in no new donor
        call_command('donor_import', mdir)
        self.assertEqual(len(Donor.objects.all()), 1)

        rmtree(tmpdir)
Пример #4
0
    def test_mailbox(self):
        with SMTP(*self.address) as client:
            client.sendmail(
                '*****@*****.**', ['*****@*****.**'], """\
From: Anne Person <*****@*****.**>
To: Bart Person <*****@*****.**>
Subject: A test
Message-ID: <ant>

Hi Bart, this is Anne.
""")
            client.sendmail(
                '*****@*****.**', ['*****@*****.**'], """\
From: Cate Person <*****@*****.**>
To: Dave Person <*****@*****.**>
Subject: A test
Message-ID: <bee>

Hi Dave, this is Cate.
""")
            client.sendmail(
                '*****@*****.**', ['*****@*****.**'], """\
From: Elle Person <*****@*****.**>
To: Fred Person <*****@*****.**>
Subject: A test
Message-ID: <cat>

Hi Fred, this is Elle.
""")
        # Check the messages in the mailbox.
        mailbox = Maildir(self.maildir_path)
        messages = sorted(mailbox, key=itemgetter('message-id'))
        self.assertEqual(
            list(message['message-id'] for message in messages),
            ['<ant>', '<bee>', '<cat>'])
Пример #5
0
  def cmd_dl(self, argv):
    ''' Collect messages from a POP3 server and deliver to a Maildir.

        Usage: {cmd} [{{ssl,tcp}}:]{{netrc_account|[user@]host[!sni_name][:port]}} maildir
    '''
    pop_target = argv.pop(0)
    maildir_path = argv.pop(0)
    assert len(argv) == 0
    if not isdirpath(maildir_path):
      raise ValueError("maildir %s: not a directory" % (maildir_path,))
    M = Maildir(maildir_path)
    with POP3(pop_target) as pop3:
      msg_uid_map = dict(pop3.client_uidl())
      print(
          f'{len(msg_uid_map)} message',
          ('' if len(msg_uid_map) == 1 else 's'),
          ('.' if len(msg_uid_map) == 0 else ':'),
          sep=''
      )
      with ResultSet() as deleRs:
        with ResultSet() as retrRs:
          for msg_n in msg_uid_map.keys():
            retrRs.add(pop3.dl_bg(msg_n, M, deleRs))
          pop3.flush()
          retrRs.wait()
        # now the deleRs are all queued
        pop3.flush()
        if deleRs:
          print("wait for DELEs...")
          deleRs.wait()
Пример #6
0
def enqueue_message(msg, queue_path, sender, recipients, return_msg=False, in_progress=False, **queue_args):
    msg_bytes = serialize_message_with_queue_data(msg, sender=sender, recipients=recipients, **queue_args)
    create_maildir_directories(queue_path)

    mailbox = Maildir(queue_path)
    sub_dir = 'cur' if in_progress else 'new'
    return inject_message_into_maildir(msg_bytes, mailbox, sub_dir=sub_dir, return_msg=return_msg)
Пример #7
0
def add_file(go, path):
    if not go:
        print(f"Would add {path}")
        return

    # Open the mailbox
    md = Maildir(DEST.joinpath(DEST_FOLDER), create=False)

    # Determine the UID for the next message
    uid_re = re.compile(",U=([0-9]+),")
    uid = 1 + max(
        chain([0],
              map(lambda key: int(uid_re.search(key).groups()[0]), md.keys())))

    print(f"Next UID: {uid}")

    # Determine the time when the message was originally delivered
    msg_bytes = path.read_bytes()
    msg = MaildirMessage(msg_bytes)
    msg_time = time.mktime(parsedate(msg["Date"]))

    # Create a Maildir filename in the format used by OfflineIMAP
    key = (f"{int(msg_time)}_0.{os.getpid()}.{socket.gethostname()},U={uid},"
           f"FMD5={md5(DEST_FOLDER.encode()).hexdigest()}:2,S")

    # Complete path
    dest = DEST.joinpath(DEST_FOLDER, "cur", key)
    assert not dest.exists() and dest.parent.exists()

    # Write the file
    print(f"Write {key}")
    dest.write_bytes(msg_bytes)

    # Update the utime
    os.utime(dest, (msg_time, msg_time))
def main() -> None:
    args = parse_args()
    global debug_enabled
    debug_enabled = args.debug
    mailbox = Maildir(
        dirname=args.maildir_path,
        factory=message_factory,
        create=False,
    )
    message_filter = MessageFilter.create(args)
    debug("filter: {}".format(message_filter))
    matches = 0
    for message in mailbox:
        debug(
            "message: {}".format((
                message.get("From"),
                message.get("Reply-To"),
                message.get("To"),
                message.get("Subject"),
            ), ), )
        if match(message, message_filter):
            matches += 1
            debug("matched: {}".format(matches))
    if args.count is None or args.count == matches:
        exit(0)
    exit(1)
Пример #9
0
async def run_tests():
    with tempfile.TemporaryDirectory() as maildir:
        # create temporary mailbox
        for d in ['cur', 'new', 'tmp']:
            maildirdir = os.path.join(maildir, d)
            os.mkdir(maildirdir)
        mailbox = Maildir(maildir)

        # start smtp server
        handler = MessageHandler(maildir)
        controller = Controller(handler)
        controller.start()

        # run tests
        tests = filter(
            lambda f: f.startswith('test_'),
            globals().keys(),
        )
        for test in tests:
            print(test + '...', end=' ')
            try:
                await globals()[test](mailbox)
            except AssertionError:
                fail()
                continue
            succeed()
Пример #10
0
def import_email(email, import_path, format, **kwargs):

    from caliopen.core.user import User
    from caliopen.core.contact import Contact, ContactLookup
    from caliopen.core.mail import MailMessage
    from caliopen.smtp.agent import DeliveryAgent

    AVATAR_DIR = '../../../caliopen.ng/src/assets/images/avatars'

    if format == 'maildir':
        emails = Maildir(import_path, factory=message_from_file)
        mode = 'maildir'
    else:
        if os.path.isdir(import_path):
            mode = 'mbox_directory'
            emails = {}
            files = [
                f for f in listdir(import_path)
                if os.path.isfile(os.path.join(import_path, f))
            ]
            for f in files:
                with open('%s/%s' % (import_path, f)) as fh:
                    emails[f] = message_from_file(fh)
        else:
            mode = 'mbox'
            emails = mbox(import_path)

    print email
    user = User.get(email)

    agent = DeliveryAgent()
    mailfrom = ''
    rcpts = [email]

    log.info("Processing mode %s" % mode)
    msgs = []
    for key, mail in emails.iteritems():
        # Create contact for user
        log.info('Processing mail %s' % key)
        msgs.append(MailMessage(mail))

    msgs = sorted(msgs, key=lambda msg: msg.date)

    for msg in msgs:
        for type, addresses in msg.recipients.iteritems():
            if not addresses:
                continue
            for alias, _address in addresses:
                lookup = ContactLookup.get(user, alias)
                if not lookup:
                    log.info('Creating contact %s' % alias)
                    infos = {'mail': alias}
                    name, domain = alias.split('@')

                    if os.path.isfile('%s/%s.png' % (AVATAR_DIR, name)):
                        infos.update({'avatar': '%s.png' % name})
                    Contact.create(user, infos)
        res = agent.process(mailfrom, rcpts, msg.mail.as_string())
        log.info('Process result %r' % res)
Пример #11
0
    def open(self, basedir=None):
        """Maildirの利用を開始する"""
        if not basedir: basedir = os.path.expanduser(user_mailbox)

        mdir = Maildir(basedir, None)
        self.mdir = mdir
        self.cur = ''
        self.fld = mdir
        self.basedir = basedir
Пример #12
0
    def send_email(self, message):
        """Sends an email directly (no queuing).

        No retries are done, the caller should handle MailDeliveryException in order to ensure that
        the mail is never lost.

        :param message: the email.message.Message to send. The envelope sender will be extracted from the
                        ``Return-Path`` or ``From`` headers. The envelope recipients will be
                        extracted from the combined list of ``To``, ``CC`` and ``BCC`` headers.
        :return: the Message-ID of the message that was just sent, if successfully sent, otherwise raises
                 MailDeliveryException and logs root cause.
        """
        smtp_from = message['Return-Path'] or message['From']
        assert smtp_from, "The Return-Path or From header is required for any outbound email"

        # The email's "Envelope From" (Return-Path), and all recipient addresses must only contain ASCII characters.
        from_rfc2822 = extract_rfc2822_addresses(smtp_from)
        assert len(
            from_rfc2822
        ) == 1, "Malformed 'Return-Path' or 'From' address - it may only contain plain ASCII characters"
        smtp_from = from_rfc2822[0]
        email_to = message['To']
        email_cc = message['Cc']
        email_bcc = message['Bcc']
        smtp_to_list = filter(
            None,
            flatten(
                map(extract_rfc2822_addresses,
                    [email_to, email_cc, email_bcc])))
        assert smtp_to_list, "At least one valid recipient address should be specified for outgoing emails (To/Cc/Bcc)"

        try:
            message_id = message['Message-Id']

            # Add email in Maildir if smtp_host contains maildir.
            if self.smtp_host.startswith('maildir:/'):
                from mailbox import Maildir
                maildir_path = self.smtp_host[8:]
                mdir = Maildir(maildir_path, factory=None, create=True)
                mdir.add(message.as_string(True))
                return message_id

            try:
                self.conn.sendmail(smtp_from, smtp_to_list,
                                   message.as_string())
            finally:
                try:
                    # Close Connection of SMTP Server
                    self.conn.quit()
                except Exception:
                    # ignored, just a consequence of the previous exception
                    pass
        except Exception, e:
            msg = "Mail delivery failed via SMTP server '%s'.\n%s: %s" % (
                unicode(self.smtp_host), e.__class__.__name__, unicode(e))
            raise ZatoException(self.cid, msg)
Пример #13
0
    def __init__(self, oldBoxDir, newBoxDir, daystoremove):
        from sys import stdout
        from mailbox import Maildir, MaildirMessage, NoSuchMailboxError
        from os.path import expanduser
        from time import time, strftime, gmtime

        self.logfile = strftime(
            expanduser("~/") + "mail-remove-log-%Y%m%d%H%M", gmtime())
        # DeltaT is epoch now - 60(s)*m*d*nm where n is number of months - here set for 4 months
        self.deltaT = int(round(time() - (60 * 60 * 24 * int(daystoremove))))
        self.newBox = Maildir(newBoxDir, create=True, factory=MaildirMessage)

        try:
            self.oldBox = Maildir(oldBoxDir,
                                  create=False,
                                  factory=MaildirMessage)
        except NoSuchMailboxError:
            print("[E] Invalid mail dir. Aborting")
            return (1)
Пример #14
0
    def __init__(self, mailDirPath: Path, mailBoxesPath: Path):
        super().__init__()
        self.clearMailDirPath = mailDirPath
        self.clearMailDirPath.mkdir(parents=True, exist_ok=True)
        self.clearMailDir = Maildir(str(self.clearMailDirPath))
        self.mailBoxesPath = mailBoxesPath
        self.mailBoxes = {}

        # Signals
        self.sNewMessage = AsyncSignal(str)
Пример #15
0
def _email_send(smtp_from, smtp_to_list, message, openobject_id=None, ssl=False, debug=False):
    """Low-level method to send directly a Message through the configured smtp server.
        :param smtp_from: RFC-822 envelope FROM (not displayed to recipient)
        :param smtp_to_list: RFC-822 envelope RCPT_TOs (not displayed to recipient)
        :param message: an email.message.Message to send
        :param debug: True if messages should be output to stderr before being sent,
                      and smtplib.SMTP put into debug mode.
        :return: True if the mail was delivered successfully to the smtp,
                 else False (+ exception logged)
    """
    if openobject_id:
        message['Message-Id'] = "<%s-openobject-%s@%s>" % (time.time(), openobject_id, socket.gethostname())

    try:
        smtp_server = config['smtp_server']

        if smtp_server.startswith('maildir:/'):
            from mailbox import Maildir
            maildir_path = smtp_server[8:]
            mdir = Maildir(maildir_path,factory=None, create = True)
            mdir.add(msg.as_string(True))
            return True

        oldstderr = smtplib.stderr
        if not ssl: ssl = config.get('smtp_ssl', False)
        s = smtplib.SMTP()
        try:
            # in case of debug, the messages are printed to stderr.
            if debug:
                smtplib.stderr = WriteToLogger()

            s.set_debuglevel(int(bool(debug)))  # 0 or 1
            s.connect(smtp_server, config['smtp_port'])
            if ssl:
                s.ehlo()
                s.starttls()
                s.ehlo()

            if config['smtp_user'] or config['smtp_password']:
                s.login(config['smtp_user'], config['smtp_password'])

            s.sendmail(smtp_from, smtp_to_list, message.as_string())
        finally:
            try:
                s.quit()
                if debug:
                    smtplib.stderr = oldstderr
            except:
                # ignored, just a consequence of the previous exception
                pass

    except Exception, e:
        _logger.error('could not deliver email', exc_info=True)
        return False
Пример #16
0
 def _maildir_delivery(self, username, domain, data):
     try:
         path = os.path.join(os.path.expanduser(MAILDIR_DELIVERY_USER),
                             domain, username)
         mdir = Maildir(path)
         mdirid = mdir.add(data)
         print "Maildir Delivered %s@%s %s/%s" % (username, domain, path,
                                                  mdirid)
     except:
         # XXX log errors with maildir but continue
         print "Maildir delivery error %s@%s " % (username, domain)
Пример #17
0
def main(args=sys.argv):
    parser = option_parser()
    opts, args = parser.parse_args(args)

    if len(args) > 1:
        if len(args) < 4:
            print ('You must specify the from address, to address and body text'
                    ' on the command line')
            return 1
        msg = compose_mail(args[1], args[2], args[3], subject=opts.subject,
                           attachment=opts.attachment)
        from_, to = args[1:3]
        eto = [extract_email_address(x.strip()) for x in to.split(',')]
        efrom = extract_email_address(from_)
    else:
        msg = sys.stdin.read()
        from email import message_from_string
        from email.utils import getaddresses
        eml = message_from_string(msg)
        tos = eml.get_all('to', [])
        ccs = eml.get_all('cc', []) + eml.get_all('bcc', [])
        all_tos = []
        for x in tos + ccs:
            all_tos.extend(y.strip() for y in x.split(','))
        eto = list(map(extract_email_address, all_tos))
        if not eto:
            raise ValueError('Email from STDIN does not specify any recipients')
        efrom = getaddresses(eml.get_all('from', []))
        if not efrom:
            raise ValueError('Email from STDIN does not specify a sender')
        efrom = efrom[0][1]

    outbox = None
    if opts.outbox is not None:
        outbox = os.path.abspath(os.path.expanduser(opts.outbox))
        from mailbox import Maildir
        outbox = Maildir(opts.outbox, factory=None)
    if opts.fork:
        if os.fork() != 0:
            return 0

    try:
        sendmail(msg, efrom, eto, localhost=opts.localhost, verbose=opts.verbose,
             timeout=opts.timeout, relay=opts.relay, username=opts.username,
             password=opts.password, port=opts.port,
             encryption=opts.encryption_method)
    except:
        if outbox is not None:
            outbox.add(msg)
            outbox.close()
            print 'Delivery failed. Message saved to', opts.outbox
        raise
    return 0
Пример #18
0
    def test_mailbox_reset(self):
        with SMTP(*self.address) as client:
            client.sendmail(
                '*****@*****.**', ['*****@*****.**'], """\
From: Anne Person <*****@*****.**>
To: Bart Person <*****@*****.**>
Subject: A test
Message-ID: <ant>

Hi Bart, this is Anne.
""")
        self.handler.reset()
        mailbox = Maildir(self.maildir_path)
        self.assertEqual(list(mailbox), [])
Пример #19
0
def _load_mails_as_is(mail_paths, store):
    deferreds = []

    for path in mail_paths:
        if isfile(path):
            mbox_mails = mbox(path, factory=None)
            yield add_mail_folder(store, mbox_mails, 'INBOX', deferreds)
        else:
            maildir = Maildir(path, factory=None)
            yield add_mail_folder(store, maildir, 'INBOX', deferreds)
            for mail_folder_name in maildir.list_folders():
                mail_folder = maildir.get_folder(mail_folder_name)
                yield add_mail_folder(store, mail_folder, mail_folder_name, deferreds)

    yield defer.gatherResults(deferreds, consumeErrors=True)
Пример #20
0
def duplicates_run(opts, maildir_paths):
    mails_by_hash = {}
    mail_count = 0

    check_maildirs_valid(maildir_paths)

    for maildir_path in maildir_paths:
        maildir = Maildir(maildir_path, factory=None)
        mail_count += collate_folder_by_hash(mails_by_hash, maildir,
                                             opts.message_id)

    duplicates, sizes_too_dissimilar, diff_too_big, removed, sets = \
        find_duplicates(mails_by_hash, opts)
    report_results(duplicates, sizes_too_dissimilar, diff_too_big, removed,
                   sets, mail_count)
Пример #21
0
    def archive_message(mlist, message):
        """See `IArchiver`.

        This archiver saves messages into a maildir.
        """
        archive_dir = os.path.join(config.ARCHIVE_DIR, 'prototype')
        try:
            os.makedirs(archive_dir, 0o775)
        except OSError as error:
            # If this already exists, then we're fine
            if error.errno != errno.EEXIST:
                raise

        # Maildir will throw an error if the directories are partially created
        # (for instance the toplevel exists but cur, new, or tmp do not)
        # therefore we don't create the toplevel as we did above.
        list_dir = os.path.join(archive_dir, mlist.fqdn_listname)
        mailbox = Maildir(list_dir, create=True, factory=None)
        lock_file = os.path.join(
            config.LOCK_DIR, '{0}-maildir.lock'.format(mlist.fqdn_listname))
        # Lock the maildir as Maildir.add() is not threadsafe.  Don't use the
        # context manager because it's not an error if we can't acquire the
        # archiver lock.  We'll just log the problem and continue.
        #
        # XXX 2012-03-14 BAW: When we extend the chain/pipeline architecture
        # to other runners, e.g. the archive runner, it would be better to let
        # any TimeOutError propagate up.  That would cause the message to be
        # re-queued and tried again later, rather than being discarded as
        # happens now below.
        lock = Lock(lock_file)
        try:
            lock.lock(timeout=timedelta(seconds=1))
            # Add the message to the maildir.  The return value could be used
            # to construct the file path if necessary.  E.g.
            #
            # os.path.join(archive_dir, mlist.fqdn_listname, 'new',
            #              message_key)
            mailbox.add(message)
        except TimeOutError:
            # Log the error and go on.
            log.error('Unable to acquire prototype archiver lock for {0}, '
                      'discarding: {1}'.format(
                          mlist.fqdn_listname,
                          message.get('message-id', 'n/a')))
        finally:
            lock.unlock(unconditionally=True)
        # Can we get return the URL of the archived message?
        return None
Пример #22
0
def load_mails(args, mail_paths):
    leap_session, soledad = args
    account = leap_session.account

    deferreds = []

    for path in mail_paths:
        maildir = Maildir(path, factory=None)
        add_mail_folder(account, maildir, 'INBOX', deferreds)
        add_mail_folder(account, maildir, 'DRAFTS', deferreds)
        for mail_folder_name in maildir.list_folders():
            mail_folder = maildir.get_folder(mail_folder_name)
            add_mail_folder(account, mail_folder, mail_folder_name, deferreds)

    yield defer.DeferredList(deferreds)
    defer.returnValue(args)
Пример #23
0
 def test_mailbox_reset(self, temp_maildir, mailbox_controller, client):
     client.sendmail(
         "*****@*****.**",
         ["*****@*****.**"],
         dedent("""\
             From: Anne Person <*****@*****.**>
             To: Bart Person <*****@*****.**>
             Subject: A test
             Message-ID: <ant>
 
             Hi Bart, this is Anne.
             """),
     )
     mailbox_controller.handler.reset()
     mailbox = Maildir(temp_maildir)
     assert list(mailbox) == []
Пример #24
0
def load_mails(args, mail_paths):
    leap_session, soledad = args
    store = leap_session.mail_store

    deferreds = []

    for path in mail_paths:
        maildir = Maildir(path, factory=None)
        yield add_mail_folder(store, maildir, 'INBOX', deferreds)
        for mail_folder_name in maildir.list_folders():
            mail_folder = maildir.get_folder(mail_folder_name)
            yield add_mail_folder(store, mail_folder, mail_folder_name,
                                  deferreds)

    yield defer.gatherResults(deferreds, consumeErrors=True)

    defer.returnValue(args)
Пример #25
0
 def delete(self, address, maildir=False):
     if not maildir:
         a = address.lower()
         if self.db.has_key(a):
             del self.db[a]
         else:
             print "Warning: %s is not in database" % a
     else:
         maildir = Maildir(address)
         for msg in maildir:
             mfrom, retpa, cc, to = self.msg_addrs(msg)
             if not retpa: continue
             for address in retpa:
                 address = address.lower()
                 if self.db.has_key(address):
                     print "deleting: <%s>" % address
                     del (self.db[address])
Пример #26
0
 def test_mailbox(self, temp_maildir, mailbox_controller, client):
     client.sendmail(
         "*****@*****.**",
         ["*****@*****.**"],
         dedent("""\
             From: Anne Person <*****@*****.**>
             To: Bart Person <*****@*****.**>
             Subject: A test
             Message-ID: <ant>
 
             Hi Bart, this is Anne.
             """),
     )
     client.sendmail(
         "*****@*****.**",
         ["*****@*****.**"],
         dedent("""\
             From: Cate Person <*****@*****.**>
             To: Dave Person <*****@*****.**>
             Subject: A test
             Message-ID: <bee>
 
             Hi Dave, this is Cate.
             """),
     )
     client.sendmail(
         "*****@*****.**",
         ["*****@*****.**"],
         dedent("""\
             From: Elle Person <*****@*****.**>
             To: Fred Person <*****@*****.**>
             Subject: A test
             Message-ID: <cat>
 
             Hi Fred, this is Elle.
             """),
     )
     # Check the messages in the mailbox.
     mailbox = Maildir(temp_maildir)
     messages = sorted(mailbox, key=itemgetter("message-id"))
     assert list(message["message-id"] for message in messages) == [
         "<ant>",
         "<bee>",
         "<cat>",
     ]
Пример #27
0
def main(smtp_host, smtp_port, web_host, web_port, develop, debug, maildir):
    if debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    logger.info("SMTP server is running on %s:%s", smtp_host, smtp_port)
    logger.info("Web server is running on %s:%s", web_host, web_port)

    if develop:
        logger.info("Running in developer mode")

    dir_context = TemporaryDirectory if maildir is None else lambda: nullcontext(
        maildir)

    with dir_context() as maildir_path:
        maildir_path = pathlib.Path(maildir_path)
        maildir_path.mkdir(parents=True, exist_ok=True)

        logger.info("Mail directory: %s", maildir_path)

        config = Configuration(
            smtp_host=smtp_host,
            smtp_port=smtp_port,
            web_host=web_host,
            web_port=web_port,
            develop=develop,
            debug=debug,
        )

        maildir = Maildir(maildir_path / "maildir")
        mailbox = MailboxHandler(maildir_path / "maildir")

        controller = Controller(mailbox,
                                hostname=config.smtp_host,
                                port=config.smtp_port)
        web_server = WebServer(config, maildir)
        mailbox.register_message_observer(web_server)

        controller.start()
        web_server.start()
        controller.stop()
Пример #28
0
 def populateMailbox(self, username):
     # Here will the mail directory of the user be stored
     pathShort = "/var/vmail/" + self.domain + "/" + username
     pathLong = pathShort + "/Maildir"
     # Create those directories
     os.mkdir(pathShort)
     mailbox = Maildir(pathLong)
     # And now populate that directory
     numOfMails = random.randint(1, 6666)
     percentageRead = random.randint(0, 100)
     for i in xrange(1, numOfMails):
         message = MaildirMessage(message=str(i))
         message.set_subdir("cur")
         readSeed = random.randint(0, 100)
         if percentageRead <= readSeed:
             message.set_flags("S")
         mailbox.add(message)
     self.chmodMailbox(pathShort)
     
     
Пример #29
0
 def update(self, maildir, allcc=False, fromaddr=None):
     """updates Database
     allcc: add all from: and cc: addresses from all mails
     fromaddr: if set, add cc: only from this sender"""
     maildir = Maildir(maildir)
     if fromaddr: fromaddr = fromaddr.lower()
     for msg in maildir:
         mfrom, retpa, cc, to = self.msg_addrs(msg)
         # mfrom header is set and it is identical to the give address
         if allcc or (mfrom and fromaddr and mfrom[0] == fromaddr):
             self._updatel(mfrom)
             self._updatel(retpa)
             self._updatel(to)
             self._updatel(cc)
         # add from: and return-path: in any case
         elif mfrom or retpa:
             self._updatel(mfrom)
             self._updatel(retpa)
         else:
             pass
Пример #30
0
    async def handle_DATA(self, server, session, envelope):
        d = Maildir(MAILDIR_PATH)
        message = email.message_from_bytes(envelope.original_content)
        for r in envelope.rcpt_tos:
            message['X-Rcpt-To'] = r
        d.add(message)

        try:
            conn = smtplib.SMTP(RELAY_HOST, RELAY_PORT)
            conn.ehlo()
            conn.starttls()
            conn.login(RELAY_USER, RELAY_PASS)
            refused = conn.sendmail(envelope.mail_from, envelope.rcpt_tos,
                                    envelope.original_content)
            if refused:
                print(refused, flush=True)
            print("To: %r" % (envelope.rcpt_tos, ), flush=True)
            return '250 OK'
        except smtplib.SMTPException as exn:
            traceback.print_exc()
            return '550 SMTPException: %s' % exn