Posted on 25-05-2009
Filed Under (软件) by waterlin

如果你想建设自己的微博客服务,可以考虑用一用Laconi这个东西。

Laconica (音”luh-KAWN-ih-kuh”)是一个微型博客系统,类似于twitter和叽歪网之类的东西。identi就是用laconi搭建的微博客系统。

(0) Comments    Read More   
Posted on 25-05-2009
Filed Under (技术) by waterlin

整天在自己的电脑上写代码,然后再用ftp上传到服务器(没办法,服务器没有SVN这种高级玩意)。每次上传都不知道哪个文件修改了,导致我得停下来检查一下哪些文件上传了,十分痛苦。

另外,自己在本地写的一些小程序,还是需要经常备份一下,以防止哪天脑残修改出了一大堆的错误回溯不了就麻烦了。

因此,很有必要在本地也搭建一个代码版本管理工具,来帮助我们进行代码、文档的管理工作。

推荐使用SVN作为代码管理工具,搭个svn server,客户端用Tortoise svn,可以整合在资源管理器上面,还可以试试搭一个trac,在线比较差异和查看更改很方便。

下面我们来看看如何在Windows下搭建一个subversion服务器来方便自己的工作。

1) 搭建一个subversion服务器

在Windows下,推荐使用VisualSVN。这个发行版本的安装最简单了,包含了所有我们需要的模块,如subversion,Apache以及一个控制终端。安装很简单,一步一步安装完成即可。

2) 安装一个svbversion的客户端

在Windows下推荐用TortoiseSVN,我不觉得在命令行下一行一行地敲svn命令是一件很开心的事~~

3) 管理你的内容

现在我们只要在VisualSVN里,创建一个代码Repositories,比如说,我现在要写一个Python的工程,创建一个名叫PythonCode的Repositories,设置好相关的属性后,我就用TortoiseSVN来check out这个Repositories。Check Out的地址就是TortoiseSVN在Repositories属性里提供给你的URL地址,类似于:

https://WWW-81ECC445A0F:8443/svn/PythonCode/

当然,你可以把计算机名换成localhost,即修改成如下地址:

https://localhost:8443/svn/PythonCode/

如果你喜欢用eclipse的话,用Subclipse作为svbversion的客户端也不错:

就这样,你在本地能清楚地看到你这次修改了哪些文件,只要把这些文件上传到服务器即可。这下就不用每次抓狂地回忆究竟修改了哪个文件!

(1) Comment    Read More   
Posted on 20-05-2009
Filed Under (技术) by waterlin

使用VC编译C或者C++程序,都需要相关的C runtime库才能运行。如果你是VC6,相应的库就叫MSVCR,如果是VC2005,那就是MSVCR08,VC2008就是MSVCR09。我这里假设你安装的是VC2005,请进入如下目录:{VS Install Dir}\VC\redist\x86和{System Driver}:\windows\system32,你就会发现下面有很多很多的库。没错,这里相当一部分就是C Runtime库。

用VC2005编写的Console Win32 C/C++程序,怎么发布给最终用户呢?有两个方法:

(1) 静态引用C Runtime库

打开”项目”->”属性”->”配置属性”->”C/C++”->”代码生成”->”运行时库 “。这里一共有四个选项,其中MT开头的是静态引用,MD开头的是动态引用,d结尾的是Debug调试版本,没有d的是Release发布版本,所以就一共有四个选项。

我们选择/MT(这是默认选项),然后编译程序(生成的程序应该不小),把这个程序发给用户,然后用户就可以直接运行了。

如果你是英文版的Visual Studio 2005,则设置这个属性的路径为:”Project” –> “Properties” –> “Configuration Properties” –> “C/C++” –> “Code Generation” –> “Runtime Library”。

(2) 动态引用C Runtime库

跟上面差不多,不过是用/MD选项编译,然后发给用户。这时,用户是不能运行这个程序的,会报个”程序安装出错,不能运行”、”重装系统可能会修复问题”之类的提示。

这时我们还要把C Runtime库一并发过去。把{VS Install Dir}\VC\redist\x86\Microsoft.VC80.CRT下的所有文件(注意,是所有,包括那个.manifest文件)发给用户,用户把这些文件放在我们程序的同一个目录,然后再次运行,这时,程序就起来了。

第一种是静态编译的方式,第二种是动态编译的方式。静态编译出来的可执行文件会比动态编译出来的大许多,但是用户使用上会方便很多,可以视情况选用。

(0) Comments    Read More   
Posted on 20-05-2009
Filed Under (技术) by waterlin

假如有以下代码,是啥意思呢?

typedef void (closed_action)(void* param, uint32 user_id);

closed_action *closed_cb;

这其实就是定义一个函数指针的简洁方式,使可读性提高了。假如有一个函数

void AAA(void *param, uint32 id)
{
}

我们就可以用AAA来给closed_cb赋值:

closed = AAA;

这个括号有没有应该都可以,是定义一个函数类型void(void*, uint32)为closed_action的意思。

(0) Comments    Read More   
Posted on 20-05-2009
Filed Under (技术) by waterlin

