<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-20394991</id><updated>2008-08-26T11:26:35.067+08:00</updated><title type='text'>懒惰的程序员</title><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>203</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20394991.post-6397529812081140718</id><published>2008-08-26T11:20:00.002+08:00</published><updated>2008-08-26T11:26:35.084+08:00</updated><title type='text'>Greasemonkey script for gitorious</title><content type='html'>&lt;p&gt;gitorious提供了查看文件的功能，但是我发现只有第一层目录下的文件可以看，深层目录下的文件都不能看，会发生404 not found错误。论坛里也有人遇到&lt;a href="http://groups.google.com/group/gitorious/browse_thread/thread/cf66c6605da5be64"&gt;同样的问题&lt;/a&gt;。因为不懂Rails，尝试apache mod_rewrite也以失败告终，没法子，自己写了一个greasemonkey脚本，把链接修改过来。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;// ==UserScript==
// @name           Unescape Slash
// @namespace      http://example.com/projects/
// @include        http://example.com/projects/*
// ==/UserScript==

var allNodeFile, thisNodeFile, a;
allNodeFile = document.getElementsByClassName('node file');
thisNodeFile = 0;
for (var i = 0; i &amp;lt; allNodeFile.length; ++i) {
    thisNodeFile = allNodeFile[i];
    a = thisNodeFile.firstChild;
    a.href = a.href.replace(/%2F/g, '/');
}&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/greasemonkey-script-for-gitorious.html' title='Greasemonkey script for gitorious'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=6397529812081140718' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6397529812081140718'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6397529812081140718'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-2838359455546868624</id><published>2008-08-22T09:57:00.006+08:00</published><updated>2008-08-22T14:44:09.177+08:00</updated><title type='text'>gitorious</title><content type='html'>&lt;p&gt;在领导和乡亲们的大力支持下，我们开始在项目组里推广git，为了方便大家使用，很希望有一个类似&lt;a href="http://github.com"&gt;github&lt;/a&gt;之类的东西，可惜github不是开源软件。后来找到了&lt;a href="http://gitorious.org"&gt;gitorious&lt;/a&gt;，一个基于rails的应用。&lt;/p&gt;&lt;p&gt;以前从没接触过rails，第一次部署rails应用，感觉头很大，gitorious还没有一个详细的部署文档，只好硬着头皮自己来，网上搜索了一大堆资料，最终成功的搭建起来。&lt;/p&gt;&lt;p&gt;首先创建一个用户git，如果选择其它用户名会导致更多步骤来配置gitorious，所以没有特殊原因，尽量使用这个用户名。以下操作均以该用户操作，除非显示地使用了&lt;code&gt;sudo&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;在局域网里搭建gitorious需要安装的软件有apache, mysql, sendmail, ruby, rubygems, imagemagick, sphinx, apg和aspell等应用程序，另外还需要libmagick9-dev, libmysqlclient15-dev, libmysqlclient15off, libonig2, libonig-dev, libaspell-dev等程序库。装好rubygems之后最好更新一下，否则可能&lt;a href="http://ryandaigle.com/articles/2008/5/13/loaded_specs-gem-error"&gt;出现错误&lt;/a&gt;，方法是：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ sudo gem update --system&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;现在可以安装所有需要的gem了，&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ sudo gem install rake rails BlueCloth mime-types oniguruma textpow chronic rmagick ruby-openid mysql raspell ultrasphinx ruby-yadis mongrel mongrel_cluster&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;接下来将&lt;code&gt;gitorious/config&lt;/code&gt;下面的gitorious.sample.yml和database.sample.yml分别复制一份，名字改为gitorious.yml和database.yml。然后运行&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ apg -m 64&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;随便选择一行输出，替换掉gitorious.yml文件的cookie_secret字段的值。这一步一定要做，否则会出现500错误。如果想用sendmail发邮件，在&lt;code&gt;config/environments/production.rb&lt;/code&gt;文件里添加一行&lt;code&gt;config.action_mailer.delivery_method = :sendmail&lt;/code&gt;。接下来创建数据库，&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ mysql -u root
&amp;gt; create database gitorious_production;
&amp;gt; exit&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;接下来创建需要的表&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;rake db:migrate RAILS_ENV=production&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;如果找不到rake的话可以试试&lt;kbd&gt;ruby /var/lib/gems/1.8/gems/rake-0.8.1/bin/rake&lt;/kbd&gt;。这时如果出现&lt;a href="http://www.ghostonthird.com/2007/12/19/merb-on-cygwin-no-such-file-or-directory-tmpmysqlsock-resolved/"&gt;找不到&lt;code&gt;/tmp/mysql.sock&lt;/code&gt;错误&lt;/a&gt;，把database.yml文件里面的localhost换成127.0.0.1。然后运行&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ ./script/server -e production&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;当server起来之后，尝试访问http://0.0.0.0:3000/，如果成功看到首页，那么就成功了。按&lt;kbd&gt;CTRL+C&lt;/kbd&gt;退出。&lt;/p&gt;&lt;p&gt;下面添加搜索功能，&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ cp vendor/plugins/ultrasphinx/examples/default.base config/ultrasphinx/&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;然后把default.base里面的path改为&lt;code&gt;#{RAILS_ROOT}/db/sphinx/&lt;/code&gt;，把&lt;code&gt;vendor/plugins/ultrasphinx/tasks/ultrasphinx.base&lt;/code&gt;文件里面包围&lt;code&gt;#{Ultrasphinx::CONF_PATH}&lt;/code&gt;的单引号去掉，一共三处。再运行&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ rake ultrasphinx:configure RAILS_ENV=production
$ rake ultrasphinx:index RAILS_ENV=production
$ rake ultrasphinx:daemon:start RAILS_ENV=production&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;重新启动server，搜索功能就在了。注册一个帐号，收到激活邮件，激活帐号，成功。&lt;/p&gt;&lt;p&gt;不过如果真想让gitorious干活的话还要配置两个cron job&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ mkdir /path/to/gitorious/public/images/graphs
$ crontab -e&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;内容为：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;*/5 * * * * /path/to/gitorious/script/task_performer
*/17 * * * * /path/to/gitorious/script/graph_generator&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;时间长短随意定，我选择5分钟运行一次&lt;code&gt;task_performer&lt;/code&gt;，另外还要做的一件事是&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ sudo ln -s /path/to/gitorious/script/gitorious /bin/gitorious&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;但是，如果想给其他人使用的话，http://0.0.0.0:3000/这样的东西是拿不出手的，为此我们需要使用apache做一个reverse proxy server。首先打开mod_proxy，&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ sudo a2enmod proxy_http&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;然后添加一个配置文件gitorious.conf&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;IfModule mod_proxy.c&amp;gt;
    ProxyRequests Off

    &amp;lt;Proxy *&amp;gt;
        Order deny,allow
        Allow from all
    &amp;lt;/Proxy&amp;gt;

    ProxyPass / http://0.0.0.0:3000/
    ProxyPassReverse / http://0.0.0.0:3000/
