Sparkle’s Workshop

在Dreamhost上安装Trac(2)

Posted on March 6, 2008 - Filed Under 互联网

前文说明了如何在Dreamhost安装Trac。安装完了怎么开始使用呢

因为Dreamhost是一个虚拟主机,因此我们不能使用tracd来启动,我们对外的唯一途径就是80端口的web server,也就是apache。而且我们不能自行安装apache的mod,于是也不能使用mod_python或者mod_wsgi的模式,也就是说只能用cgi或者fastcgi的模式,而本文只介绍fastcgi的做法

首先假设我们的站点的目录是~/mysite,而trac的目录在~/mytrac,而且我们已经初始化了一份trac

这里我把站点的目录和trac的目录分开,这样方便管理,而且站点其实需要很少文件的。我们只需要一个index.fcgi和一个.htaccess

这里是index.fcgi的内容

#!/bin/bash
 
export TRAC_ENV="${HOME}/mytrac"
 
export LD_LIBRARY_PATH=${HOME}/python/lib:${LD_LIBRARY_PATH}
export LD_RUN_PATH=${HOME}/python/lib:${LD_RUN_PATH}
export PATH=${HOME}/python/bin:$PATH
 
exec ${HOME}/python/bin/python ${HOME}/python/share/trac/cgi-bin/trac.fcgi

由于我们的python是安装在用户目录的,因此需要更多的预设环境变量
其实你也可以直接copy trac.fcgi过来在头部加上配置,但是我更喜欢自己些一个文件然后exec默认的fcgi文件
而且我exec的时候,可以直接指定使用的python的路径,而在trac.fcgi头部标注路径的做法似乎不太生效

接下来就是.htaccess文件

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.fcgi/$1 [L]
RewriteRule ^$ index.fcgi
 
AuthType Basic
AuthName "Trac"
AuthUserFile ${HOME}/mytrac/trac.htpasswd
Require valid-user

首先就是rewrite了,把所有的请求都rewrite给index.fcgi
然后就是认证。非常可惜,Dreamhost并不支持在.htaccess里面使用Location指令,因此我不得不把整个site都加入验证了,因此我的site变得完全private了,本来应该只是针对/login做验证。我尝试了很久都没有解决方案

so it’s done

Leave a Comment >>

在Dreamhost上安装Trac

Posted on March 6, 2008 - Filed Under 互联网

在公司使用了一段时间的Trac,觉得很不错,于是想在Dreamhost上安装一个Trac,方便记录自己的一些想法,也可以用作跟朋友一起做一些小项目。本文就是介绍如何在Dreamhost上安装Trac

Dreamhost的wiki里面也有提及如何安装Trac,但是相应的版本比较旧了,而且感觉也不是很完整,在参考wiki来安装的时候也碰到不少问题。最后还是决定安装目前最新版的Trac 0.11。之前介绍的在公司安装的是0.10,一来在windows下0.10一来的包都有二进制版本,二来那个时候0.11还没有很成熟。现在Trac官方网站已经把0.11的安装说明作为默认的了,看来0.11很快就要发布了。另外也因为在linux下安装本身就没有现成的二进制包,而0.11依赖的包更少,更容易安装。

Dreamhost上的python版本是2.3.5,另外因为没有办法使用根用户,所以索性在自己的用户底下安装最新的python2.5.1,更加容易处理。

从python网站下载Python-2.5.1.tgz,然后参看Dreamhost的wiki安装

cd
mkdir python
tar -zxvf Python-2.5.1.tgz
cd Python-2.5.1
./configure --prefix ~/python/ --enable-shared
make
make install
install -c -m 644 ./libpython2.5.a ~/python/lib/
install -c -m 755 ./libpython2.5.so ~/python/lib/
install -c -m 755 ./libpython2.5.so.1.0 ~/python/lib/

我把它安装在我的用户目录的python/下,有几个lib在用户模式下安装并不会copy到正确的位置,因此需要自己处理一下

然后就可以通过

~/python/bin/python

来测试是否正常工作

接着修改我们的.bashrc