用下面这种结构的代码,就可以巧妙地实现对C++输出日志的排版:

#define INDENT ” ”
LOG(“Using configured information:\n”
INDENT “address = %s\n”
INDENT “port = %d\n”
INDENT “user_id = %s\n”
INDENT “user_key = %s\n”,
);

其实就是定义一个代表很多空格的宏。

(0) Comments    Read More   
Posted on 11-05-2009
Filed Under (技术) by waterlin

在许多情况下,我们需要给网站建一个论坛,当然不可能自己从头开始写一个完整的论坛出来。在这种情况下,比较经济实惠的做法是,采用一个开源代码的论坛程序,然后做好Single sign-on的改造工作。

用phpBB论坛程序能非常方便地与你的网站进行整合,官方网站分别提供了phpBB3的sessions集成phpBB2的sessions集成样板文章。因为官方已经停止了对phpBB2的维护,所以,这里就简单介绍一下phpBB3 Sessions的桥接方法。

首先,把下面这段代码加到你需要桥接phpbb3的页面里:

<?php
define(‘IN_PHPBB’, true);
$phpbb_root_path = (defined(‘PHPBB_ROOT_PATH’)) ? PHPBB_ROOT_PATH : ‘./’;
$phpEx = substr(strrchr(__FILE__, ‘.’), 1);
include($phpbb_root_path . ‘common.’ . $phpEx);

// Start session management
$user->session_begin();
$auth->acl($user->data);
$user->setup();
?>

这里需要注意的是,$phpbb_root_path变量是定义你的phpBB3与你当前文件的相对路径,你需要根据你的实际情况来进行修改。比如说,我的phpbb3就是安装在forum目录下的,我应该替换成如下代码:

$phpbb_root_path = (defined(‘PHPBB_ROOT_PATH’)) ? PHPBB_ROOT_PATH : ‘./forum/’;

千万不要忘记最后的那个”/”目录字符,否则下面的代码会出错。

接下来就是判断是否有用户登陆了,如果有的话,则输出欢迎消息,如果没有的话,则输出提示登陆的消息。

<?php
if ($user->data[‘user_id’] == ANONYMOUS)
{
echo ‘Please login!’;
}

else
{
echo ‘Thanks for logging in, ‘ . $user->data[‘username_clean’];
}
?>

通过这样的方法,就能轻松地访问phpBB3的sessions了。更多的变量说明,可以查阅官方手册。只要把这些代码封装好,就能很好地操作phpBB3的sessions,达到整合平台的目的。

(0) Comments    Read More   
Posted on 08-05-2009
Filed Under (技术) by waterlin

一个朋友用Zen-cart的代码搭了一个网站娱乐一下,是从Zen-cart中文站下的代码。他的网站前几天出了这个问题:访问首页,只能打开一个空白页面,啥都没有;后台管理页面能访问,没有任何问题。

打开网站的日志(你也可以打开页面的错误输出来显示这个错误),能看到提示如下的错误信息:

Warning: session_start() [function.session-start]: Cannot send session cache limiter – headers already sent (output started at /home1/ecshinec/public_html/index.php:5) in /home1/ecshinec/public_html/includes/functions/sessions.php on line 108

Notice: Undefined index: seo_urls in /home1/ecshinec/public_html/includes/functions/html_output.php on line 24

Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 31457280 bytes) in /home1/ecshinec/public_html/includes/classes/seo.url.php(1068) : eval()’d code on line 21846

Notice: Object of class queryFactoryResult could not be converted to int in Unknown on line 0

这个Fatel Error很有可能是Ultimate SEO URLs这个module出了问题。

解决的办法,就是在后台管理 –> Configuration –> SEO里,把SEO相关的属性全部都改成false。当然,更深层次的错误原因,有空的时候再进一步研究。

(2) Comments    Read More   
Posted on 08-05-2009
Filed Under (技术) by waterlin

最近在用Perl来做工作的时候,运行到一个地方,需要我输入一个设备名,以判断接下来应该做的步骤。每次运行到这里,我都是手动输入很长的设备名,比如说ciscocontenteng,每次这样输入,不仅累死人,还很容易出错。

这种情况下,可以用Term::Complete这个module来实现用tab键自动补全。用法非常简单,看代码就差不多能理解了:

use warnings;
use strict;

use Term::Complete;

my @completion_list = (“atest”,”btest”,”cdtest”,”efgtest”);

my $input = Complete(‘please input the start character and use tab to complete: ‘, \@completion_list);
#$input = Complete(‘prompt_string’, @completion_list);

print “The input word is: “.$input;

在上面的代码里,我们设定了一个数组@completion_list,里面包含了需要补全的名称,Perl就是根据这个列表来对你输入的字符进行补全的。Complete函数是主导这个工作的核心,它的第一个参数是在终端上输出提示输入的说明,第二个参数就是能用于补全的词组列表。

运行这个脚本的时候,你按tab键,Perl会自动用列表中的词来帮你补全,你输入回车确定补全、输入结束后,Perl会把你输入的内容存到变量$input里。

