##language:zh #pragma section-numbers on ''' 45分钟!给gmailfs添加中文文件名支持 ''' ::-- ZoomQuiet [<<DateTime(2007-03-24T08:41:01Z)>>] <<TableOfContents>> ## 默许导航,请保留 <<Include(CPUGnav)>> = vcc.给gmailfs添加中文文件名支持 = 最近把工作基本都转到了Ubuntu下面,程序员还是用*nix最方便啊,支持多多。想 用gmailfs把一些东西备份到gmail里去,反正google这么慷慨的提供了这么好的服 务,不用白不用;-) ubuntu安装软件那个是爽,sudo apt-get instal gmailfs就搞定了,看了一下说 明,配了gmailfs.conf,开始mount,cp....,ls,直接出错,中文文件名不支 持!怎么办?马上去gmailfs作者的主页看看。有一个0.7.3版本发布,有一个 bugfix “The failure to handle some text encoding for non-English languages“。OK, 下载下来换上一试,还是不行。怎么办?没办法了,只好打开 编辑器,看看代码了。 先在出错代码处加上log.debug:{{{#!python def getdir(self, path): # ..... for thread in folder: assert len(thread) == 1 for msg in thread: log.debug("thread.summary is " + thread.snippet) m = re.search(FileNameTag+'='+FileStartDelim+'(.*)'+ FileEndDelim, thread.snippet) if (m): # Match succeeded, we got the whole filename. log.debug("Used summary for filename") filename = m.group(1) else: # Filename was too long, have to fetch message. log.debug("Long filename, had to fetch message") body = fixQuotedPrintable(msg.source) log.debug('body='+body+' '+ FileNameTag+'='+FileStartDelim+'(.*)'+FileEndDelim) #这里加上 m = re.search(FileNameTag+'='+FileStartDelim+'(.*)'+ FileEndDelim, body) filename = m.group(1) #..... }}} 然后把gmailfs.conf的[logs]的level设为debug。 == 原来body是base64编码的 == 再试,哦,原来body是base64编码的,OK,我们来看看fixQuotedPrintable都干了 些什么活:{{{#!python #ubuntu带的0.7.2版的: def fixQuotedPrintable(body): fixed = body if re.search("Content-Transfer-Encoding: quoted",body): fixed = quopri.decodestring(body) # Map unicode return fixed.replace('\u003d','=') #新版0.7.3的: def fixQuotedPrintable(body): # first remove headers newline = body.find("\r\n\r\n") if newline >= 0: body = body[newline:] fixed = body if re.search("Content-Transfer-Encoding: quoted",body): fixed = quopri.decodestring(body) # Map unicode return fixed.replace('\u003d','=') ##注意到没,加了newline。先把base64的decodestring加上, def fixQuotedPrintable(body): # first remove headers newline = body.find("\r\n\r\n") if newline >= 0: body = body[newline:] fixed = body if re.search("Content-Transfer-Encoding: quoted",body): fixed = quopri.decodestring(body) if re.search("Content-Transfer-Encoding: base64",body): fixed = base64.decodestring(body) # Map unicode return fixed.replace('\u003d','=') }}} 加上import base64, 试一下,不行,再仔细看一下代码,哦,看出问题出来了没? 原来他已经先把header去掉了,所以 `re.search("Content-Transfer-Encoding: base64",body)`做的是无用功啊。怎么 改?先保留他的代码,不要动他,加上: {{{#!python def fixQuotedPrintable(body): # first remove headers newline = body.find("\r\n\r\n") body_orig = body # 加一个变量保存有header的body if newline >= 0: body = body[newline:] fixed = body if re.search("Content-Transfer-Encoding: quoted",body_orig): fixed = quopri.decodestring(body) if re.search("Content-Transfer-Encoding: base64",body_orig): fixed = base64.decodestring(body) # Map unicode return fixed.replace('\u003d','=') }}} OK,这下ls不会出错了,大功....,等等,ls出来中文名是乱码啊,哥们,别高兴 得太早;-) == 把charset加上吧 == 没办法,那就把charset加上吧: {{{#!python def fixQuotedPrintable(body): # first remove headers newline = body.find("\r\n\r\n") body_orig = body # check encoding charset_match = re.search("charset=([^;]+)",body_orig) # 这里解析 encoding charset if newline >= 0: body = body[newline:] fixed = body if re.search("Content-Transfer-Encoding: quoted",body_orig): fixed = quopri.decodestring(body) if re.search("Content-Transfer-Encoding: base64",body_orig): fixed = base64.decodestring(body) if charset_match: fixed = unicode(fixed,charset_match.group(1)).encode('utf-8') # Map unicode return fixed.replace('\u003d','=') }}} OK,ls出来正确的文件名,再试试把它cp回来看看, == 找不到inode为XXXXXXXX的数据邮件 == 糟糕,出错,似乎找不到inode为XXXXXXXX的数据邮件,看了一下gmail邮箱,有啊。再仔细看一下他的代 码,没有发现什么问题,难道是“灵异”事件?不会这么好彩吧;-) 多年的编程经验 告诉我,不会有什么邪门的事,一定是事出有因,多半是我自己的问题。我是相信 gmailfs代码的质量,不至于最基本的问题都搞不定,google我也相信不会乱来, 那一定是我的问题了。那我的问题在哪里呢? 仔细看看我的邮箱,search一下,1个2个3个4个,等等,别的英文名文件都是3个,这个为什么是4个,而且有一个内 容里s=0 (s是sizeTag),难怪,干掉这个邮件,再试,终于OK了。 == 附上修改给gmailfs的作者 == 开始cp...., 另发一封简短的邮件附上修改给gmailfs的作者,顺道感谢感谢他^_^ 虽然这是我第一次接触gmailfs,不过读懂代码并不是什么难事,python的代码的 可读性又是特别的好。还在害怕读代码的人们,不要站在岸边看风景,跳进源码的 海洋里游泳吧! 附注:查看发件箱,这是22号晚上的事,今天把它补记下来,也作一点点些微的贡 献吧。另多出一个邮件的无头公案,就交给在座的各位看官,再世的包青天包大 人.....^-^ {{{ vcc _ 都是我的错,让你多一个,不该乱把Ctrl-C拼命的按;-) }}} == 反馈 ==