谁有在 Mac 上面使用 Emacs 作为邮件客户端的经验?

offlineimap 没法双向同步中文文件夹

腾讯企业邮里有类似 其他文件夹.xxx 的文件夹,没法重命名。目前只能用白名单间接排除掉。

装emacs之前我用getmail+mutt+vim+msmtp+w3m收发QQ邮件。然而还是没学会怎么配置gnus。因为只能找到gmail的例子。


Gmail账号因为无法验证丢了的人

请问下你是用什么同步的,offlineimap or mbsync? 我用mbsync 同步qq邮箱,如果 配置文件中指定了 inbox路径,第二次同步就会出现 Error: channel xxxxx: master Inbox cannot be opened. 我觉得是远程的服务器上收件箱不是命名为 Inbox. 如果不在配置文件中指定 Inbox 项,则同步之后根本没有收件的那个文件夹,但有已删除,已发送等文件夹可以同步。 能看下你的配置文件吗? 对了,完全无法同步163邮箱。。。。。。

用getmail吧。一般POP3收件够用了。还能把原件存在服务器里以防万一(当然也能远程删信,一般30天后自动彻底删除)。直接用procmail过滤也能免得一个个到不同邮箱设置过滤规则。

上面也提到了 offlineimap 的缺陷

对 mu4e 的说明有点无语,明明只要是支持malidir的收件端都能用,就写了个offlineimap而不提及其他收件端误导用户,一般来说其实 getmail 更容易配置。

曾经linux下用过mew 小日本写的一个东西,对CJK是支持的, 记得当初用的时候 定阅了一些邮件列表,可以很方便的找到当前主题的下(上)一封邮件 支持pop imap ,可以看我配置里的注释 有详细解释 https://www.emacswiki.org/emacs/Mew

用了 mac的Mail后 就懒得折腾了 。

已弃用Mew,有个更好的替代品Wanderlust,最早是由日本人写的,对Maildir支持更好。

顺带,macOS上支持写完邮件后用Mail.app发信。说实话这个APP还是不错的。不过我当初就是因为GUI的东西太慢才开始用命令行工具……

刚发现之前贴过链接了

这个可以用 nametrans = lambda foldername: foldername.decode('utf-8').encode('imap4-utf-7') imap-utf-7 在网络有人分享了的. 具体网址记不了了。文件可以贴过来


"""
Imap folder names are encoded using a special version of utf-7 as defined in RFC
2060 section 5.1.3.

5.1.3.  Mailbox International Naming Convention

   By convention, international mailbox names are specified using a
   modified version of the UTF-7 encoding described in [UTF-7].  The
   purpose of these modifications is to correct the following problems
   with UTF-7:

      1) UTF-7 uses the "+" character for shifting; this conflicts with
         the common use of "+" in mailbox names, in particular USENET
         newsgroup names.

      2) UTF-7's encoding is BASE64 which uses the "/" character; this
         conflicts with the use of "/" as a popular hierarchy delimiter.

      3) UTF-7 prohibits the unencoded usage of "\"; this conflicts with
         the use of "\" as a popular hierarchy delimiter.

      4) UTF-7 prohibits the unencoded usage of "~"; this conflicts with
         the use of "~" in some servers as a home directory indicator.

      5) UTF-7 permits multiple alternate forms to represent the same
         string; in particular, printable US-ASCII chararacters can be
         represented in encoded form.

   In modified UTF-7, printable US-ASCII characters except for "&"
   represent themselves; that is, characters with octet values 0x20-0x25
   and 0x27-0x7e.  The character "&" (0x26) is represented by the two-
   octet sequence "&-".

   All other characters (octet values 0x00-0x1f, 0x7f-0xff, and all
   Unicode 16-bit octets) are represented in modified BASE64, with a
   further modification from [UTF-7] that "," is used instead of "/".
   Modified BASE64 MUST NOT be used to represent any printing US-ASCII
   character which can represent itself.

   "&" is used to shift to modified BASE64 and "-" to shift back to US-
   ASCII.  All names start in US-ASCII, and MUST end in US-ASCII (that
   is, a name that ends with a Unicode 16-bit octet MUST end with a "-
   ").

      For example, here is a mailbox name which mixes English, Japanese,
      and Chinese text: ~peter/mail/&ZeVnLIqe-/&U,BTFw-

"""
import binascii
import codecs

# encoding

def modified_base64(s):
    s = s.encode('utf-16be')
    return binascii.b2a_base64(s).rstrip('\n=').replace('/', ',')

def doB64(_in, r):
    if _in:
        r.append('&%s-' % modified_base64(''.join(_in)))
        del _in[:]

def encoder(s):
    r = []
    _in = []
    for c in s:
        ordC = ord(c)
        if 0x20 <= ordC <= 0x25 or 0x27 <= ordC <= 0x7e:
            doB64(_in, r)
            r.append(c)
        elif c == '&':
            doB64(_in, r)
            r.append('&-')
        else:
            _in.append(c)
    doB64(_in, r)
    return (str(''.join(r)), len(s))


# decoding

def modified_unbase64(s):
    b = binascii.a2b_base64(s.replace(',', '/') + '===')
    return unicode(b, 'utf-16be')


def decoder(s):
    r = []
    decode = []
    for c in s:
        if c == '&' and not decode:
            decode.append('&')
        elif c == '-' and decode:
            if len(decode) == 1:
                r.append('&')
            else:
                r.append(modified_unbase64(''.join(decode[1:])))
            decode = []
        elif decode:
            decode.append(c)
        else:
            r.append(c)
    if decode:
        r.append(modified_unbase64(''.join(decode[1:])))
    bin_str = ''.join(r)
    return (bin_str, len(s))


