2

How can I safely, and hopefully with the standard python tools for Maildir, find the complete filename and path of a Maildir message. I want to write the mail-message-file to a tarfile before I delete it.

I'm importing mailbox and tarfile (++)

Context:

A list of Maildirs (created from a text file)

Looping over the Maildirs (simplified), creating a list over mails to delete, a function will take the list of mails, and one by one, append the emails to a tarfile, then delete the email.

import mailbox
# Creating the list
for maildir in maildir_list
    inbox = mailbox.Maildir(maildir, factory=None, create=False)
      # Looping over folders, if (folder = Trash)
    for key,msg in inbox.iteritems():
        my_list.append(maildir, inbox, key, foldername

Then looping over the list to append the mails to a tarfile and delete (discard) them.

    import tarfile,mailbox
    # _box is allready initialized in the previous function
    for _maildir, _box, _key, _foldername in __my_list:
        __msg = _box[_key]
        __subdir = __msg.get_subdir()
        __suffix   = mailbox.Maildir.colon + __msg.get_info()
        if __suffix == mailbox.Maildir.colon:
            __suffix = ''
        __file_name = "%s/.%s/%s/%s%s" % ( _maildir, _foldername, __subdir, _key, __suffix )

        try:
            tar.add(__file_name)
            _box.discard(_key)
        except Exception as inst:
            error_type = type(inst)
            log_text = "%s\: ERROR %s - %s" % (error_type, __file_name, inst)
            log_this( logKeySub, log_text )
            e.write(log_text + "\n")

I've looked into the python docs for mailbox and email, searched google, stackoverflow, etc. For now I'm resorting to building the path and file name with _maildir, _foldername, _key and get_info().

Edit: Based on a comment by t-8ch I've made this adjustment:

for _maildir, _box, _key, _foldername in __my_list:
    try:
        __file = _box._toc[_key]
        __file_name = "%s/.%s/%s" % ( _maildir, _foldername, __file )
    except Exception as inst:
            error_type = type(inst) # Type Exception, inst.args, inst
            log_text = "%s\: ERROR with %s/.%s - %s - %s" % (error_type, _maildir, _foldername, _key, inst)
            log_this( logKeySub, log_text )
            e.write(log_text + "\n")
            continue

A dry run proved it to work very nicely.

sastorsl
  • 2,015
  • 1
  • 16
  • 17
  • Where do the values of `__my_list` come from? – tripleee Feb 26 '13 at 20:17
  • I must have missed your comment since I didn't see it until now. In another function I have "for key, msg in box.iteritems()", which populates the list. – sastorsl Mar 04 '13 at 10:35
  • That still doesn't really help clarify. Which library are you using, how does `box` get initialized? Are you using [Mailbox](http://docs.python.org/2/library/mailbox.html) or something else? Please edit your question to include the relevant information. – tripleee Mar 04 '13 at 11:16
  • I've made a small adjustment, based on what I saw in mailbox.py. If mailbox.Maildir.colon + msg.get_info() == mailbox.Maildir.colon --> suffix = '' - But still I would prefer a standard tool so that I don't have to "construct" the filename. – sastorsl Mar 04 '13 at 15:02
  • Does `Maildir._toc` help you? Like: `_box._toc[_key]` – t-8ch Mar 04 '13 at 17:22
  • YES: _box._toc[_key] works. Returns /, i.e. "cur/12345677890.etc.host:2, - Did you find this in the source for mailbox.py, or have a missed an obvious source? – sastorsl Mar 04 '13 at 22:14

1 Answers1

4

You can use Maildir._toc. This is a dictionary mapping the keys of mails to the path of their corresponding file. This dictionary is constructed in Maildir._refresh(). This allows to defer the reading of a mails file only on demand and thus decreases the time to refresh the list of all mails (which happens quite often).

(I did find this in the source)

t-8ch
  • 2,583
  • 14
  • 18