在前文里讲了如何用gnus搭配一些工具收发Gmail,不过fetchmail用来收取POP3邮件,的确有很多缺陷,最重要的是它只能抓取Gmail INBOX里的邮件,对label无能为力,这很让人头疼。不过还好有offlineimap这个小工具,而且其中有一部分功能就是专门为Gmail定制的。
具体可以参考Sacha Chua的这篇文章Geek: How to use offlineimap and the dovecot mail server to read your Gmail in Emacs efficiently,文中使用dovecot在本地架设一个imapd,而offlineimap作为一个桥梁,默默地在后台把远端的Gmail邮件同步到本地imapd里去。这样gnus直接连接本地imapd即可。这篇文章的回复里,有人质疑为啥还需要本地imapd呢?让offlineimap直接同步Gmail到一个Maildir,然后gnus访问这个Maildir不也可以么?Sacha Chua没有直接答复,我试了一下的确也可行。
只是使用 nnmaildir 直接访问 Maildir 目录有个缺憾,对于已读标记,gnus维护自己的flags,而不是使用标准的Maildir flags,这导致offlineimap没法把已读标记同步回Gmail :-( 不过也有人给出个workaround,就是利用offlineimap的 presynchook
和 postsynchook
再额外同步gnus和Maildir的flags……
所以,目前看来比较理想的方式还是使用dovecot在本地架设imapd,然后gnus通过nnimap 的方式访问本地imapd,这样就不会有已读标记丢失的问题。gnus 对本地imapd所做的修改再由offlineimap同步到远端的Gmail,所以基本是这个流程:
- 同步邮件到本地: Gmail → offlineimap → dovecot
- gnus管理邮件: gnus ↔ dovecot
- 同步邮件到远端: dovecot → offlineimap → Gmail
offlineimap
配置offlineimap,让它可以同步你的Gmail账户。可以查看offlineimap源码包下的示例配置,其中对每个参数都有详细说明。默认配置文件位于 ~/.offlineimaprc
:
[general]
ui = Basic
accounts = GMail
maxsyncaccounts = 3
socktimeout = 30
[Account GMail]
localrepository = Local
remoterepository = Remote
autorefresh = 5
quick = 10
maxage = 7
[Repository Local]
type = IMAP
remotehost = localhost
port = 143
remoteuser = jqian
remotepass = login password
[Repository Remote]
type = Gmail
remoteuser = junist@gmail.com
remotepass = gmail's password
maxconnections = 2
readonly = False
# Setting realdelete = yes will Really Delete email from the server.
# Otherwise "deleting" a message will just remove any labels and
# retain the message in the All Mail folder.
realdelete = no
idlefolders = ['INBOX']
folderfilter = lambda folder: folder not in ['[Gmail]/All Mail', '[Gmail]/Trash']
如果你的邮件过多,而且有很多archive过的,那可以通过设置 maxage
来避免同步很老的邮件。设置 autorefresh
可以让offlineimap定期同步。设置 idlefolders
使用 IDLE
指令将保持长连接,可以有push mail的效果。运行offlineimap默认是一个ncurse的交互界面,如果你要让offlineimap在后台执行,应该设置 ui = Basic
。
此外,在 [Repository Remote]
这个section里,如果设置 type = Gmail
,那么当删除邮件时,实际邮件将被移动到 [Gmail]/Trash
,这是Gmail的特性。
offlineimap是用python的ConfigParser来解析 ~/.offlineimaprc
,所有的注释符 #
需顶格,注意。
最后,可以让offlineimap登录后即在后台运行,它就会默默的帮你去同步Gmail邮件了。
dovecot imapd
dovecot基本无需额外配置,默认使用系统的用户名密码就能登录。不过你可以指定离线邮件的保存位置,ubuntu下编辑 /etc/dovecot/conf.d/10-mail.conf
:
mail_location = maildir:%h/Maildir
其中,Sacha文章提及的 default_mail_env
已经过时了,使用 mail_location
替代。
gnus
在本地架设imapd的话,给gnus指定 nnimap 类型的访问方式即可:
(setq gnus-select-method
'(nnimap ""
(nnimap-address "localhost")
(nnimap-authenticator login)
(nnimap-authinfo-file "~/.authinfo")))
其中,你可以把登录本地imapd的用户名密码保存到 ~/.authinfo
,这样就不需要每次打开gnus还需要手工录入密码了。如果使用 ~/.authinfo.gpg
则可以通过 gpg 加密。
然后,运行gnus,怎么样?所有的Gmail标签都能看到了吧?
一些补充
Gmail的label尽量不要用中文,offlineimap处理中文标签似乎有bug,遇到过同步失败的情况。
这里有一份我的配置,其中详细介绍了使用gnus收取Gmail的多种办法。