class StreamReader(codecs.StreamReader):
    def decode(self, s, errors='strict'):
        return decoder(s)


class StreamWriter(codecs.StreamWriter):
    def decode(self, s, errors='strict'):
        return encoder(s)


def imap4_utf_7(name):
    if name == 'imap4-utf-7':
        return (encoder, decoder, StreamReader, StreamWriter)
codecs.register(imap4_utf_7)

#http://lists.alioth.debian.org/pipermail/offlineimap-project/2011-March/001431.html
import os

def getnetrc(authinfo=None, **match):
    '''A dumb filter for ~/.netrc. It understands oneline entries,
    comments and default entry. No macros or multiline entries.

    Return first matching dict or None.'''
    default = None
    if not authinfo:
        authinfo = os.getenv('NETRC') or '~/.netrc'

    for li in open(os.path.expanduser(authinfo)).readlines():
        li = li.partition('#')[0].split() # current line in list
        if not li:
            continue
        if li[0] == 'default':
            default = dict(zip(li[1:-1:2], li[2::2]))
            continue
        elif li[0] == 'macdef':
            continue

        li = dict(zip(li[:-1:2], li[1::2])) # current line in dict

        if match and contains(li, match):
            return li

    if default and contains(default, match):
        return default

def contains(d, m):
    '''Return True if d contains all items of m.'''
    for k in m:
        if not k in d or d[k] != m[k]:
            return False
    return True

# debug
if __name__ == "__main__":
    print getnetrc(machine='imap.gmail.com', login='foo')
    print "&V4NXPpCuTvY-" + "&V4NXPpCuTvY-".decode('imap4-utf-7').encode('utf-8')
    print "&XfJSIJZk-" + "&XfJSIJZk-".decode('imap4-utf-7').encode('utf-8')
    print "&XfJT0ZAB-" + "&XfJT0ZAB-".decode('imap4-utf-7').encode('utf-8')
    print "&g0l6P3ux-" + "&g0l6P3ux-".decode('imap4-utf-7').encode('utf-8')
    print "&i6KWBZCuTvY-" + "&i6KWBZCuTvY-".decode('imap4-utf-7').encode('utf-8')

这边贴 一点吧。inbox 路径好像没有关系。 IMAPStore gmail-remote


MaildirStore gmail-local
Path /Users/Shared/mail/Declan/
Inbox /Users/Shared/mail/Declan/INBOX/

Channel gmail-inbox
Master :gmail-remote:
Slave :gmail-local:
Patterns "INBOX"
Create Both
Expunge Both
SyncState *

Channel gmail-trash
Master :gmail-remote:"[Gmail]/Trash"
Slave :gmail-local:"Trash"
Create Both
Expunge Both
SyncState *

Channel gmail-sent
Master :gmail-remote:"[Gmail]/Sent Mail"
Slave :gmail-local:"Sent"
Create Both
Expunge Both
SyncState *

Channel gmail-drafts
Master :gmail-remote:"[Gmail]/Drafts"
Slave :gmail-local:"Drafts"
Create Both
Expunge Both
SyncState *

Channel gmail-spam
Master :gmail-remote:"[Gmail]/Spam"
Slave :gmail-local:"Spam"
Create Both
Expunge Both
SyncState *

Channel gmail-important
Master :gmail-remote:"[Gmail]/Important"
Slave :gmail-local:"Important"
Create Both
Expunge Both
SyncState *

Channel gmail-all
Master :gmail-remote:"[Gmail]/All Mail"
Slave :gmail-local:"Archive"
Create Both
Expunge Both
SyncState *

Channel gmail-starred
Master :gmail-remote:"[Gmail]/Starred"
Slave :gmail-local:"Starred"
Create Both
Expunge Both
SyncState *

如果不在意本地文件夹名的话可以用

IMAPStore 163-remote
Account 163

MaildirStore 163-local
# The trailing "/" is important
Path ~/Maildir/Netease/
Inbox ~/Maildir/Netease/Inbox

Channel 163-default
Master :163-remote:
Slave :163-local:
Patterns *
Create Both 
SyncState  *

整个同步过来。因为中文用的是utf-7. 所以会显示 &i6KWBZCuTvY- 这样的东西。mbsync 作者没有支持 utf7 的打算。这个可以在mailist 里面搜到。

1 个赞

按这样的设置,hotmail和qq没问题,但是163/126邮箱只会在本地建一些文件夹,但是不会同步邮件,翻了下mailing list,也没发现什么解决办法。

网易需要在网页版设置里面开客户端授权密码。

已经开启了,用mew和其他的客户端都可以imap收件,但是mu4e不行。

mu4e不负责收邮件

说错,mbsync

推一下我之前写的博客, 关于mu4e的配置

http://lengyueyang.github.io/2017/02/26/Use%20Mu4e%20to%20manage%20email/

1 个赞

ThunderBird 占用内存太多了

碰到了同样的问题。mbsync能连接服务器,也不报错,但就是不能同步邮件,建的文件夹都是空的。不知现在有解决办法吗?

没解决,结果就是用offlineimap收126/163,用mbsync收其他邮箱。设置mu4e-get-mail-command为"mbsync -a; offlineimap"

1 个赞

昨天翻到的,这个问题在1.3版本解决了: Isync / Bugs / #26 UID FETCH fails to fetch message 你可以试一下。

这么说,用mbsync的话,只好把邮箱全部改成英文的?