&amp;lt;/IfModule&amp;gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;重启apache，用域名访问，如http://example.com/，如果发现没有css和image，确认一下gitorious.conf里面的http://0.0.0.0:3000/结尾的"&lt;strong&gt;/&lt;/strong&gt;"是否在，没有的话，加上它。重启apache再试一下。&lt;/p&gt;&lt;p&gt;最后还需要一点配置，使用户可以做&lt;kbd&gt;git clone&lt;/kbd&gt;。启动git-daemon，&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ ./script/git-daemon&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;这样用户就可以使用&lt;kbd&gt;git clone git://...&lt;/kbd&gt;了，为了能够通过http方式clone，还要配置二级域名，如http://git.example.com，指向&lt;code&gt;#{repository_base_path}&lt;/code&gt;所在的路径，也可以使用http://example.com/git/的方式，但是要修改&lt;code&gt;app/models/repository.rb:69&lt;/code&gt;和&lt;code&gt;spec/models/repository_spec.rb:75&lt;/code&gt;&lt;/p&gt;&lt;p&gt;如果使用gitorious的人比较多的话可以配置mongrel cluster，具体参见&lt;a href="http://www.douban.com/subject/2372282/"&gt;Deploying Rails Applications&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;部分参考资料：&lt;ul&gt;&lt;li&gt;&lt;a href="http://erikonrails.wordpress.com/2008/05/11/how-to-get-gitorious-running-on-your-own-server/"&gt;How to get Gitorious running on your own server&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.coreworks.be/2008/5/15/git-gitorious-ubuntu"&gt;git + gitorious ubuntu&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.cordinc.com/blog/2008/03/installing-sphinx-ultrasphinx.html"&gt;Installing Sphinx &amp; Ultrasphinx on Windows&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/gitorious.html' title='gitorious'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=2838359455546868624' title='2 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2838359455546868624'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2838359455546868624'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-6987343183217945976</id><published>2008-08-18T14:57:00.002+08:00</published><updated>2008-08-18T15:04:26.732+08:00</updated><title type='text'>Upgrade n800 to diablo</title><content type='html'>&lt;p&gt;Nokia N800上最新的系统是diablo，和著名的blizzard公司的游戏同名。升级需要reflash，无法在线升级，不过升级到diablo之后就可以在线升级了，无需每次reflash。&lt;/p&gt;&lt;p&gt;升级之前想着要备份，但是想当然的以为备份是在PC上的Nokia软件里，结果没有备份。:-(&lt;/p&gt;&lt;p&gt;实际上，备份是在N800里面，结果周末花了很多时间重新安装配置软件。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/upgrade-n800-to-diablo.html' title='Upgrade n800 to diablo'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=6987343183217945976' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6987343183217945976'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6987343183217945976'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-902561281454019487</id><published>2008-08-14T13:33:00.002+08:00</published><updated>2008-08-14T13:44:50.471+08:00</updated><title type='text'>Interactive git rebase</title><content type='html'>&lt;p&gt;胆战心惊地尝试了一把&lt;kbd&gt;git rebase --interactive&lt;/kbd&gt;，把以前的commit message修改了一下。一直习惯用&lt;kbd&gt;-m&lt;/kbd&gt;直接在命令行上写commit message，但是在git上有个小小的问题，就是用&lt;kbd&gt;git log&lt;/kbd&gt;看的时候并不会自动换行，所以使用emacs的fill功能（&lt;kbd&gt;M-q&lt;/kbd&gt;）美化一下格式，然后再提交。&lt;/p&gt;&lt;p&gt;当然，出了修改commit message、author之外，&lt;kbd&gt;git rebase --interactive&lt;/kbd&gt;还可以做很多更夸张的事。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/interactive-git-rebase.html' title='Interactive git rebase'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=902561281454019487' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/902561281454019487'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/902561281454019487'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-6528259256410101666</id><published>2008-08-10T16:08:00.002+08:00</published><updated>2008-08-10T16:11:53.404+08:00</updated><title type='text'>Google doc</title><content type='html'>&lt;p&gt;前两天发现我从Google doc上发布的帖子被屏蔽了，幸好Google绝大多数服务都支持https连接。所以如果出现链接被重置的情况，不妨试一下https。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/google-doc.html' title='Google doc'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=6528259256410101666' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6528259256410101666'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6528259256410101666'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-54181861533328353</id><published>2008-08-06T12:56:00.002+08:00</published><updated>2008-08-06T13:10:03.812+08:00</updated><title type='text'>Programming makes me happy</title><content type='html'>&lt;p&gt;一段漫长的低迷期总算过去了，自从能够静下心来看程序，心情便好起来了。同样的环境，同样的代码，不一样的心情，由消极变积极之后，不再有世界末日来临的感觉。当然，坏消息也有，老板离职了，因为个人原因回Intel工作。说起来我们组也很有意思，就像一个栈，先来的人压在下面，离职的时候后来的人先出栈，看看现在周围这几个人，仿彿又回到了几年前……&lt;/p&gt;&lt;p&gt;看别人写的代码有点抵触情绪，觉得很麻烦，不如索性自己重新写一个，当然如果是很大的程序没法重写，就拖着，能不看就不看。直到有一天拖不下去了，硬着头皮看下去，发现也还看得懂。&lt;/p&gt;&lt;p&gt;写程序能让我心情好起来，但是好像已经很久没有写了。应该养成个习惯，没事写两笔，就像写blog一样，即使只是为了心理健康。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/programming-makes-me-happy.html' title='Programming makes me happy'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=54181861533328353' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/54181861533328353'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/54181861533328353'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-2791522805922416798</id><published>2008-08-04T10:22:00.002+08:00</published><updated>2008-08-04T10:31:45.164+08:00</updated><title type='text'>filecache</title><content type='html'>&lt;p&gt;看同事使用source insight，只需输入文件名，source insight便可以找到并显示这个文件。看了sacha的&lt;a href="http://sachachua.com/wp/2008/07/27/eclipse-to-emacs-navigating-your-source-tree/"&gt;Eclipse to Emacs: Navigating your source tree&lt;/a&gt;才知道在Emacs里面可以使用filecache达到相同的效果，如果搭配上ido，还会更加强大。也许是时候从iswitchb转到ido了。&lt;/p&gt;&lt;p&gt;下面是我的配置（忽略git相关目录及文件）：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(require 'filecache)
(add-to-list 'file-cache-filter-regexps "\\.git\\&gt;")
(file-cache-add-directory-recursively "/path/to/project")&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;code&gt;filecache&lt;/code&gt;没有文档，只能看源文件头上的注释，不过已经足够了，本来也不是很复杂的东西。使用时有一个小窍门，在使用&lt;kbd&gt;C-x C-f&lt;/kbd&gt;打开文件时，不用管前面的目录名是什么，直接在后面输入文件名，然后用&lt;kbd&gt;C-TAB&lt;/kbd&gt;补全，目录名会自动被替换，无需手工删除。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/08/filecache.html' title='filecache'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=2791522805922416798' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2791522805922416798'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2791522805922416798'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-3692365158984805738</id><published>2008-07-29T16:29:00.005+08:00</published><updated>2008-08-08T14:43:26.061+08:00</updated><title type='text'>Convert video for mobile device with mencoder</title><content type='html'>&lt;p&gt;在同事的帮助下，学会了两条命令，用mencoder为我的Nokia N800和blackberry 8320转换视频格式。mencoder是mplayer的一个副产品，凡是能用mplayer播放的视频，就能用mencoder转换。&lt;/p&gt;&lt;p&gt;为Nokia N800转换视频的命令：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ mencoder -sub 1.srt -font /usr/share/fonts/truetype/arphic/gbsn00lp.ttf 1.avi -subcp cp936 -subfont-text-scale 3 -o 2.avi -vf-add scale=400:240 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=240 -ffourcc DX50 -oac mp3lame -lameopts vol=10&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;为blackberry 8320转换视频的命令：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ mencoder 1.avi -o 2.avi -vf-add scale=320:240 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=600 -oac mp3lame -lameopts vol=10&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/convert-video-for-mobile-device-with.html' title='Convert video for mobile device with mencoder'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=3692365158984805738' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3692365158984805738'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3692365158984805738'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-3662008531348571906</id><published>2008-07-28T11:24:00.002+08:00</published><updated>2008-07-28T11:52:50.467+08:00</updated><title type='text'>My blackberry story</title><content type='html'>&lt;p&gt;上周四收到快递送来的blackberry 8320，开始了我的黑莓时代。&lt;/p&gt;&lt;p&gt;说起黑莓，和我还真有那么一点渊源。最开始还是在Intel的时候，Intel与RIM签了1亿美元的订单，开始使用我们的部件和编译器。当初还想着1亿美元总够我们这些人吃一阵子的，没想到被卖给Marvell，RIM虽说一百个不乐意，也没法子，只好继续使用我们的产品。像新一代的83和88系列，应该就包含我们的硬件，其中的部分程序，就是用我参与开发的编译器编译出来的。&lt;/p&gt;&lt;p&gt;刚开始使用黑莓很不习惯，跟我的Moto E398很不一样，经过几天的高强度试用，现在熟练多了，还发现了一些贴心的小功能。当然，不符合中国人操作习惯的地方也有，只是没有缺点的产品是不存在的，关键还是个人喜好。我选择手机的标准就比较庸俗，要么大屏幕触摸屏，要么全键盘。&lt;/p&gt;&lt;p&gt;我前前后后一共用过一个小灵通和三个手机，8320是唯一超过2千元的，算是赶个时髦，除此之外，我还有一个Nokia N800，这里有几张图，大家可以比较一下大小，反正我拿到8320的时候，感觉比我想象的要小的多。点击下图可以看到更多照片。&lt;/p&gt;&lt;p&gt;&lt;table style="width:194px;"&gt;&lt;tr&gt;&lt;td align="center" style="height:194px;background:url(http://picasaweb.google.com/f/img/transparent_album_background.gif) no-repeat left"&gt;&lt;a href="http://picasaweb.google.com/netcasper/lDpln"&gt;&lt;img src="http://lh6.ggpht.com/netcasper/SIxj7N1KpYE/AAAAAAAAAhk/Vo-FUTMgV_Q/s160-c/lDpln.jpg" width="160" height="160" style="margin:1px 0 0 4px;"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align:center;font-family:arial,sans-serif;font-size:11px"&gt;&lt;a href="http://picasaweb.google.com/netcasper/lDpln" style="color:#4D4D4D;font-weight:bold;text-decoration:none;"&gt;数码设备&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/my-blackberry-story.html' title='My blackberry story'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=3662008531348571906' title='6 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3662008531348571906'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3662008531348571906'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-3627633466170164651</id><published>2008-07-17T11:18:00.002+08:00</published><updated>2008-07-17T11:58:56.421+08:00</updated><title type='text'>Tomorrow never dies</title><content type='html'>&lt;p&gt;仿彿又回到了&lt;a href="http://www.wanglianghome.org/blog/2006/08/secure-your-job.html"&gt;2006年&lt;/a&gt;，流言纷飞，人心思动。&lt;/p&gt;&lt;p&gt;我们组向来十分稳定，居然在今年上半年有2人离职，虽说各有各的原因，但是对其他人的震动还是不可忽视的。自从年初停了前一个产品，兵分两路开始两个新产品以来，工作中一直弥漫着一种不正常的气氛，就好像我在情绪低潮时的那种狂躁的感觉，这一次却是以一种集体的形式爆发出来。&lt;/p&gt;&lt;p&gt;俗话说“人比人得死，货比货得扔”。如今才知道，原来我们前一个产品的代码质量还是相当不错的，即使我们曾对它有这样那样的不满；原来我们前一个产品的客户是如此的专业，尽管他们也提过不少苛刻的需求。说句心里话，我们组接了一个烂摊子，想知道有多烂吗？一位刚刚离职的同事，在离职前花了近两个月时间看代码，居然发现了十多个bug。请注意，他只是坐在那里用眼睛盯着屏幕，甚至都没有编译、更没有测试，这在我们前一个产品上绝对是不可想象的。&lt;/p&gt;&lt;p&gt;更不可想象的是，我们居然被要求放弃在高质量的代码上做开发，转而去收拾一个烂摊子。当然了，不是每个人都觉得它烂，那可是从Intel买来的啊？！想必是个宝贝吧，毕竟是花了不少人力，开发了几年时光啊！&lt;/p&gt;&lt;p&gt;在硬件公司（无论是Intel还是Marvell）里开发软件真得很辛苦，在一个人人都用git的年代，我们还在用ClearCase。管中窥豹，可见一斑。外行指挥内行，拍脑袋做决定的现象屡见不鲜。想当年在Intel的时候不是也有过Zero Bug这样轰轰烈烈的、自上而下的运动嘛！&lt;/p&gt;&lt;p&gt;眼看在Marvell的两年时间就要到了，恐怕那时会有更多的变动吧。山雨欲来风满楼啊！&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/tomorrow-never-dies.html' title='Tomorrow never dies'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=3627633466170164651' title='4 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3627633466170164651'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3627633466170164651'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-4292999176292124704</id><published>2008-07-16T10:38:00.002+08:00</published><updated>2008-07-16T10:52:24.535+08:00</updated><title type='text'>Skip big attachment</title><content type='html'>&lt;p&gt;用offlineimap备份gmail邮件时碰到一个问题，我有两个很大的邮件，里面是一些照片，大概在16M左右，offlineimap在下载的时候会崩溃，然后打印一堆backtrace。&lt;/p&gt;&lt;p&gt;我一不懂python二不懂imap，更没读过offlineimap的源代码，但还是仗着胆子改了改，让offlineimap在同步的时候忽略太大（10M）的邮件。有同样需求的可以参见我的&lt;a href="http://www.wanglianghome.org/cgi-bin/wiki.cgi/OfflineimapSkipBigAttachment"&gt;offlineimap patch to skip big attachment&lt;/a&gt;，点击wiki页面上的链接以下载patch，这个patch是用&lt;kbd&gt;git format-patch&lt;/kbd&gt;生成的。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/skip-big-attachment.html' title='Skip big attachment'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=4292999176292124704' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4292999176292124704'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4292999176292124704'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-6926446797194579676</id><published>2008-07-09T09:48:00.002+08:00</published><updated>2008-07-09T09:57:32.740+08:00</updated><title type='text'>The third dell machine</title><content type='html'>&lt;p&gt;第三次买Dell台式机，一时没想开，选了19吋宽屏显示器，没有升级到22吋的，结果发现既不能调节高度，也没有额外的USB口。上Dell的网站查了一下，多数显示器都不能调节高度，除了Ultra Sharp系列，但是在台式机配置里面基本看不到。&lt;/p&gt;&lt;p&gt;另一个弱项是只有4个USB口，且都在机箱后面，其中3个已经用掉，分别是鼠标、键盘和音箱。&lt;/p&gt;&lt;p&gt;优点是噪声很小，不仔细听根本听不到，比前面买的都要安静。&lt;/p&gt;&lt;p&gt;唯一的遗憾是这台电脑不是买给自己用的。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/third-dell-machine.html' title='The third dell machine'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=6926446797194579676' title='1 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6926446797194579676'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6926446797194579676'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-200530198380669696</id><published>2008-07-03T13:37:00.002+08:00</published><updated>2008-07-03T13:41:32.976+08:00</updated><title type='text'>Are these exceptions same thing?</title><content type='html'>&lt;p&gt;Exception在C++/Java世界里似乎是个很不受欢迎的东西，没有认真去读这篇&lt;a href="http://www.ckwop.me.uk/Why-Exceptions-Suck.html"&gt;Why Exceptions Suck&lt;/a&gt;，只是感到很奇怪，在Perl和Lisp里面应用很广泛啊？！难道它们在理念上不是类似的吗？！&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/are-these-exceptions-same-thing.html' title='Are these exceptions same thing?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=200530198380669696' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/200530198380669696'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/200530198380669696'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-4041270885001374330</id><published>2008-07-02T12:25:00.002+08:00</published><updated>2008-07-02T12:53:19.041+08:00</updated><title type='text'>machine learning based research compiler</title><content type='html'>&lt;p&gt;&lt;a href="http://money.cnn.com/news/newsfeeds/articles/marketwire/0411688.htm"&gt;将机器学习引入编译领域&lt;/a&gt;是一个很令人兴奋的消息，然而更令人激动的是，你可以这样做，而无需自己写一个编译器。&lt;/p&gt;&lt;p&gt;&lt;a href="http://unidapt.org/software.html#milepostgcc"&gt;Milepost&lt;/a&gt;是一个基于GCC的研究项目，它利用机器学习可以在短时间内将编译器的优化能力提升到一个新的层次。&lt;/p&gt;&lt;blockquote&gt;Within one month, Milepost was able to improve the performance of a state-of-the-art complier by 10 percent -- something that would normally take several years to accomplish.&lt;/blockquote&gt;&lt;p&gt;如果该研究成果获得实际应用，那么像我这样的编译器程序员很可能将失业，不再是“机器吃人”，而是“程序吃人”。&lt;/p&gt;&lt;p&gt;越来越厌倦开发商业软件，继续下去，注定要被某种程序吃掉。很羡慕做这个项目的那些人，如果他们的研究成功了，那么他们的成果可以被千千万万的程序员利用，而做到这些，（相对来说）只需要很少的编译知识，更不用自己去实现一个编译器；即使他们的研究不能得到实际应用，他们也没有把时间浪费在一些不相关的、或者不感兴趣的事情上面。&lt;/p&gt;&lt;p&gt;要不怎么人常说：“要做大事，必须要学会借助他人的力量”。一个人的力量是非常有限的，七八条枪就想维护两三套SDK，还想做的好，让人家都来用，简直是痴人说梦。不拥抱开源，只有死路一条。&lt;/p&gt;&lt;p&gt;程序员的黄金时光，就像女人的青春，是浪费不起的，不要让他们做垃圾项目的殉葬品。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/07/machine-learning-based-research.html' title='machine learning based research compiler'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=4041270885001374330' title='1 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4041270885001374330'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4041270885001374330'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-3478544474965861479</id><published>2008-06-25T16:56:00.002+08:00</published><updated>2008-06-25T17:03:35.676+08:00</updated><title type='text'>rgrep</title><content type='html'>&lt;p&gt;原来都是使用&lt;code&gt;find-grep&lt;/code&gt;在emacs里面搜索文件，但是每次都要手工修改&lt;code&gt;find-grep&lt;/code&gt;的命令来过滤&lt;code&gt;.svn&lt;/code&gt;这样的目录。其实很想使用ack，可惜它的输出格式与grep不一样。&lt;/p&gt;&lt;p&gt;翻看emacs文档的时候发现了&lt;code&gt;rgrep&lt;/code&gt;，它在搜索时会略过用于版本控制的目录，但在使用方式上也与&lt;code&gt;find-grep&lt;/code&gt;有些不同，需要习惯一下。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/rgrep.html' title='rgrep'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=3478544474965861479' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3478544474965861479'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/3478544474965861479'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-6018324581487322518</id><published>2008-06-18T11:14:00.002+08:00</published><updated>2008-06-18T11:35:48.533+08:00</updated><title type='text'>Watching Google I/O</title><content type='html'>&lt;p&gt;这两天一直在看Google I/O会议的视频，由于这些视频都比较大，一般在100M以上，所以都是先用Firefox的插件&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3006"&gt;Video DownloadHelper&lt;/a&gt;下载到本地，然后用vlc观看。&lt;/p&gt;&lt;p&gt;先后看了Maile Ohye的Search Friendly Development，Chris DiBona（这哥们讲话真快）的Open Source is Magic，Steve Yegge的Server-side JavaScript on the Java Virtual Machine，以及Marissa Mayer的Keynote。还有几个已经下载，准备在今后几天观看。&lt;/p&gt;&lt;p&gt;从视频内容本身获得的收获就不说了，单单是这种把会议做成视频放在YouTube上让大家免费观看的方式就让我唏嘘不已。闭门造车是要不得的，要走出去，把自己的东西讲给别人听、听别人讲他们的东西，相互了解、相互启发，这对于一个程序员来说是非常重要的。然而由于各种各样的原因，有些地方我们去不了，有些时间我们挤不开。幸好还有Google想到了我们，不仅是这次会议的视频可以在YouTube上找到，我们还可以找到很多Google举办的内部讲座，比如Linus Torvalds on git等等，都是非常值得一看的。&lt;/p&gt;&lt;p&gt;我相信很多技术公司也举办过类似的会议，我甚至看过Ballmer先生怒吼着Developers! Developers! Developers!的视频，然而，仅此而已。以人为本，不仅要放在嘴上，而且要放在心里，还要有行动。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/watching-google-io.html' title='Watching Google I/O'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=6018324581487322518' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6018324581487322518'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/6018324581487322518'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-8859755862280257567</id><published>2008-06-16T14:45:00.004+08:00</published><updated>2008-06-16T15:15:15.553+08:00</updated><title type='text'>SELinux</title><content type='html'>&lt;p&gt;SELinux是Security Enhanced Linux的缩写。望文生义的时候还以为是关于黑客啊、攻击啊、漏洞啊之类的事情，这两天在读《&lt;a href="http://www.douban.com/subject/2607577/"&gt;SELinux by example&lt;/a&gt;》的时候才明白，原来这个东东竟然是用来对付程序员的，准确的说，是为了防止由于程序员的疏忽或错误对系统造成不可预料的伤害。&lt;/p&gt;&lt;p&gt;书中的例子是关于文件&lt;code&gt;/etc/passwd&lt;/code&gt;，碰巧同时在读的《&lt;a href="http://www.douban.com/subject/2076724/"&gt;Mastering Perl&lt;/a&gt;》的第三章Secure Programming Techniques中也用这个文件举例。后者主要是说明处理外部数据时要格外当心，否则可能导致泄露系统信息。然而，要求每个程序员在写程序的时候都要打起120分的精力来注意安全问题是不现实的，总有这样那样的原因导致安全问题被有意无意的忽略。而且，与其让每个程序单独的考虑安全问题，不如将其放在一个集中的地方，就如同SELinux那样，使用各种规则来保证每个程序只能访问特定的系统资源，以及每种系统资源只能被特定的程序访问。&lt;/p&gt;&lt;p&gt;通俗地讲，即使某些应用程序在运行时被提升为具有root权限以访问某些系统资源，但是由于SELinux的存在，一个具有root权限的程序也不意味着它可以访问任何系统资源，相反，它只能访问那些被SELinux规则允许的系统资源，这样就避免了由于程序员的疏忽或错误而对系统造成伤害。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/selinux.html' title='SELinux'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=8859755862280257567' title='2 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/8859755862280257567'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/8859755862280257567'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-7345730788162978311</id><published>2008-06-11T10:54:00.003+08:00</published><updated>2008-06-11T14:03:59.941+08:00</updated><title type='text'>2008 resolution revisited</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;上半年在技术、生活上有所收获，在工作、投资和开源上基本没有进展。&lt;/p&gt;&lt;p&gt;技术上，通过编写一个小的webapp，开始接触Catalyst, DBIx::Class以及SQLite。在那之后还用DBIx::Class和SQLite写了一个小程序来备份del.icio.us的收藏。写了一个Emacs major mode，学会了高亮显示、隐藏文本、调用ediff、使用narrow等等，为了测试，还写了一个unit test framework。开始频繁使用virtualbox。git成为日常使用的版本控制工具。&lt;/p&gt;&lt;p&gt;老婆怀孕了，所以下半年的第一要务是照顾好孕妇，其它的事情不求有功但求无过。&lt;/p&gt;&lt;/div&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/2008-resolution-revisited.html' title='2008 resolution revisited'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=7345730788162978311' title='3 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7345730788162978311'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7345730788162978311'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-7525928328115854342</id><published>2008-06-04T16:37:00.001+08:00</published><updated>2008-06-04T16:37:43.543+08:00</updated><title type='text'>Backup gmail with offlineimap</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;一直使用POP3方式备份Gmail，前一段突然出了问题，总是那拿不到最近几天的邮件，十分郁闷。昨天在弄mutt，突然想到可以用offlineimap来备份gmail，通过IMAP协议，而不是POP。以前读过这样的blog，所以有点印象。&lt;/p&gt;&lt;p&gt;IMAP的优势在于很多操作都是在服务器上，省去了同步的烦恼，然而必须在线的要求实在太苛刻，这有点像版本控制工具的发展，git等分布式版本控制工具的出现，部分原因就是为了在离线的状态下也可以进行操作，方法是在本地复制一个repository。IMAP也有类似的机制，方法是在本地建一个IMAP服务器，然后用同步工具把邮件从远端的IMAP服务器搬到自己的IMAP服务器上，offlineimap就是这样的工具。&lt;/p&gt;&lt;p&gt;在备份gmail的过程中offlineimap偶尔会崩溃，导致我一晚上只备份了5000多份邮件，稍微有点郁闷。&lt;/p&gt;&lt;/div&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/backup-gmail-with-offlineimap.html' title='Backup gmail with offlineimap'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=7525928328115854342' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7525928328115854342'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7525928328115854342'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-7603329952083770835</id><published>2008-06-03T13:16:00.001+08:00</published><updated>2008-06-03T13:16:01.033+08:00</updated><title type='text'>Searching Mail</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;读了sacha的&lt;a href='http://sachachua.com/wp/2008/05/31/emacs-gnus-searching-mail/'&gt;Searching Mail&lt;/a&gt;之后非常兴奋，下载了nnir和imap，然而在我的IMAP server上尝试失败，搜索结果总是返回空。无助之际，想到了&lt;a href='http://www.mutt.org/'&gt;mutt&lt;/a&gt;，在以前学习的基础上稍加调整，就可以用了，搜索功能用起来很爽。唯一的问题是在Ubuntu上如果从GNU Screen里面打开mutt，会花屏，用mcabber上gtalk也有类似的问题。在Fedora 8和9上都没有问题。&lt;/p&gt;&lt;p&gt;这时候Virtualbox就排派上用场了。装上Fedora 9，做了port forwarding，这样就可以通过ssh连进去。然后启动GNU Screen，并在里面开一个mutt（顺便把mcabber也搬进去了）。&lt;/p&gt;&lt;p&gt;看起来有点复杂，其实很多步骤都是以前做好的，比如mutt的设置，虚拟机的安装，port forwarding的设置等等，一点一点的积累，最终就变成完整的解决方案。&lt;/p&gt;&lt;/div&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/06/searching-mail.html' title='Searching Mail'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=7603329952083770835' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7603329952083770835'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7603329952083770835'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-2919070054933511329</id><published>2008-05-21T14:38:00.003+08:00</published><updated>2008-05-21T14:51:37.633+08:00</updated><title type='text'>Plug your own filter into Catalyst</title><content type='html'>&lt;p&gt;&lt;code&gt;Template::Manual::Filters&lt;/code&gt;里面提供了好多很好用的filter，当它们不够用的时候，还可以提供自己写的filter函数。但是怎么告诉Catalyst呢？没有找到文档，只好又去看代码。方法是在&lt;code&gt;MyApp.pm&lt;/code&gt;里面&lt;code&gt;__PACKAGE__-&gt;setup;&lt;/code&gt;一行之前添加如下代码：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;__PACKAGE__-&gt;config( 'View::HTML' =&gt; {
    FILTERS =&gt; {
        'myown' =&gt; \&amp;myown_filter,
    },
});&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;把&lt;code&gt;View::HTML&lt;/code&gt;换成你自己的View，然后写一个名为&lt;code&gt;myown_filter&lt;/code&gt;的函数来完成真正的filter功能。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/05/plug-your-own-filter-into-catalyst.html' title='Plug your own filter into Catalyst'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=2919070054933511329' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2919070054933511329'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2919070054933511329'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-8920676814789528474</id><published>2008-05-18T16:05:00.000+08:00</published><updated>2008-05-18T16:06:08.581+08:00</updated><title type='text'>Completing read</title><content type='html'>&lt;p&gt;自动补全功能在任何时候都是受欢迎的，Emacs提供了一个基本的函数&lt;code&gt;completing-read&lt;/code&gt;，可以在接受用户输入时提供补全功能。除此之外，我们还可以使用一些更加强大的函数，比如&lt;code&gt;ido&lt;/code&gt;里面的&lt;code&gt;ido-completing-read&lt;/code&gt;，或者使用&lt;code&gt;iswitchb&lt;/code&gt;提供的功能。&lt;/p&gt;&lt;p&gt;使用&lt;code&gt;ido-completing-read&lt;/code&gt;比较简单，参见&lt;code&gt;psvn.el&lt;/code&gt;。而&lt;code&gt;iswitchb&lt;/code&gt;并没有提供一个类似的函数，所以必须自己写一个。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(defun wl-completing-read (prompt choices dummy require-match)
  "Use iswitchb completion functionality."
  (let ((iswitchb-make-buflist-hook
         (lambda ()
           (setq iswitchb-temp-buflist choices))))
    (iswitchb-read-buffer prompt nil require-match)))

