Exemplo n.º 1
0
 def get_message(self, key):
     """Return a Message representation or raise a KeyError."""
     with self._get_fd(key) as fd:
         if self._factory:
             return self._factory(fd)
         else:
             return mailbox.MaildirMessage(fd)
Exemplo n.º 2
0
 def store(self, message, folder):
     box = self.__mailbox(folder)
     msg = mailbox.MaildirMessage(message)
     key = box.add(msg)
     self.index[self.digest(message)] = folder + "/" + key
     self.log(INFO, f"stored {key}")
     return key
Exemplo n.º 3
0
def _save_local_message_copy(msg, person, assignment_path, dry_run=False):
    try:
        _os.makedirs(assignment_path)
    except OSError:
        pass
    mpath = _os_path.join(assignment_path, 'mail')
    try:
        mbox = _mailbox.Maildir(mpath, factory=None, create=not dry_run)
    except _mailbox.NoSuchMailboxError as e:
        _LOG.warn('could not open mailbox at {}'.format(mpath))
        mbox = None
        new_msg = True
    else:
        new_msg = True
        for other_msg in mbox:
            if other_msg['Message-ID'] == msg['Message-ID']:
                new_msg = False
                break
    if new_msg:
        _LOG.log(_GOOD_DEBUG,
                 'saving email from {} to {}'.format(person, assignment_path))
        if mbox is not None and not dry_run:
            mdmsg = _mailbox.MaildirMessage(msg)
            mdmsg.add_flag('S')
            mbox.add(mdmsg)
            mbox.close()
    else:
        _LOG.log(_GOOD_DEBUG,
                 'already found {} in {}'.format(msg['Message-ID'], mpath))
Exemplo n.º 4
0
    def convert(self, outpath):
        box = mailbox.Maildir(outpath)

        for jconversation in self.jfile['conversations']:
            conv_messages = []

            first_id = None
            for jmsg in jconversation:
                msg = self.build_message(jmsg)

                if self.options.threading:
                    # create a fake empty root message for each conversation

                    if first_id is None:
                        if 'address' in jmsg:  # sms
                            root = self.build_fake_root([jmsg['address']])
                        elif 'addresses' in jmsg:
                            root = self.build_fake_root(jmsg['addresses'])
                        else:
                            raise NotImplementedError(
                                'no address in the first message')

                        # conv_messages.append(root)
                        first_id = root['Message-ID']

                    set_header(msg, 'References', first_id)

                msg = mailbox.MaildirMessage(msg)
                if jmsg.get('read', False):
                    msg.add_flag('S')
                conv_messages.append(msg)

            for msg in conv_messages:
                box.add(msg)
Exemplo n.º 5
0
def format_email(to=None,
                 ffrom=None,
                 date=None,
                 subject=None,
                 body=None,
                 msgObject=None):
    """
    contains maildir-specific extensions...
    """
    if not msgObject:
        msgObject = mailbox.MaildirMessage()
        msgObject['Message-Id'] = email.utils.make_msgid()
    msgObject.set_payload(body)
    for X in ['Subject', 'To', 'From', 'Date']:
        # otherwise we'll add multiple values
        del msgObject[X]
    msgObject['Subject'] = subject
    msgObject['To'] = to
    if ffrom:
        msgObject['From'] = ffrom
    else:
        msgObject['From'] = addressbook.utils.my_address().email
    if date:
        msgObject['Date'] = date
    else:
        msgObject['Date'] = email.utils.formatdate()
    msgObject.set_flags('S')
    msgObject.set_subdir('cur')
    return msgObject