export LD_LIBRARY_PATH=${HOME}/python/lib:${LD_LIBRARY_PATH}
export LD_RUN_PATH=${HOME}/python/lib:${LD_RUN_PATH}
export PATH=${HOME}/python/bin:$PATH

再测试一次正常工作

. ~/.bashrc
python

剩下来的工作,主要就是参看Trac官方提供的Install手册

先安装easy install

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

接着用easy install安装Trac和依赖的包

easy_install Pygments
easy_install Genshi
easy_install Trac

运行

tracadmin

成功,现在Trac已经可以开始使用了

待续

1 Comment

令你的Mac Term更好用

Posted on February 29, 2008 - Filed Under 苹果

一直都认为Mac的Term很难用,包括内置的,还有很多人推荐的iTerm
我一直都在用iTerm,但是有很多问题,显示不了中文,输入不了中文,在VI或者一些软件下面不能用方向键(甚至我ssh到一台linux主机都不能用)

在windows平台的时候,使用putty或者securecrt等term软件,都有一大堆设置可以使用.而iTerm不停出新版本,也不见有多少个设置.就算用Linux,也没有那么多问题.还真的有狠心把MacBook装成Linux算了的想法

网上没有任何这方面的资料,还到一些blog里面留言询问别人的心得,也没有结果

研究了很久,终于知道怎么处理了

首先是方向键问题,我突然想想有可能emacs的键位可以使用,结果真的可以.^N ^P ^B ^F分别代表上下左右,这样用了一段时间
后来突然想起我在securecrt在设置把TERM改成Linux,改不会是有影响
于是在~/.profile加入

export TERM=linux

果然,方向键都有效了,整个操作变得跟Linux一样.原来securecrt的设置只是主动传给shell,而并不是它自己的设置.而且ssh到linux主机也正常了.后来研究发现,TERM会跟随ssh传递到远端shell,当然你可以自己再修改一次.

然后就是中文问题了,经过研究发现,我的Linux系统里面有一个文件/etc/inputrc
里面有一些关于meta的设置,而MacOS下面并没有这个文件
于是我在~/.inputrc加入一样的meta设置

set meta-flag on
set input-meta on
set convert-meta off
set output-meta on

然后把iTerm的Encoding改成UTF-8

另外还在~/.profile加入

alias ls="ls -wG"

现在ls终于能看见中文,而且输入中文也正常.不过delete文字不太正常,还没找到解决方法.

Mac默认就是按照UTF-8存储中文的,如果连上Linux并不是用UTF-8而是用GBK的话,可以临时修改iTerm的Encoding来查看

Leave a Comment >>

给《程序员》写的MINA文章已经出刊了

Posted on February 26, 2008 - Filed Under Uncategorized

第一次给杂志写文章,没什么经验,行文一般般,呵呵。不过也是能顺利出刊。

对文章有任何意见和建议,或者讨论MINA,可以在这里留言

迟点我再写一些MINA的心得

5 Comments

在CentOS4上安装JMagick

Posted on February 21, 2008 - Filed Under 互联网

用Java做网站经常要处理用户上传的图片,例如生成缩略图等等。虽然Java可以使用Java2D进行一些图片操作,但是功能和效率实在太差了。目前比较好的是用JMagick来进行图像处理,不过JMagick是通过JNI调用ImageMagick的,对平台有一定依赖。本篇文章就是在CentOS4上安装JMagick。

版本问题
CentOS4内置的软件版本一直都比较低,ImageMagick就只有6.0.7。另外JMagick也很久没有更新了,最新版是6.2.6-0,对应使用ImageMagick 6.2.6。而ImageMagick官方网站上只有6.3.8。情况有点混乱,最后决定使用最新版的ImageMagick和最新版的JMagick,似乎工作正常。

从ImageMagick官方ftp上下载最新版的ImageMagick和JMagick(是的,这里也有下载),分别解开。进入ImageMagick目录,运行

./configure –prefix=/usr/local/ImageMagick
make
make install

因为我不想跟系统的ImageMagick相冲,于是安装到独立的目录里面了

