Была задача слить всю почту с gmail и отправить в архив. На просторах github’a был обнаружен скрипт, позволяющий это делать. Но к сожалению данный скрипт не работал и вот почему: т.к. я использую в gmail настройки русского языка, то все imap каталоги обзываются кириллицей (по всей видимости актуально и для других национальных языков), которая в свою очередь кодируется в IMAPUTF7.
Мне не удалось найти кодер\декодер данной кодировки или утилиту которая бы это делала, поэтому я подсмотрел как обзывает каталоги почтового ящика Mozilla Thunderbird. Ниже привожу [название папки] —> [код в UTF7]:
1 2 3 4 5 6 7 |
Вся почта --> BBIEQQRP- &BD8EPgRHBEIEMA- Черновики --> BCcENQRABD0EPgQyBDgEOgQ4- Отправленные --> BB4EQgQ,BEAEMAQyBDsENQQ9BD0ESwQ1- Спам --> BCEEPwQwBDw- Корзина --> BBoEPgRABDcEOAQ9BDA- Важное --> BBIEMAQ2BD0EPgQ1- Помеченное --> BB8EPgQ8BDUERwQ1BD0EPQRLBDU- |
Соответственно, в зависимости от того содержимое какой папки мы хотим забэкапить, то наименование и подставляем в 41-й строке скрипта, после [Gmail]/.
Сам скрипт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#!/usr/bin/python # -*- utf-8 -*- # import imaplib, os, getpass, re, email, email.utils, datetime, time, calendar uidre = re.compile(r"\d+\s+\(UID (\d+)\)$") def getUIDForMessage(n): resp, lst = svr.fetch(n, 'UID') m = uidre.match(lst[0]) if not m: raise Exception("Internal error parsing UID response: %s %s. Please try again" % (resp, lst)) return m.group(1) def downloadMessage(n, fname): resp, lst = svr.fetch(n, '(RFC822)') if resp!='OK': raise Exception("Bad response: %s %s" % (resp, lst)) f = open(fname, 'w') f.write(lst[0][1]) f.close() message = email.message_from_string(lst[0][1]) dt_src = email.utils.parsedate_tz(message['date']) if dt_src: utc_dt = datetime.datetime(*dt_src[:6])-datetime.timedelta(seconds= dt_src[-1]) dt = datetime.datetime.fromtimestamp(calendar.timegm(utc_dt.timetuple())) message_ctime = time.mktime(dt.timetuple()) os.utime(fname, (message_ctime, message_ctime)) filere = re.compile(r"(\d+).eml$") def UIDFromFilename(fname): m = filere.match(fname) if m: return int(m.group(1)) svr = imaplib.IMAP4_SSL('imap.gmail.com') svr.login(raw_input("Gmail address: "), getpass.getpass("Gmail password: ")) resp, [countstr] = svr.select("[Gmail]/&BBIEQQRP- &BD8EPgRHBEIEMA-", True) count = int(countstr) lastdownloaded = max(UIDFromFilename(f) for f in os.listdir('.')) # A simple binary search to see where we left off gotten, ungotten = 0, count+1 while ungotten-gotten>1: attempt = (gotten+ungotten)/2 uid = getUIDForMessage(attempt) if int(uid)<=lastdownloaded: print "Finding starting point: %d/%d (UID: %s) too low" % (attempt, count, uid) gotten = attempt else: print "Finding starting point: %d/%d (UID: %s) too high" % (attempt, count, uid) ungotten = attempt # The download loop for i in range(ungotten, count+1): uid = getUIDForMessage(i) print "Downloading %d/%d (UID: %s)" % (i, count, uid) downloadMessage(i, uid+'.eml') svr.close() svr.logout() |
Затем просто запускам скрипт из консоли.