Exemplo n.º 6
0
def create_mail(msg, maildir, notmuch_db, tags, old=False):
    email_message = email.message.EmailMessage()
    # freezegun doesn't handle time zones properly when generating UNIX
    # timestamps.  When the local timezone is UTC+2, the generated timestamp
    # is 2 hours ahead of what it should be.  Due to this we need to make sure
    # that the dates are always sufficiently far behind 2019-01-30 12:00 to
    # handle up to UTC+12 .
    if old:
        email_message['Date'] = 'Wed, 10 Jan 2019 13:00:00 +0100'
    else:
        email_message['Date'] = 'Wed, 20 Jan 2019 13:00:00 +0100'
    email_message['From'] = 'You <*****@*****.**>'
    email_message['To'] = 'Me <*****@*****.**>'
    email_message['Message-ID'] = make_msgid()
    email_message.set_content(msg)

    maildir_message = mailbox.MaildirMessage(email_message)
    message_key = maildir.add(maildir_message)

    fname = os.path.join(maildir._path, maildir._lookup(message_key))
    notmuch_msg = notmuch_db.add_message(fname)
    for tag in tags:
        notmuch_msg.add_tag(tag, False)

    # Remove the angle brackets automatically added around the message ID by make_msgid.
    stripped_msgid = email_message['Message-ID'].strip('<>')
    return (stripped_msgid, msg)
Exemplo n.º 7
0
def sample_mail(subject="Sample subject"):
    msg = mailbox.MaildirMessage()
    msg.set_unixfrom('author Sat Jan 01 15:35:34 2019')
    msg['From'] = "from@localhost"
    msg['To'] = "to@localhost"
    msg['Subject'] = subject
    msg['Date'] = email.utils.formatdate()
    msg.set_payload("Sample body")
    return msg
Exemplo n.º 8
0
 def get_message(self, key):
     """Return a Message representation or raise a KeyError."""
     fd = self._get_fd(key)
     try:
         if self._factory:
             return self._factory(fd)
         else:
             return mailbox.MaildirMessage(fd)
     finally:
         fd.close()
Exemplo n.º 9
0
 def process_message(request_id, response, exception):
     if exception is not None:
         print("ERROR: " + request_id)
     else:
         msg_bytes = base64.urlsafe_b64decode(response['raw'].encode('ASCII'))
         mime_msg = email.message_from_bytes(msg_bytes)
         maildir_message = mailbox.MaildirMessage(mime_msg)
         #box.add(maildir_message)
         message_id = response['id']
         with open("mail/cur/%s" % message_id, "wb") as message_file:
             message_file.write(maildir_message.__bytes__())
    def add(self, msg, folder, flags):
        """ add message in a given subdir """
        mmsg = mailbox.MaildirMessage(msg)

        if GMVaultExporter.GM_SEEN in flags:
            mmsg.set_subdir('cur')
            mmsg.add_flag('S')
        if mmsg.get_subdir() == 'cur' and GMVaultExporter.GM_FLAGGED in flags:
            mmsg.add_flag('F')

        self.subdir(folder).add(mmsg)
Exemplo n.º 11
0
 def deliver_maildir(self,suspect):
     md_msg=mailbox.MaildirMessage(suspect.get_message_rep())
     md_path=apply_template(self.config.get(self.section,'path'), suspect)
     if os.path.isfile(md_path):
         self.logger.error("%s seems to be a file - can not use as maildir"%md_path)
         return
     
     maildir=mailbox.Maildir(md_path)
     try:
         maildir.lock()
         maildir.add(md_msg)
         maildir.flush()
     except Exception,e:
         self.logger.error("Could not store message %s to %s: %s"%(suspect.id,md_path,str(e)))
Exemplo n.º 12
0
 def test___getitem___valid_message_id_w_datestamp_folder_w_message(self):
     import os
     import mailbox
     path = self._getTempdir()
     root = mailbox.Maildir(os.path.join(path, 'Maildir'),
                            factory=None, create=True)
     root.add_folder('2009.06.23')
     folder = root.get_folder('2009.06.23')
     to_store = mailbox.MaildirMessage('STORE_ME')
     key = folder.add(to_store)
     md = self._makeOne(path)
     md.sql.execute('insert into messages'
                      '(message_id, year, month, day, maildir_key)'
                    ' values("ABC", 2009, 6, 23, "%s")' % key)
     message = md['ABC'] # doesn't raise