然后进入JMagick的目录,运行

./configure –prefix=/usr/local/jmagick \
–with-magick-home=/usr/local/ImageMagick \
–with-java-home=/opt/jdk
make all
make install

因为我的jdk是自己安装的,所以直接指定了。如果你遇到找不到java的错误,检查一下你是否配置了JAVA_HOME环境变量等,实在不行,就加上这个

export PATH=/opt/jdk/bin:$PATH

如果提示找不到ImageMagick相关资源,就加上这个

export PATH=/usr/local/ImageMagick/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/ImageMagick/lib

安装成功之后,就是在tomcat里面使用的问题了,我不习惯在整个系统里面增加环境变量的做法,一般来说,我会在具体的引用启动脚本里面加上环境变量的配置

打开tomcat/bin/catalina.sh,在顶部加入

LD_LIBRARY_PATH=/usr/local/ImageMagick/lib
CATALINA_OPTS=”-Djava.library.path=/usr/local/jmagick/lib”

测试成功

Leave a Comment >>

SSH over proxy

Posted on February 18, 2008 - Filed Under 互联网

一直都是用SecureCRT连接ssh服务器
由于我们的网络环境比较特殊,服务器在电信,但是我们办公的出口是网通
于是我用了一个在双通机房的sock服务器来proxy
SecureCRT很简单就可以设置使用代理了

今天在研究rsync,打算over ssh来使用
用cygwin装了rsync和openssh
但是直接用ssh连接实在太慢了
研究了半天,终于搞定ssh的proxy配置

这里得知,通过在~/.ssh/config加入ProxyCommand来实现
但是我试过几个版本的netcat,都没有-X -x的参数
而connect-proxy根本不知道在哪里能找到

有一个朋友说可以用Corkscrew,但是它只支持http proxy

还有一个connect.c,不过网站挂了

最后终于被我找到这个,似乎就是connect.c的新网站,使用方法都一模一样

Features of connect.c are:
* Supports SOCKS (version 4/4a/5) and https CONNECT method.
* Supports NO-AUTH and USERPASS authentication of SOCKS
* Partially supports telnet proxy (experimental).
* You can input password from tty, ssh-askpass or environment variable.
* Run on UNIX or Windows platform.
* You can compile with various C compiler (cc, gcc, Visual C, Borland C. etc.)
* Simple and general program independent from OpenSSH.
* You can also relay local socket stream instead of standard I/O.

因为我是在windows下使用cygwin,懒得用gcc编译了
下载了connect.exe,放在c:\windows
然后在~/.ssh/config加入

ProxyCommand connect -S x.x.x.x:x %h %p

1 Comment

Ibatis with MapBean

Posted on January 29, 2008 - Filed Under Java

用了两年的Hibernate之后,对ORM深有感触。一方面,ORM可以令到我们从OO角度来思考数据,屏蔽了数据库的差异(其实Hibernate被吹的最厉害就是那个分页,其实分页没什么技术含量,而且ROR都把分页从核心抽离了)。另一方面,性能问题,例如必须select才能update,必须select全部,必须update全部,cache带来的后遗症,javabean关联问题(一对多,多对一,多对多等),lazyload问题。当然,小型项目是很有优势的

Hibernate一直说,他生成的sql比一般程序员的要好,可以减少很多问题。但是,我倒是认为用Hibernate反而因为对程序员的要求更高导致更多问题。而且我现在认为,SQL才是王道,至少目前是。

于是在新项目中启用Ibatis,这一年来的使用感觉很不错,全程使用细粒度的SQL语句,虽然多写了很多SQL语句,但是感觉到项目在自己的控制中

我只用了Ibatis 40%不到的功能,可能大家会觉得不可思议。我没有用cache,没有用关联,没有用resultMap,甚至,连JavaBean也没有用

在大家都在讨论PO,VO,DTO的时候,我的系统里面一个JavaBean都没有

首先我问问,JavaBean是用来做什么的,存储数据,每一个PO,其实就约等于一个表里面的一行数据

我举一个真实一点的例子,一个user表

