让urxvt支持256色

urxvt默认是不支持256色的,所以在urxvt里使作vim的时候,那些漂亮的配色方案就没有效果了。幸好,urxvt要加入256色的支持很简单,执行:

echo "x11-terms/rxvt-unicode 256-color" >> /etc/portage/package.use
emerge -av rxvt-unicode

要vim也支持256色,需要在~/.vimrc里加入:

set t_Co=256

最终效果:
urxvt with 256 color by hosanna_cn, on Flickr

Palm Pre 通信录拼音排序补丁

自Palm pre入手到现在已经一个多月了,这一个多月里对WebOS这个手机操作系统从不了解到慢慢熟悉,再到学习开发,大部分的业余时间都花在了这里。暂且不说Palm pre这款手机如何,单WebOS这个系统就给了我不少的惊喜,卡片式的操作方式真的很赞。但因为Palm pre未在中国大陆地区上市,所以中文支持不咋的,这方面完全依靠民间的开发者在支撑着。但我碰到的一个最大的问题是:通信录里的联系人不可以按拼音排序!据说当初iOS和Android系统也有这样的问题,不过现在已经有了相应的补丁来解决这个问题,而Palm pre 在这方面,虽然有人用JAVA重写了一个通信录(服务端)软件,但我一直都安装不成功,就只能自己想办法了。

一开始我想到的是给sqlite这个软件打补丁,让它直接支持拼音排序,好不容易搭好的编译环境,并为sqlite加入了拼音排序函数,却发现Webos使用的是它自己写的一个sqlite-server来读取数据的,而这个软件的源代码又不是开源了,无法为它添加补丁,只好作罢。一个偶然的机会,看到了iPhone的拼音排序补丁,发现它是直接在数据库文件里做了处理,这给了我一个思路,又恶补了几天SQL的语法,终于可以让Palm pre 的通信录可以按拼音来排序了,看图:
Palm pre 通信录拼音排序

这是虚拟机里面的截图,Palm Pre的SDK还是比较给力的,用起来很方便。虚拟机软件用的是VirtualBox,赞一个!

在截图中露脸的那几个朋友,记得给我寄广告费!嗯……这一次,先免费看效果,下一次就得收钱了!

补丁文件迟点再放出,先让我的Palm Pre做一下小白鼠,确认没什么不良反应再放出,佛曰:我不入地狱,谁入地狱!

VIM中为一个文件设置多种文件类型

VIM的很多插件功能都是根据文件类型来开启的,比如说代码高亮和自动补全等功能。而VIM又是根据文件扩展名来确定文件类型,有很多时候,在一个文件里可能要用到针对多种文件类型的功能,比如说在编辑php文件的时候,因为经常是要同时包含php和html代码,所以想同时打开snipMate针对php和html的自动补全功能。这个时候,单单是针对文件扩展名来确定文件类型是不够的,这样只能使用一种文件类型的特性。幸好,VIM是可以为一种文件扩展名定义多种文件类型的,只需要VIM的配置文件里加入如下配置:

if has("autocmd")
    autocmd BufRead,BufNewFile *.php set filetype=html.php
endif

这样在用VIM打开php文件时,就会同时应用html和php两种文件类型的特性,多个文件类型之间用“.”号连接。

为SCIM制作输入法

在Linux下我一直都是用SCIM输入平台下的五笔输入法,最近用的有点不太爽了,因为默认的五笔输入法只有GB2312字符集,很多字都打不出来,比如“囧”和一些粤语聊天中经常用到的字(“冇”……“嘢”等),所以就打算弄一个如Windows下极点五笔那样的支持GBK字符集的输入法。

首先,找一个现成的码表文件研究一下它的格式到底是怎么样的,SCIM的码表文件可以在/usr/share/scim/tables这个文件夹下面找到,先拿一个五笔的码表来看一下吧:

mkdir ~/wb-tables
cd ~/wb-tables
cp /usr/share/scim/tables/Wubi.bin ./

SCIM的码表文件是一个bin文件,还不可以直接编辑,所以要把它转换成文本文件。SCIM提供了码表制作的工具scim-make-table可以完成这个工作:

scim-make-table Wubi.bin -o Wubi.txt