Exemplo n.º 13
0
 def _add_message(self, maildir, msg_id, flags, subdir):
     m = mailbox.MaildirMessage()
     m.set_payload('Hello world!', 'ascii')
     m.add_header('from', '*****@*****.**')
     m.add_header('to', '*****@*****.**')
     m.add_header('subject', 'Hi!')
     m.add_header('message-id', msg_id)
     if flags:
         m.set_flags(flags)
     m.set_subdir(subdir)
     maildir.lock()
     try:
         maildir.add(m)
     finally:
         maildir.unlock()
Exemplo n.º 14
0
    def deliver(
        self,
        subject='Test mail',
        body='This is a test mail',
        to='*****@*****.**',
        frm='*****@*****.**',
        headers=None,
        new=False,  # Move to new dir or cur dir?
        keywords=None,  # List of keywords or labels
        seen=False,  # Seen flag (cur dir only)
        replied=False,  # Replied flag (cur dir only)
        flagged=False):  # Flagged flag (cur dir only)
        """Deliver a new mail message in the mbox.

        This does only adds the message to maildir, does not insert it
        into the notmuch database.

        :returns: A tuple of (msgid, pathname).
        """
        msgid = self._next_msgid()
        when = time.time()
        msg = email.message.EmailMessage()
        msg.add_header('Received', 'by MailDir; {}'.format(time.ctime(when)))
        msg.add_header('Message-ID', '<{}>'.format(msgid))
        msg.add_header('Date', time.ctime(when))
        msg.add_header('From', frm)
        msg.add_header('To', to)
        msg.add_header('Subject', subject)
        if headers:
            for h, v in headers:
                msg.add_header(h, v)
        msg.set_content(body)
        mdmsg = mailbox.MaildirMessage(msg)
        if not new:
            mdmsg.set_subdir('cur')
        if flagged:
            mdmsg.add_flag('F')
        if replied:
            mdmsg.add_flag('R')
        if seen:
            mdmsg.add_flag('S')
        boxid = self.mailbox.add(mdmsg)
        basename = boxid
        if mdmsg.get_info():
            basename += mailbox.Maildir.colon + mdmsg.get_info()
        msgpath = self.path / mdmsg.get_subdir() / basename
        return (msgid, msgpath)
Exemplo n.º 15
0
    def store_mail(mbx, mail):
        """
        stores given mail in mailbox. If mailbox is maildir, set the S-flag and
        return path to newly added mail. Oherwise this will return `None`.

        :param mbx: mailbox to use
        :type mbx: :class:`mailbox.Mailbox`
        :param mail: the mail to store
        :type mail: :class:`email.message.Message` or str
        :returns: absolute path of mail-file for Maildir or None if mail was
                  successfully stored
        :rtype: str or None
        :raises: StoreMailError
        """
        if not isinstance(mbx, mailbox.Mailbox):
            logging.debug('Not a mailbox')
            return False

        mbx.lock()
        if isinstance(mbx, mailbox.Maildir):
            logging.debug('Maildir')
            msg = mailbox.MaildirMessage(mail)
            msg.set_flags('S')
        else:
            logging.debug('no Maildir')
            msg = mailbox.Message(mail)

        try:
            message_id = mbx.add(msg)
            mbx.flush()
            mbx.unlock()
            logging.debug('got mailbox msg id : %s', message_id)
        except Exception as e:
            raise StoreMailError(e)

        path = None
        # add new Maildir message to index and add tags
        if isinstance(mbx, mailbox.Maildir):
            # this is a dirty hack to get the path to the newly added file
            # I wish the mailbox module were more helpful...
            plist = glob.glob1(os.path.join(mbx._path, 'new'),
                               message_id + '*')
            if plist:
                path = os.path.join(mbx._path, 'new', plist[0])
                logging.debug('path of saved msg: %s', path)
        return path
Exemplo n.º 16
0
 def __setitem__(self, message_id, message):
     """ See IMessageStore.
     """
     to_store = mailbox.MaildirMessage(message)
     date = to_store['Date']
     yy, mm, dd, hh, mt, ss, wd, jd, dst = parsedate(date)
     folder_name = self._getFolderName(yy, mm, dd)
     folder = self._getMaildir(folder_name)
     key = folder.add(to_store)
     try:
         self.sql.execute('insert into messages'
                          '(message_id, year, month, day, maildir_key) '
                          'values("%s", %d, %d, %d, "%s")'
                           % (message_id, yy, mm, dd, key)
                         )
     except:
         folder.remove(key)
         raise