public class User {
  private int id;
  private String name;
 
  // 省略getter/setter一大段
}

不知道大家有没有用eclipse生成JavaBean getter/setter的痛苦,至少非常枯燥。整个JavaBean实现了什么功能?完全没有

好了我开谜底了,我用的是HashMap

什么,HashMap?是不是听错了

没听错,请问有什么事情是上面那个那么普通的JavaBean能做到的,而HashMap不能做到的呢

用HashMap没有具体属性的类型啊,那不是变成动态语言一样了,而且我要在JavaBean里面加逻辑怎么办

好吧,这是我想到的两个问题(如果你也有别的问题可以留意提出来)

首先,现在不同以前了,动态语言的优势慢慢提高了,像动态语言有什么不好,我从ROR里面学了很多不错的思想

其次是要加逻辑怎么办,这个问题,之前在Javaeye讨论充血模型还是贫血模型不可开交,最后还是没什么结论,目前还是一片贫血的情况,你可以翻一下你的项目里面的JavaBean,至少大多数的Bean都是没有意义的getter/setter。BO跟PO混杂在一起也很多人不建议的。至于逻辑,大可以写在util包里面,我都把整个model包去掉了,强化一下util不成么,呵呵

再次,数据库的列,跟JavaBean的属性两者,本来就是冗余的,如果我们修改数据库结构,就还要修改相应的JavaBean,或者影射文件。当然我这种做法更依赖数据库。另外,ROR的名字转换功能可以令到代码中的调用名字更好看一些,我觉得也不是非常有必要的实现

直接使用HashMap不太方便,尤其是类型转换上,于是我实现了一个MapBean的类,其实这个类很简单,关键是用HashMap代替JavaBean的思想

public class MapBean extends HashMap<String, Object> {
	public MapBean() {
	}
 
	public MapBean(Object... args) {
		put(args);
	}
 
	public int getInt(Object key) {
		return getInt(key, 0);
	}
 
	public int getInt(Object key, int defaultInt) {
		Integer i = (Integer) get(key);
		return i == null ? defaultInt : i;
	}
 
	public String getString(Object key) {
		return (String) get(key);
	}
 
	public String getString(Object key, String defaultValue) {
		String value = (String) get(key);
		return value == null ? defaultValue : value;
	}
 
	public Timestamp getTimestamp(Object key) {
		return (Timestamp) get(key);
	}
 
	public void put(Object... args) {
		for (int i = 1; i < args.length; i += 2) {
			put(String.valueOf(args[i - 1]), args[i]);
		}
	}
 
	public JSONObject toJson() {
		return JSONObject.fromObject(this);
	}
 
	public JSONObject toJson(String... keys) {
		xxx
	}
 
	public String toJsonString() {
		return toJson().toString();
	}
}

这个类主要是方便做类型转换,加入了getInt,getString等方法,另外因为我的系统里面大量使用了JSON,也有一些HashMap向JSON转换的辅助方法,还有一个特别处理过的put方法和构造器,有什么用呢,看下面的例子

MapBean params = new MapBean("id",userId,"name",username,"sex",0,"online",true);

如果你直接用HashMap实现以上功能,要写五行代码,就这个差别而已,呵呵

当然如果你用JavaBean的话,你也可以写一个对应的构造函数

接下来,我们在sql-map-config.xml中加入

<typeAlias alias="mapbean" type="xxxxxxx.MapBean" />

就可以用mapbean的别称来引用这个类了

例如具体的SQL xml是这样的

<select id="getWorkManagerSystemRole" resultClass="mapbean"
	parameterClass="mapbean">
	select * from work_manager_system_role where
	system_id=#system_id# and user_id=#user_id#
</select>

其实我已经把Ibatis当成SQL wrapper来用了,我曾经评估过Spring的JDBC Template,不过功能始终差少少,或许以后我把JDBC Template再强化一下来代替Ibatis吧

7 Comments

架设你的CruiseControl

Posted on January 28, 2008 - Filed Under Uncategorized