现在可以使用文件编辑器打开Wubi.txt来看一下这码表文件到底是怎么组成的,一个码表文件大概是这样的:

SCIM_Generic_Table_Phrase_Library_TEXT
VERSION_1_0
### Begin Table definition.
BEGIN_DEFINITION
UUID = c584dfc8-c088-4908-9802-80eba0fb6ad9
SERIAL_NUMBER = 20040227
ICON = /usr/share/scim/icons/Wubi.png
NAME = Wubi
NAME.zh_CN = 五笔字型
NAME.zh_HK = 五筆字型
NAME.zh_TW = 五筆字型
LANGUAGES = zh_CN,zh_SG,zh_TW,zh_HK
### AUTHOR =
STATUS_PROMPT = 中
KEYBOARD_LAYOUT = US_Default
VALID_INPUT_CHARS = abcdefghijklmnopqrstuvwxy
### KEY_END_CHARS =
SINGLE_WILDCARD_CHAR = z
MULTI_WILDCARD_CHAR = *
SPLIT_KEYS = apostrophe
COMMIT_KEYS = space
FORWARD_KEYS = Return
SELECT_KEYS = 1,2,3,4,5,6,7,8,9
PAGE_UP_KEYS = Page_Up,comma,minus
PAGE_DOWN_KEYS = Page_Down,period,equal
MODE_SWITCH_KEYS = Shift+KeyRelease+Shift_L,Shift+KeyRelease+Shift_R
FULL_WIDTH_PUNCT_KEYS = Control+period
FULL_WIDTH_LETTER_KEYS = Shift+space
MAX_KEY_LENGTH = 4
SHOW_KEY_PROMPT = FALSE
AUTO_SELECT = TRUE
AUTO_WILDCARD = TRUE
AUTO_COMMIT = TRUE
AUTO_SPLIT = FALSE
AUTO_FILL = FALSE
DISCARD_INVALID_KEY = TRUE
DYNAMIC_ADJUST = FALSE
ALWAYS_SHOW_LOOKUP = TRUE
USE_FULL_WIDTH_PUNCT = TRUE
DEF_FULL_WIDTH_PUNCT = TRUE
USE_FULL_WIDTH_LETTER = TRUE
DEF_FULL_WIDTH_LETTER = FALSE
BEGIN_CHAR_PROMPTS_DEFINITION
a 工
b 子
c 又
d 大
e 月
f 土
g 王
h 目
i 水
j 日
k 口
l 田
m 山
n 已
o 火
p 之
q 金
r 白
s 木
t 禾
u 立
v 女
w 人
x 纟
y 言
END_CHAR_PROMPTS_DEFINITION
END_DEFINITION

### Begin Table data.
BEGIN_TABLE
a 工 戈
aa 式 戒
……
……
END_TABLE

由这个文件可以看到,SCIM的码表文件主要是由描述部分(BEGIN_DEFINITION……END_DEFINITION)和码表部分(BEGIN_TABLE……END_TABLE)两大块组成的。描述部分主要是输入法的一些基本的设置,如输入法的名字、输入法的图标等;码表部分就是各字、词对应的输入码,也是我们要修改的主要部分。

自己重新做一个码表这么艰难并重复制作轮子的事情当然不会做,只要在一个现成的码表上面添加上我们需要的部分就可以了。码表文件的获得方法有很多,可以使 用工具软件把windows下面的输入法码表转换成文本文件再拿来用就可以了。我使用的是for VIMIM的极点五笔字库,可以在这里下载。把下载的码表内容替换掉Wubi.txt文件中码表部分的内容就可以了。当然也可顺便改一下输入法的名字和图标,贴上自己的标志。接下来就是把Wubi.txt转换成SCIM的码表文件就可以了,还是使用scim-make-table:

scim-make-table Wubi.txt -b -o NWubi.bin

最后把生成的码表文件复制到/usr/share/scim/tables,如果有修改输入法的图标文件,把图标文件(48x48大小png图片)也复制到/usr/share/scim/icons下面,重新启动输入法,就可以在可用码表里选择启用自己生成的输入法了。

sudo cp NWubi.bin /usr/share/scim/tables
sudo cp NWubi.png usr/share/scim/icons

robots.txt 404错误的解决