Exemplo n.º 17
0
	def _explain_to(self, message):
		"""Copy format-specific state to message."""
		if isinstance(message, mailbox.MaildirMessage):
			flag_map = {
				'\\draft':    'D',
				'\\flagged':  'F',
				'\\answered': 'R',
				'\\seen':     'S',
				'\\deleted':  'T'
			}
			msg.set_flags(v for k, v in flag_map.items() if k in self._flags)
			if '\\recent' not in self._flags:
				msg.set_subdir('cur')
			if self._idate is not None:
				msg.set_date(self._idate)
		else:
			# Use maildir conversion for all other formats
			maildir = mailbox.MaildirMessage(self)
			maildir._explain_to(message)
Exemplo n.º 18
0
 def make_message(
         self,
         subject='subject',
         from_addr='*****@*****.**',
         to_addr='*****@*****.**'):
     mbox = mailbox.Maildir(self._path)
     mbox.lock()
     try:
         msg = mailbox.MaildirMessage()
         msg.set_unixfrom('author Sat Jul 23 15:35:34 2017')
         msg['From'] = from_addr
         msg['To'] = to_addr
         msg['Subject'] = subject
         msg['Date'] = email.utils.formatdate()
         msg.set_payload(textwrap.dedent('''
         This is the body.
         There are 2 lines.
         '''))
         mbox.add(msg)
         mbox.flush()
     finally:
         mbox.unlock()
     return msg
Exemplo n.º 19
0
def main(argv):
    in_mbox = "inbox.mbox"
    out_box = "Maildir"
    try:
        opts, args = getopt.getopt(argv, "i:o:", ["infile=", "outdir="])
    except getopt.GetoptError:
        print("python splitgmail.py -i <infile> -o <outdir>")
        sys.exit(2)

    for opt, arg in opts:
        if opt in ("-i", "--infile"):
            in_mbox = arg
        elif opt in ("-o", "--outdir"):
            out_box = arg

    print("Processing file \"" + in_mbox + "\", output \"" + out_box + "\"")
    sys.stdout.flush()

    destMbox = mailbox.Maildir(out_box, create=True)

    # create common subfolders, INBOX is root
    destMbox.add_folder("Sent")
    destMbox.add_folder("Archive")

    sourcembox = mailbox.mbox(in_mbox, create=False)
    print(str(sourcembox.__len__()) + " messages to process")
    sys.stdout.flush()

    mcount = mjunk = mchat = msaved = 0
    for message in sourcembox:
        read = True
        flagged = False
        mcount += 1
        gmail_labels = message["X-Gmail-Labels"]
        # extract delivery date from mbox "From_" field
        ddate = message.get_from()
        ddate = ddate.split(' ', 1)[1]
        depoch = time.mktime(
            time.strptime(ddate.strip(),
                          "%a %b %d %H:%M:%S +0000 %Y")) - time.timezone
        tbox = "Archive"  # default target box: Archive

        if gmail_labels:
            gmail_labels = gmail_labels.split(
                ','
            )  # from here we only work on an array to avoid partial matches
            if "Unread" in gmail_labels:
                read = False
            if "Starred" in gmail_labels:
                flagged = True

            if "Spam" in gmail_labels:  # skip all spam
                mjunk += 1
                continue
            elif "Chat" in gmail_labels:  # skip all chat
                mchat += 1
                continue
            elif "Sent" in gmail_labels:  # anything that has Sent goes to Sent box
                tbox = "Sent"
            elif "Inbox" in gmail_labels:  # Inbox treated here because some messages can be Sent,Inbox
                tbox = "Inbox"
            else:
                for label in gmail_labels:
                    # ignore meta labels
                    if label == "Important" or label == "Unread" or label == "Starred" or label == "Newsletters":
                        continue

                    # use first match
                    tbox = label

                    # handle odd labels
                    if label == "[Imap]/Archive":
                        tbox = "Archive"
                    break
                # if nothing matched we'll use default set at message loop start

        # fixup missing status flags in the message
        if read:
            message["Status"] = "RO"
        else:
            message["Status"] = "O"
        if flagged:
            message["X-Status"] = "F"

        mfrom = message["From"] or "Unknown"
        mid = message["Message-Id"] or "<N/A>"
        print("Storing " + mid + " from \"" + mfrom + "\" to folder \"" +
              tbox + "\"")
        msaved += 1

        # convert message to maildir
        MDmsg = mailbox.MaildirMessage(message)

        # fixup received date
        MDmsg.set_date(depoch)

        if tbox == "Inbox":
            destMbox.add(MDmsg)
        else:
            if tbox not in destMbox.list_folders():
                destMbox.add_folder(tbox)
            tfolder = destMbox.get_folder(tbox)
            tfolder.add(MDmsg)

    print(
        str(mcount) + " messages processed, " + str(saved) + " messages saved")
    print("ignored: " + str(mjunk) + " spam, " + str(mchat) + " mchat")