说实在话,07年最大的感悟就是重新认识了TDD和持续集成的意义,这个下次有机会再说。这次要说的是部署一个持续集成服务器。

持续集成服务器的作用其实很简单,就是check out最新的代码,然后运行指定的script,然后把结果记录下来,还可以将结果(尤其是错误的结果)通过email等手段发给程序员。

事情倒是很简单,但是我们为什么要专门的软件呢,当然你也可以自己写bash script来做这些事情,做着做着你就会发现差不多实现一个CruiseControl出来了,呵呵,无谓重复发明轮子。

常用的持续集成服务器有CruiseControl、Luntbuild 和 Anthill等,相对来说CruiseControl比较老牌,支持度也比较好,不过实际使用的时候还是觉得不太好使(最近又发现了一个软件Hudson,Netbeans在使用)

下面是安装和配置过程,可能有一些细节不是很准确,因为已经是比较早之前安装的

从官方网站下载最新版的CruiseControl 2.7.1,我选用的是exe的版本,因为我的服务器是windows的,相对来说,exe版本有一些预设的参数,配置会简单些

运行安装程序,默认装在C:\Program Files\CruiseControl,可以不改动,而实际的项目文件可以放在其他盘上面的

安装成功之后运行cruisecontrol.bat,就能看到一个dos窗口运行,这个时候访问本机8080端口就可以看到一个示范项目

接下来修改配置文件

打开config.xml,可以看到示范例子的配置,把它都注释掉,不过其实我最后的配置也跟它差不多

直接贴我的配置吧,然后再来解释

<project name="xxx-xxx">
        <listeners>
            <currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
        </listeners>
        <bootstrappers>
            <svnbootstrapper localWorkingCopy="D:/cc/${project.name}" />
        </bootstrappers>
        <modificationset quietperiod="30">
		<svn localWorkingCopy="D:/cc/${project.name}"/>
        </modificationset>
        <schedule interval="300">
            <ant anthome="apache-ant-1.7.0" buildfile="D:/cc/${project.name}/build.xml" 
target="svnup test" />
        </schedule>
        <log>
		<merge dir="D:/cc/${project.name}/target/testresult"/>
        </log>
</project>

首先是项目的名字,这个是必须的,中途可以用${project.name}来引用

listeners是监听事件,这里加了一个构建状态监听。CruiseControl默认把构建状态保存在logs/${project.name}/status.txt下,但是,这仅仅是成功or失败的状态,而没有具体的信息,加上这个配置的话,就能在首页看到是否成功的显示

bootstrappers和modificationset启动监听,其实我已经分不清他们两个的具体作用了(不好意思了,以后再翻一下补上),配置到你的项目目录中,我这里用了D:/cc/${project.name}。另外,你应该预先用svn checkout一份项目在这个位置,因为CruiseControl还要在该目录进行svn update的操作,所以这个目录的svn信息必须完整的,比如有.svn等文件,简单来说,也就是你可以在该目录成功运行“svn update”的命令

schedule里面放的是实际运行的script,很明显,我这里用了ant,调用了它的svnup和test两个target,为什么有个svnup的东西?呵呵待会说

最后是log,这个是用来合并ant输出日志的,如果你在CruiseControl的构建页面里面没有看到任何出错的详细信息,那就可能是没有合并日志,而ant脚本也必须配置成把相应的日志输出到设定的目录

基本的配置就是这样,这里还miss了一个ant的build.xml的内容,待会再介绍它,现在我先来说说CruiseControl的工作流程

CruiseControl通过内置的svn支持,定期检查localWorkingCopy目录的svn状态变化,然后触发构建script,但是,这里有一点必须主意的是,CruiseControl并没有svn update的功能,他仅仅是用内置的svn支持去检查你的目录是否有更新,但是具体的更新是由你来做,于是便有了很奇怪的ant svnup的target,待会你会看到它的内容

说实在话我觉得这种模式非常奇怪。而且如果检查的频率不够的话,svnup的时候,非常有可能update了好几个changeset下来,也就是说构建不是按照changeset分割的,仅仅是按照时间分割的