最近查看网站日志,在404错误的条目里,出现最多的就是robots.txt这个文件了。原本以为是我真没有这个文件,但一检查发出根目录下是有这个文件的,但为什么还是显示page not found呢?然后我再以为是Drupal的问题,但是在网上搜索了好久,也没听说这个跟Drupal有什么关系。最后才突然想到可能是Nginx服务配置的问题,一查配置文件,果然是我没有加上txt文件支持的原因。

知道原因就好办了,在配置文件里加入下面几句就可以了:

location ~ (^\/|\.html|\.css|\.jpg|favicon\.ico|robots\.txt|\.png|\.js|\.gif)$ {
        root   /var/www/hosts/nofool.info/htdocs/;
        access_log        off;
        expires           30d;
}

上面的例子是为Nginx加入一些静态文件如html、css、jpg、png、js、gif的支持,txt文件则只支持robots.txt,ico文件则只支持favicon.ico

自动把网址转换超链接代码(PHP 版)

有时候需要在提交内容的时候,自动把一些网址自动加上超链接。下面是一个PHP的样例,支持转换普通的链接、FTP地址、E-mail地址、Twitter类的链接,里面的正则表达式稍作修改也可以用于其它的语言。

function add_links($text) {
    $text= preg_replace("/(^|[\s ])([\w]*?)((ht|f)tp(s)?:\/\/[\w]+[^ \,\"\n\r\t<]*)/is", "$1$2<a href=\"$3\" >$3</a>", $text); /* http[s]//** */
    $text= preg_replace("/(^|[\s ])([\w]*?)((www|ftp)\.[^ \,\"\t\n\r<]*)/is", "$1$2<a href=\"http://$3\" >$3</a>", $text); /* ftp://** */
    $text= preg_replace("/(^|[\n ])([a-z0-9&\-_\.]+?)@([\w\-]+\.([\w\-\.]+)+)/i", "$1<a href=\"mailto:$2@$3\">$2@$3</a>", $text); /* E-mail */
    $text= preg_replace("/@(\w+)/", '<a href="http://www.twitter.com/$1" target="_blank">@$1</a>', $text); /* @twitter 用户 */
    $text= preg_replace("/\#(\w+)/", '<a href="http://search.twitter.com/search?q=$1" target="_blank">#$1</a>',$text); /* #twitter 搜索 */
    return $text;
}

Nginx 通过FCGI支持Perl 脚本

折腾了几天,总算让Nginx也支持Perl程序了。因为之前已经配置好PHP的环境了(请看这里),所以这一次只是想在原来的的基础上增加Perl的支持而已,所以并不打算需要太复杂的设置。在网上找了很久,都没有找到比较好的教程,很多都需要自己写一个接口程序和启动脚本,并且很多都是不太符合Gentoo启动脚本的格式。最后没办法,只有自己慢慢的摸索了,参照PHP的相关设置,绕了不少的弯路,才总算成功了。趁自己还没有忘记之前,把过程记录下来吧。

首先,需要的是一个Perl的接口程序,找了好久我才找到了fcgiwrap这个程序,还好,Gentoo的Portage里也有,可以直接emerge它:

$ eix fcgiwrap
[*] www-misc/fcgiwrap
     Available versions:  (~)1.0.2-r1 (**)9999
     Installed versions:  1.0.2-r1(22时48分47秒 2010年08月05日)
     Homepage:            ht tp://nginx.localdomain.pl/wiki/FcgiWrap
     Description:         Simple FastCGI wrapper for CGI scripts (CGI support for nginx)
$ sudo emerge fcgiwrapp

创建一个spawn-fcgi启动脚本的链接

$ sudo ln -s /etc/init.d/spawn-fcgi  /etc/init.d/spawn-fcgi.pl

spawn-fcgi的配置文件

$ cat /etc/conf.d/spawn-fcgi.pl
# Copyright 1999-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /var/cvsroot/gentoo-x86/www-servers/spawn-fcgi/files/spawn-fcgi.confd,v 1.6 2009/09/28 08:38:02 bangert Exp $

# DO NOT MODIFY THIS FILE DIRECTLY! CREATE A COPY AND MODIFY THAT INSTEAD!

# The FCGI process can be made available through a filesystem socket or
# through a inet socket. One and only one of the two types must be choosen.
# Default is the inet socket.