Exemplo n.º 20
0
 def deliver(self, message):
     # TODO: Create an ID based on process and thread IDs.
     # Current bhaviour may allow for name clashes in multi-threaded.
     self.box.add(mailbox.MaildirMessage(str(message)))
Exemplo n.º 21
0
def iadd(ui, repo, id=None, comment=0, **opts):
    """Adds a new issue, or comment to an existing issue ID or its comment COMMENT"""

    comment = int(comment)

    # First, make sure issues have a directory
    issues_dir = ui.config('artemis', 'issues', default=default_issues_dir)
    issues_path = os.path.join(repo.root, issues_dir)
    if not os.path.exists(issues_path): os.mkdir(issues_path)

    if id:
        issue_fn, issue_id = _find_issue(ui, repo, id)
        if not issue_fn:
            ui.warn('No such issue\n')
            return
        _create_missing_dirs(issues_path, issue_id)
        mbox = mailbox.Maildir(issue_fn, factory=mailbox.MaildirMessage)
        keys = _order_keys_date(mbox)
        root = keys[0]

    user = ui.username()

    default_issue_text = "From: %s\nDate: %s\n" % (user,
                                                   datestr(format=date_format))
    if not id:
        default_issue_text += "State: %s\n" % default_state
        default_issue_text += "Subject: brief description\n\n"
    else:
        subject = mbox[(comment < len(mbox) and keys[comment])
                       or root]['Subject']
        if not subject.startswith('Re: '): subject = 'Re: ' + subject
        default_issue_text += "Subject: %s\n\n" % subject
    default_issue_text += "Detailed description."

    # Get properties, and figure out if we need an explicit comment
    properties = _get_properties(opts['property'])
    no_comment = id and properties and opts['no_property_comment']
    message = opts['message']

    # Create the text
    if message:
        if not id:
            state_str = 'State: %s\n' % default_state
        else:
            state_str = ''
        issue = "From: %s\nDate: %s\nSubject: %s\n%s" % \
                (user, datestr(format=date_format), message, state_str)
    elif not no_comment:
        issue = ui.edit(default_issue_text, user)

        if issue.strip() == '':
            ui.warn('Empty issue, ignoring\n')
            return
        if issue.strip() == default_issue_text:
            ui.warn('Unchanged issue text, ignoring\n')
            return
    else:
        # Write down a comment about updated properties
        properties_subject = ', '.join(
            ['%s=%s' % (property, value) for (property, value) in properties])

        issue =     "From: %s\nDate: %s\nSubject: changed properties (%s)\n" % \
                     (user, datestr(format = date_format), properties_subject)

    # Create the message
    msg = mailbox.MaildirMessage(issue)
    if opts['attach']:
        outer = _attach_files(msg, opts['attach'])
    else:
        outer = msg

    # Pick random filename
    if not id:
        issue_fn = issues_path
        while os.path.exists(issue_fn):
            issue_id = _random_id()
            issue_fn = os.path.join(issues_path, issue_id)
        mbox = mailbox.Maildir(issue_fn, factory=mailbox.MaildirMessage)
        keys = _order_keys_date(mbox)
    # else: issue_fn already set

    # Add message to the mailbox
    mbox.lock()
    if id and comment >= len(mbox):
        ui.warn(
            'No such comment number in mailbox, commenting on the issue itself\n'
        )

    if not id:
        outer.add_header(
            'Message-Id',
            "<%s-0-artemis@%s>" % (issue_id, socket.gethostname()))
    else:
        root = keys[0]
        outer.add_header(
            'Message-Id', "<%s-%s-artemis@%s>" %
            (issue_id, _random_id(), socket.gethostname()))
        outer.add_header(
            'References', mbox[(comment < len(mbox) and keys[comment])
                               or root]['Message-Id'])
        outer.add_header(
            'In-Reply-To', mbox[(comment < len(mbox) and keys[comment])
                                or root]['Message-Id'])
    new_bug_path = issue_fn + '/new/' + mbox.add(outer)
    commands.add(ui, repo, new_bug_path)

    # Fix properties in the root message
    if properties:
        root = _find_root_key(mbox)
        msg = mbox[root]
        for property, value in properties:
            if property in msg:
                msg.replace_header(property, value)
            else:
                msg.add_header(property, value)
        mbox[root] = msg

    mbox.close()

    if opts['commit']:
        commands.commit(ui, repo, issue_fn)

    # If adding issue, add the new mailbox to the repository
    if not id:
        ui.status('Added new issue %s\n' % issue_id)
    else:
        _show_mbox(ui, mbox, 0)