接下来就是build.xml的内容,我只列出跟CruiseControl相关的部分

<target name="test" depends="testcompile">
	<junit printsummary="true" fork="true">
		<classpath>
			...
		</classpath>
		<batchtest todir="target/testresult">
			<fileset dir="target/test">
				<include name="**/*Test.*" />
			</fileset>
		</batchtest>
	</junit>
</target>
<target name="svnup">
	<exec executable="svn">
		<arg line="up" />
	</exec>
</target>

这里需要主意的是,把测试结果输出到目录,然后在CruiseControl合并。另外一个当然是奇怪的svnup

这里有一个问题,如果你用海龟之类的svn client checkout项目,而你的机器上面没有装svn命令行的话,你可能不能使用我这个方法,需要有少少改动。其实就是用ant的svn支持来代替命令行的svn操作,具体可以研究ant的配置手册

基本就是这样了,重启你的CruiseControl,然后提交一些changge上svn,看看有没有结果输出吧

7 Comments

优化你的Eclipse VM参数

Posted on January 26, 2008 - Filed Under Uncategorized

最近dzone在讨论eclipse的VM参数
引用了一篇2004年的帖子

Here are the best options that I’ve found so far for my 2-processor Windows machine running JDK5.0 and Eclipse3.1:

-vmargs -XX:+UseParallelGC

2004年就用两个CPU都颇奢侈了吧

我现在的机器是双核+2G内存,于是我修改了一下eclipse的VM参数

打开eclipse.ini

修改或加入如下内容

-vmargs
-Xmx512m
-XX:+UseParallelGC

Leave a Comment >>

我与Mercurial

Posted on January 25, 2008 - Filed Under Uncategorized

最初知道 Mercurial这个工具其实是因为去年6月份看了cyfdecyf的一篇blog分布式版本管理工具:git & mercurial(作者搬迁了blog,新地址是这里).然后断断续续有在使用,一直想把一些经验写出来.最近刚好遇到云风在研究分布式版本管理,还是动手把一些经验写下来吧

一直一来都是用CVS,然后是SVN来做版本管理,最初认识分布式版本管理,是一个叫SVK的工具,是一个台湾人的作品,本身基于SVN,令到SVN可以分布式工作.当时觉得安装非常麻烦就没有研究下去了,而且本身对这样的功能需求也不大.后来Linus因为不满现有版本管理软件的问题,自己花了两个星期写了一个分布式版本管理Git,现在Linux kernel等源代码已经完全工作在Git的管理之上了.但是Git本身非常晦涩难懂,而且只能在Linux下运行,我本身也主要用Windows来工作,因此也没有深入研究.

直至看到 cyfdecyf的文章,这篇文章有坚定我研究分布式版本管理的信心.集中式版本管理的缺陷, cyfdecyf和云风都有描述了一些例子,我认为那些例子都很典型.如果所有开发人员都在一个房间里面,集中式版本管理是最好的,最明显的例子就是公司的开发,大家都能直接访问到服务器,网络不会中断.这种情况下,使用分布式版本管理反而增加了复杂性.但是,如果开发人员不是在同一个房间,甚至在不同的国家.当然你也可以在Internet上假设一个SVN服务器.但是,开发人员不一定有网络,或者网络不一定很好.而每次提交,或者同步,都要花上好几分钟或者更长时间,这非常影响开发.又或者你只是私人的项目,而你有没有能力假设公开的SVN服务器.而且我只是一个人,为什么每次都要提交到外边的服务器.当然也可以在自己的机器上面架设一个SVN,但是如果你有两台以上的机器就会觉得很麻烦了.

所有的这些场景,其实你需要一个分布式版本管理.cyfdecyf的文章最后在选择Git的代替品,定了用Mercurial.那我也从Mercurial开始吧.不过Mercurial的中文资料非常少,我始终不理解分布式版本管理的原理.最后,非常搞笑的情况是,我其实是看了Git的一份中文资料才真正明白的,也推荐大家从Git的中文资料入手.

待续…

3 Comments

« go backkeep looking »