2015-04-03 2 views
1

Я загружаю сообщения IMAP с imaplib в Mbox (с mailbox модуля):Сохранение сообщений IMAP с модулем Python почтового ящика

import imaplib, mailbox 
svr = imaplib.IMAP4_SSL('imap.gmail.com') 
svr.login('[email protected]', 'mypaswword') 
resp, [countstr] = svr.select("[Gmail]/All Mail", True) 

mbox = mailbox.mbox('mails.mbox') 

for n in range(...): 
    resp, lst1 = svr.fetch(n, 'UID') # the UID of the message 
    resp, lst2 = svr.fetch(n, '(RFC822)') # the message itself 
    mbox.add(lst2[0][1])  # add the downloaded message to the mbox 
    # 
    # how to store the UID of this current mail inside mbox? 
    # 

Давайте загружать почту с UID = 1 .. 1000. В следующий раз я хотел бы начать с 1001-го сообщения, а не с 1-го. Однако mailbox.mboxне хранит UID anywhre. Поэтому в следующий раз, когда я открою файл mbox, невозможно будет узнать, где мы остановились.

Есть ли естественный способ с модулем mailbox для хранения UID писем?

Возможно, я не использую mailbox + imaplib так, как должно быть?

ответ

1

Чтобы ответить на ваш вопрос: долгое время я долго смотрел на документы, я не видел никакого способа сделать то, что вы ищете. Если это абсолютное требование, что UI хранятся в файле MBox, то я предложил бы добавить заголовок пользовательского UID для писем, которые вы хранящие:

message = email.message_from_string(lst2[0][1]) 
message.add_header("my_internal_uid_header", lst1[0][1]) 
mbox.add(message) 

Теперь, конечно, это огромная боль получить самый большой сохраненный UID, потому что вам нужно перебирать все сообщения. Я думаю, что это было бы очень плохо. Если это вообще возможно, лучше хранить такую ​​информацию в другом месте.

Удачи!

+0

Правда, это огромный, чтобы получить самый большой сохраненный UID, потому что нужно повторить ... Что бы вы сделали тогда @JosiahDaniels? – Basj

+0

Я не уверен, какие у вас требования. Например, можете ли вы сохранить его в отдельном json-файле в той же папке? Или важно сохранить UID в файле mmox? – JosiahDaniels

+0

Все, что я хочу, это возможность не повторно загружать дважды одно и то же сообщение в mbox. Я надеялся, что это возможно только с mbox и без внешнего файла. Я ищу хорошее питоновское решение;) Но если внешний JSON является обязательным, давайте сделаем это ... даже если это позор;) – Basj

1

Я надеюсь, что это будет полезно:

1) библиотеки и среды Win7 Anaconda3-4.3.1-Windows-x86_64.exe (новый доступен, но то, что я использовал

2) К списку все ваши почтовые ящики:

import getpass, imaplib, sys 

def main(): 
     hostname = 'my.mail.server' 
     username = 'my_user_name' 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, 'passowrd') 

    try: 
     print('Capabilities:', m.capabilities) 
     print('Listing mailboxes ') 
     status, data = m.list() 
     print('Status:', repr(status)) 
     print('Data:') 
     for datum in data: 
     print(repr(datum)) 

    finally: 
     m.logout() 

if __name__ == '__main__': 
    main() 

3) Использование генерироваться выше информации можно сбросить все сообщения электронной почты с почтового сервера каталогов:

import getpass, imaplib, sys, email, os , io 
import codecs 

BASE_NAME = 'msg_no_' 
BASE_DIR = 'D:/my_email/' 

def writeTofile(mailDir, partOfName, msg): 

    ## no need of dos backslash -- newDir = BASE_DIR + mailDir.replace('/', '\\') 

    newDir = BASE_DIR + mailDir 

    if not os.path.exists(newDir): 
     os.makedirs(newDir) 

    os.chdir(newDir) 

    # print('Dir:' + os.getcwd()) 

    file_name = BASE_NAME + partOfName + '.eml' 

    # print('Write:' + file_name) 

    fw = open(newDir + '/' + file_name,'w', encoding="utf-8") 
    fw.write(msg) 
    fw.close() 

    return 


def processMailDir(m, mailDir): 

    print('MailDIR:' + mailDir) 

    m.select(mailbox=mailDir, readonly=True) 
    typ, data = m.search(None, 'ALL') 

    for num in data[0].split(): 
     typ, data = m.fetch(num, '(RFC822)') 
     msg = email.message_from_bytes(data[0][1]) 

     smsg = msg.as_bytes().decode(encoding='ISO-8859-1') 

     writeTofile(mailDir, num.decode(), smsg) 

    m.close() 

    return 


def main(): 

    if len(sys.argv) != 3: 
     hostname = 'my.mail.server' 
     username = 'my_username' 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, 'password') 

    else: 
     hostname, username = sys.argv[1:] 
     m = imaplib.IMAP4_SSL(hostname) 
     m.login(username, getpass.getpass()) 

    try: 
     print('Start...') 

     processMailDir(m, 'INBOX') 
     processMailDir(m, 'Sent') 
     processMailDir(m, 'archive/2013/201301') 
     processMailDir(m, 'archive/2013/201302') 
# etc.. etc.. simple as it can be but not simpler 
     print('Done...') 

    finally: 
     m.logout() 

if __name__ == '__main__': 
    main() 

Над сбросит ваши электронные письма: D: \ my_email \ INBOX \ msg_no_1.eml ... msg_no203.eml

тогда вам нужен этот секрет, чтобы открыть EML на окнах:

Administrator: cmd.com: 

assoc .eml=Outlook.File.eml 
ftype Outlook.File.eml="C:\Program Files (x86)\Microsoft Office\Office12\OUTLOOK.EXE" /eml "%1" 

Уважаемый стопроцентная цензура - будьте милостивы, я бы нашел выше полезной; например: smsg = msg.as_bytes(). decode (encoding = 'ISO-8859-1') занял много времени, чтобы понять.

Смежные вопросы