(defvar wl-completing-read-function
  (if (fboundp 'iswitchb-read-buffer) 'wl-completing-read 'completing-read))&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;在引入&lt;code&gt;wl-completing-read-function&lt;/code&gt;变量之后，要使用&lt;code&gt;funcall&lt;/code&gt;来调用它，而不是直接进行函数调用。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(funcall wl-completing-read-function prompt choice nil t)&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/05/completing-read.html' title='Completing read'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=8920676814789528474' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/8920676814789528474'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/8920676814789528474'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-4383727455123004421</id><published>2008-05-11T13:41:00.002+08:00</published><updated>2008-05-11T21:00:44.946+08:00</updated><title type='text'>Authorization in Catalyst</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;&lt;p&gt;一边看&lt;a href='http://blog.jrock.us/'&gt;Jonathan Rockway&lt;/a&gt;的书——&lt;a href='http://www.packtpub.com/catalyst-perl-web-application/book'&gt;Catalyst&lt;/a&gt;，一边有模有样地学着写，到了authentication and authorization这部分被彻底打败了。&lt;/p&gt;&lt;p&gt;一开始按照书的去做，结果登录部分总是有问题（也可能是自己抄错了），于是去看&lt;a href='http://search.cpan.org/%7Emstrout/Catalyst-Manual-5.701004/lib/Catalyst/Manual/Tutorial/Authentication.pod'&gt;文档&lt;/a&gt;，登录部分问题解决，认证部分又失败。无数次碰壁之后，没法子，只好去看代码，把&lt;a href='http://search.cpan.org/%7Ejayk/Catalyst-Plugin-Authentication-0.10006/lib/Catalyst/Plugin/Authentication.pm'&gt;Catalyst::Plugin::Authentication&lt;/a&gt;下面的代码看了个遍，终于搞明白了。有三种方法设计数据库，分别对应一个表、两个表和三个表。使用三个表的时候要使用&lt;code&gt;Catalyst::Plugin::Authentication::Store::DBIC&lt;/code&gt;，其它两种情况要使用&lt;code&gt;Catalyst::Plugin::Authentication::Store::DBIx::Class&lt;/code&gt;。这两个Store的配置方式也是不同的。所谓三个表，就是一个帐号密码表，一个角色（role）表，和一个关联表（记录每个帐号对应的角色）；两个表即去掉角色表，而将其内容放在关联表里的角色部分；一个表最简单，将角色直接记录在帐号密码表里面，多个角色用逗号分割，记录在一个字段里。&lt;/p&gt;&lt;p&gt;我按照书上的例子建了三个表，却使用了错误的Store，自然得不到正确的角色信息。而不同的Store，还使用不同的方式验证用户登录，DBIC要用&lt;code&gt;$c-&amp;gt;login&lt;/code&gt;，而DBIx::Class要用&lt;code&gt;$c-&amp;gt;authenticate&lt;/code&gt;，要命的是传参的方式也不一样，前者接受用户名和密码两个参数，后者却接受Hash，要把用户名和密码对应字段名作为key传进去。这么多对应关系，有一点点错误，就完蛋了。&lt;/p&gt;&lt;p&gt;需要注意的是，文档里提到login函数不再提倡使用，只是为了兼容，才保留在哪里。由此可见，如果不是出书的速度慢了点，就是Catalyst的开发速度够快。所以，以后就不要使用三个表的设计了。&lt;/p&gt;&lt;/div&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/05/authorization-in-catalyst.html' title='Authorization in Catalyst'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=4383727455123004421' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4383727455123004421'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/4383727455123004421'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-2332653024602634989</id><published>2008-05-07T13:53:00.000+08:00</published><updated>2008-05-07T13:54:04.349+08:00</updated><title type='text'>Customize agenda view of Org Mode</title><content type='html'>&lt;p&gt;看了Randy Pausch的&lt;a href="http://www.youtube.com/watch?v=oTugjssqOT0"&gt;Time Management&lt;/a&gt;，感觉有必要改善自己使用Org Mode的方式，First thing first。我常用的任务状态有四个——TODO, STARTED, WAITING, DONE。日积月累，处于WAITING状态的任务已经达到7个之多，TODO夹在里面，很难分辨。最佳的解决方法是重新安排任务日期，使其不再出现在每天的任务列表里面。然而总有些东西挥之不去。&lt;/p&gt;&lt;p&gt;我的第一个解决方法是降低这些任务的优先级，然后设置排序算法，使优先级低的任务出现在不显眼的位置，对我来说，就是列表的底部。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(setq org-agenda-sorting-strategy
  '((agenda priority-down time-up)
    (todo priority-down category-keep)
    (tags priority-down category-keep)))&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;其次，让WAITING这几个字符低调一点，红彤彤的一大片，太惹眼了。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(setq org-todo-keyword-faces
      '(("WAITING" . (:foreground "gray" :weight bold))))&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;这下世界清静了。&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/05/customize-agenda-view-of-org-mode.html' title='Customize agenda view of Org Mode'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=2332653024602634989' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2332653024602634989'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/2332653024602634989'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-20394991.post-7370701603438304962</id><published>2008-05-04T13:27:00.003+08:00</published><updated>2008-05-04T19:26:14.506+08:00</updated><title type='text'>Read CPAN module source code</title><content type='html'>&lt;p&gt;有了&lt;code&gt;cperl-perldoc&lt;/code&gt;，在Emacs里面看perl文档很方便，但有时候想看看代码，只好切换到命令行下面执行：&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;$ emacsclient --no-wait `perldoc -l A::Module`&lt;/pre&gt;&lt;/blockquote&gt;&lt;p&gt;如果使用下面的Emacs Lisp代码，可以省掉切换的麻烦，像使用&lt;code&gt;cperl-perldoc&lt;/code&gt;看文档一样，直接在Emacs里面代开源代码文件。&lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;(defun wl-cperl-find-module (module)
  "View source code of CPAN module."
  (interactive
   (list (let* ((default-module (cperl-word-at-point))
                (input (read-string
                        (format "CPAN module%s: "
                                (if (string= default-module "")
                                    ""
                                  (format " (default %s)" default-module))))))
           (if (string= input "")
               (if (string= default-module "")
                   (error "No module given")
                 default-module)
             input))))
  (let ((perldoc-output
         (with-temp-buffer
           (call-process "perldoc" nil t nil "-l" module)
           (buffer-substring-no-properties (point-min) (1- (point-max))))))
    (if (string-match "no documentation found" perldoc-output)
        (message "%s" perldoc-output)
      (find-file-other-window perldoc-output))))

(cperl-define-key (kbd "C-c m") 'wl-cperl-find-module)&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://www.wanglianghome.org/blog/2008/05/read-cpan-module-source-code.html' title='Read CPAN module source code'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=20394991&amp;postID=7370701603438304962' title='0 条评论'/><link rel='replies' type='application/atom+xml' href='http://www.wanglianghome.org/blog/atom.xml' title='帖子评论'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7370701603438304962'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20394991/posts/default/7370701603438304962'/><author><name>netcasper</name><uri>http://www.blogger.com/profile/09923405180744914893</uri><email>noreply@blogger.com</email></author></entry></feed>