# The filename specified by
# FCGI_SOCKET will be suffixed with a number for each child process, for
# example, fcgi.socket-1. 
# Leave empty to use an IP socket (default). See below. Enabling this, 
# disables the IP socket.
# 
FCGI_SOCKET=/var/run/fcgiwrap.sock

# When using FCGI_PORT, connections will only be accepted from the following
# address. The default is 127.0.0.1. Use 0.0.0.0 to bind to all addresses.
#
#FCGI_ADDRESS=127.0.0.1

# The port specified by FCGI_PORT is the port used
# by the first child process. If this is set to 1234 then subsequent child
# processes will use 1235, 1236, etc.
#
FCGI_PORT=

# The path to your FastCGI application. These sometimes carry the .fcgi
# extension but not always. For PHP, you should usually point this to
# /usr/bin/php-cgi.
#
FCGI_PROGRAM=/usr/sbin/fcgiwrap

# The number of child processes to spawn. The default is 1.
#
#FCGI_CHILDREN=1

# If you want to run your application inside a chroot then specify the
# directory here. Leave this blank otherwise.
#
#FCGI_CHROOT=

# If you want to run your application from a specific directiory specify
# it here. Leave this blank otherwise.
#
#FCGI_CHDIR=

# The user and group to run your application as. If you do not specify these,
# the application will be run as root:root.
#
FCGI_USER=nginx
FCGI_GROUP=nginx

# Additional options you might want to pass to spawn-fcgi
#
FCGI_EXTRA_OPTIONS="-M 0700"

# If your application requires additional environment variables, you may
# specify them here. See PHP example below.
#
ALLOWED_ENV="PATH"

Nginx配置文件