这样,以后就再也不用敲一长串的字符了。

(0) Comments    Read More   
Posted on 08-05-2009
Filed Under (商业) by waterlin

今天,在上BBS的时候,突发奇想出一个BBS建设的建议,发在水木社区的Advice版面了。随手写的帖子,没修改,比较乱,原文如下:

发信人: waterlin (从细节完善生活), 信区: Advice
标 题: 我来提个建议
发信站: 水木社区 (Fri May 8 12:41:52 2009), 站内

水木是我最喜欢的BBS了,当然希望它能成长得更好,提供更多的功能。

我觉得,现在水木应该开发版面订阅RSS源的功能。

各个版面的人,肯定都有共同关注的内容,所以,经常有人转载相关的文章。这样挺麻烦的,时效性差,经常有人不贴原文出处之类的,使人想追溯原文很困难,不便于进一步的讨论,对于一些有争议的文章,就更没办法查原文出处去分辨是非了。

如果各个讨论版面,能增加订阅某个RSS源的功能,这一切问题就解决了。

比如说,”郑渊洁”版,我就喜欢在它上面转郑渊洁博客的文章,这样,版面上的人才会参加讨论,作为这个版块,郑渊洁的文章,当然是不可缺少的一部分了。

如果水木能自动订阅郑渊洁的博客,并把文章以特定的格式发到版面上,如加上原文出处,版权声明之类的,就更好了。

类似这样的版块还有很多,如Linux版块可能订阅相关的Linux RSS源,Movie可以订阅官方电影上映消息等。

当然,发文章的ID,最好是版主或是其他有权限的人,也要设置关键字审核。经由网友们讨论投票决定哪些RSS应该为版面订阅,并且各个版面每天订阅的RSS不能超过多少多少篇。

我觉得增加版面订阅功能,也算是对满世界SNS潮流的回击了~~

(3) Comments    Read More   
Posted on 06-05-2009
Filed Under (技术) by waterlin

最近,一直在苦苦寻找一个最适合自己的bug追踪系统。我自己平时写的一些小工具,有一些bug需要追踪管理一下,用记事本显得格式太随意了,不好管理。

试了很多有名的工具,如Bugzilla,Mantis,感觉都太厚重了,团队用倒是蛮合适的。

后来想着用XML定义一个日志数据库,一个Bug开一个文件,这样可以详细记录Bug的内容及解决过程、方法等。再写一个前端,用来管理组织这些XML文件。但我个人的bug量不多,更多的时候,是随手写一点想法,这种XML严谨的组织方式,并没有让我觉得更轻松。

尝试着用Emacs Muse记录了一段时间,有一个缺点,就是我写下来的解决方法里,有很多是代码,如果我不加<verse></verse>标签,Muse会尽量地帮我重新转义一下。总的来说,Muse还是偏排版多一点,不适合于记录随想随写的东西。

最后,我发现用Perl的pod来做自己的bug追踪系统挺好的。Pod虽然是个文档系统,但是只要灵活地运用标签也是能做简单的bug追踪系统。Pod的优点是,当你不需要用命令的时候,直接输入你的内容即可,总体来说,比较简洁。

我的pod格式定义如下:

=pod

=head1 project 1

=head2 Bug #000001

=head3 Bug #000001的简单描述或标题

Bug #000001的详细描述,所有的有关内容。。

=head3 Bug Status::Fixed

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000001, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=head2 Bug #000002

=head3 Bug #000002的简单描述或标题

Bug #000002的详细描述,所有的有关内容。。

=head3 Bug Status::Active

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000002, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=head2 Bug #000003

=head3 Bug #000003的简单描述或标题

Bug #000003的详细描述,所有的有关内容。。

=head3 Bug Status::Suspended

=head3 Bug解决方法记录

=over indentlevel

=item 解决步骤一

解决步骤一的内容。

=item 解决步骤二

解决步骤二的内容。

=item Bug Fix summary

Solution of Bug #000003, the summary of this bug is:

Try to readcord the document in time and in style.

这里就写一写把Bug搞定后的总结。

=back

=cut

把上面的例子代码存成一个文档,比如说,我喜欢存为WaterBug.txt,后缀用.txt是为了方便用其它编辑器查看。

用pod2html的命令生成文档给其他人观看:

pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug

当然,你可以为这个文档写一个你自己的Style Sheet,生成一个打着你的logo的个性化文档:

pod2html –infile WaterBug.txt –outfile WaterBug.html –title WaterBug –css stylesheet.css

在定义我的pod格式时,我分别用ActiveSuspendedFixedOn-hold四种状态来标明Bug的状态,即”正在进行”、”还未开始”、”已经搞定”、”暂时放着”等四种状态,这些状态关键字都是以::开头进行标识。

以这些简单的标记来记录文档,我可以随手写在任何文本文件里,包括Google Docs这些在线文档,即使将来要转成其它格式的文档,也可以轻松地用perl来实现转换。

要查找特定状态的bug,只要搜索一下::Fixed或是::Suspended或是::Active或是::On-hold即可。

(1) Comment    Read More