Exemplo n.º 22
0
    # Open the maildir for delivery
    try:
        inbox = mailbox.Maildir(maildir, None,
                                config.get("dystill", "create_maildirs"))
    except mailbox.Error, message:
        print "Could not deliver the message to the specified mailbox."
        sys.exit(EX_TEMPFAIL)
    except mailbox.NoSuchMailboxError, message:
        print "Could not deliver the message to the specified mailbox."
        sys.exit(EX_TEMPFAIL)

    folders = inbox.list_folders()

    # Bring the message in
    message = mailbox.MaildirMessage(zemail)
    delivered = False
    exit = EX_OK

    # Mark as read
    if actions.__contains__("markasread"):
        message.add_flag("S")
        message.set_subdir("cur")

    # Flag
    if actions.__contains__("flag"):
        message.add_flag("F")

    # Delete
    if actions.__contains__("delete"):
        message.add_flag("S")
Exemplo n.º 23
0
# We only want to extract the items that have been read and which are
# not deleted
c.execute('select title, author, feedurl, pubDate, content from'
         + ' rss_item where unread=0 and deleted=0')
# for every line, we put a message in the right mailbox
for line in c:
    header = u'<html><head></head><body>'.encode('utf-8')
    footer = u'</body></html>'.encode('utf-8')
    msg = MIMEText(header+line[4].encode('utf-8')+footer, 'html')
    msg['Subject'] = line[0].encode('utf-8')
    msg['From'] = line[1].encode('utf-8')
    msg['Date'] = email.utils.formatdate(float(line[3]))
    if line[2] in feed2mail.keys():
      feed = feed2mail[line[2]]
        # If the maildir doesn't exist, we create it.
        if feed not in destination.list_folders():
            print "maildir", feed, "doesn't exist: we create it !"
            maildir_feed = destination.add_folder(feed)
        else:
              maildir_feed = destination.get_folder(feed)
        # Add the message to the maildir and mark it unread:
        msg_in_feed = mailbox.MaildirMessage(msg)
        msg_in_feed.set_flags('S')
        msg_key = maildir_feed.add(msg_in_feed)
    else: 
        print "Unknown Feed:",line[2]

destination.close()

exit(0)
  
Exemplo n.º 24
0
def email_from_raw(raw):
    msg_bytes = base64.urlsafe_b64decode(raw.encode('ASCII'))
    mime_msg = email.message_from_bytes(msg_bytes)
    maildir_message = str(mailbox.MaildirMessage(mime_msg))
    return maildir_message