$ cat /etc/nginx/vhosts/example.com.conf
server {
    listen 127.0.0.1;
    server_name *.example.com example.com;
    access_log /var/log/nginx/localhost.access_log main;
    error_log /var/log/nginx/localhost.error_log info;
    root /var/www/example.com;

    location ~ .*.php$ {
	include /etc/nginx/fastcgi.conf;
	fastcgi_pass 127.0.0.1:1234;
	fastcgi_param  SCRIPT_FILENAME  /var/www/example.com/$fastcgi_script_name;
	fastcgi_index index.php;
    }
    
    location ~ .*.pl$ {
	include /etc/nginx/fastcgi_params;
	fastcgi_pass unix:/var/run/fcgiwrap.sock-1;
	fastcgi_param  SCRIPT_FILENAME  /var/www/example.com/$fastcgi_script_name;
	fastcgi_index index.pl;
    }

这里要注意的是,网上很多教程和fcgiwrap的手册(man page)都是把fastcgi_pass设置成 fastcgi_pass unix:/var/run/fcgiwrap.sock ,但是这样是不行的,查看Nginx的Log会发现有提示如下的错误:

connect() to unix:/var/run/fcgiwrap.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: *.example.com, request: "GET /test.pl HTTP/1.1", upstream: "fastcgi://unix:/var/run/fcgiwrap.sock:", host: "example.com"

原因嘛,/etc/conf.d/spawn-fcgi.pl 这个配置文件里关于FCGI_SOCKET的注释有写到,FCGI_SOCKET会为每个子进程添加一个数字后缀,所以需要把这个后缀也要添加上去,例如: fastcgi_pass unix:/var/run/fcgiwrap.sock-1; 否则,就会出现文件找不到的错误,我在这里花了不少的时间才明白这个事情。

最后,启动相关服务:

$ sudo /etc/init.d/spawn-fcgi.pl start
$ sudo /etc/init.d/nginx start

如果还是出现502错语并且Nginx Log 里有这样的出错提示:

upstream closed prematurely FastCGI stdout while reading response header from upstream, client: 127.0.0.1, server: *.example.com, request: "GET /test.pl HTTP/1.1", upstream: "fastcgi://unix:/var/run/fcgiwrap.sock-1:", host: "example.com"

那就要检查一下你的Perl文件是否有读取跟执行的权限了(755),在这里又花了我很长的时间才明白Perl脚本是还需要执行的权限的,这一点跟PHP不同。

Jquery 取消链接的默认行为

在写JS脚本,特别是AJAX脚本的过程中,经常要取消掉对象的默认行为。比如说点击某个链接,就在特定的块里面显示另一个页面的内容,通常是这样来写:

<div id="ajax">
</div>
<a href="ajax.html" class="load"></a>

Jquery Js

$('.load a').bind ('click', function() {
    var link = $(this).attr("href");
   $('#ajax').load(link);
});

这样的确可以把ajax.html的内容填入到#ajax中,但脚本执行完之后,页面还是会跳转到ajax.html这个页面,这可不是我所希望的结果。最后,查资料得到解决的方法,在脚本执行后返回flase取消默认的行为并阻止事件起泡(bubbling up),最后的脚本如下:

$('.load a').bind ('click', function() {
    var link = $(this).attr("href");
   $('#ajax').load(link);
   return false;
});

另外,通过preventDefault() 方法只取消默认的行为,通过使用 stopPropagation() 方法只阻止一个事件起泡。

参考网址:http://api.jquery.com/bind/

理解CSS3渐变背景

CSS3 支持定义渐变的背景,这个功能很实用,今天试用了一下,大概了解了基本的设置方式。

####Webkit 类浏览器设置

/*例子*/
background: -webkit-gradient(linear, 0 0, 0 100%, from(red), to(blue));
  • 第一个参数指定渐变的类型,linear(线性)或 radial(径向)。
  • 第二个参数指定渐变开始的坐标,可以是数字或百分比,也可以是关键字(如 left-top )。
  • 第三个参数指定渐变结束的坐标。
  • 第四个参数指定渐变开始的颜色。
  • 第五个参数指定渐变结束的颜色。

####Firefox 浏览器设

/*例子*/
background: -moz-linear-gradient(top, red, blue);
  • 第一个参数指定从哪里开始渐变( 例子里用的是 top ,还可以是指定角度如-45deg )。
  • 第二个参数指定渐变开始的颜色(red)。
  • 第三个参数指定渐变结束的颜色(blue)。

####效果

参考链接:
http://webkit.org/blog/175/introducing-css-gradients/
http://hacks.mozilla.org/2009/11/css-gradients-firefox-36/

获取实时天气信息的Perl脚本

前段时间捣鼓Perl的时候,根据Yahoo!提供的天气状况API写了一个脚本,用来分析并获取实时天气状况的信息。现在这个脚本已经被我用在了FVWM桌面的天气状况显示上,另外,使用第三方的飞信API,还可以把信息发到手机上,呵呵,还是蛮实用的。

#!/usr/bin/perl
###################
#根据http://developer.yahoo.com/weather/提供的API写的获取天气信息的脚本
#作者:一介农夫
###################
use strict;
use Encode;
use LWP::Simple;

my $wid = "2161664"; #中山,各个具体的wid可以到http://weather.yahoo.com/去搜索
my $url = "http://weather.yahooapis.com/forecastrss?w=$wid&amp;u=c";
my $data = get($url);
$data =~ s/<yweather\:forecast\s+(.*?)\>//g; #去掉后面重复的两行信息,暂时未知如何处理。
my $use_data = "";
my @temp_data = split /\n/, $data;
foreach my $temp_data (@temp_data) { 
    if ($temp_data =~ m/<yweather\:\w+\s+(.*?)\>/ig) {
	$use_data .= " ".$1."\n";
    }
}

my %info ="";
my %text = (
    "0" => "龙卷风",
    "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" => "雷阵雨",
    "3200" => "未知",
);
my @condition = split /\"\s+/, $use_data;
foreach my $condition (@condition) {
    if ($condition =~ m/^(\w+)\s*=\s*\"(.*?)\s*$/) {
	$info{"$1"} = "$2";
    }
}

my $message = decode ("utf8","中山天气状况:$text{$info{code}},温度:$info{temp}C,湿度:$info{humidity}%,能见度:$info{visibility}KM,气压:$info{pressure}MB,日出时间:$info{sunrise},日落时间$info{sunset}。$info{date}");
$message = encode("gb2312","$message"); #中文编码处理

my $send_url = "http://sms.api.bz/fetion.php?username=手机号码&password=飞信密码&sendto=要发送的手机&message=$message";
#print $message;
my $send = get($send_url);