2005年04月30日

今天偶然在 Python.list 邮件列表发现一封邮件,上面是说有一个 Python 的迷题网站,需要你使用 python 的编程知识才可以一步一步地向下走。有些复杂的可能需要下载一些模块才可以继续下去。每个迷题都是要求你计算出结果,或按指示进行,因此提示是很重要的。如果做不出来,它有一个论坛是关于解题的提示。当然不建议你把答案写出来,而只是提示最好。好了,大家去试试吧:

Python Challenge

2005年04月29日

本来是想给同事用的 Roundup ,但在汉化过程中出现了问题,于是就在 Roundup 邮件列表中提了一些关于语言设置翻译方面的问题。最终问题也解决了。解决我问题的是 Roundup 的一位开发人员  alexander smishlajev ,他问我能否提供一个中文的po文件,唉,我答应了。

翻译是痛苦的,特别是有些术语搞不清,意思是明白但不好表达,尤其是 roundup 我用得很少,有些东西还不太清楚。不管怎么样,有总比没有强,如果不行还有原文可以看,不是吗?

最后大段的翻译我使用了 poEdit 来完成的。感谢大熊的介绍。的确不错。还可以帮助我发现一些小问题。也许我翻译的po会在 roundup 的某个版本出现,不过 wiki 还是放了一个最新的,有兴趣的可以下载。有翻译上的错误也请指出来,让我们一起把它做好。

下载zh_CN.po,文件名在下载后请改为zh_CN.po。

2005年04月28日

这件工作正在进行,还没有完成,只是想把如何增加中文译文的过程描述一下。因为我解决这个问题花了不少时间,也得到了roundup邮件列表一位成员的帮助,他就是俄语译文的作者,打开ru.po可以看到他的名字。

roundup允许你为英语之外的语言增加翻译文件,在安装目录下的locale子目录中提供了一个叫roundup.pot的文件,把它另存为po文件,你就可以开始翻译了。增加译文有两种方式,一种是放在共享目录下,另一种是放在某个实例下。那么我使用的是第二种。

两种方式对于po文件的要求也不同。第一种要求命名为roundup.po,并且要严格按照标准的翻译文件目录的要求存放,如C:\Python23\share\locale\zh_CN\LC_MESSAGES\roundup.po。而如果采用第二种方式则可以为 locale\zh_CN.po。采用第二种方式要注意locale目录是在你创建的实例目录下的,与其它的db子目录是同级的。

放置好po文件,接着就是需要设置你想用的语方言种类,一种方法是在环境变量中设置LANGUAGE, LC_ALL, LC_MESSAGES, LANG这几个中的一个。另一种方法就是修改config.ini了。找到tracker节,修改language选项为zh_CN即可。我采用的是第二种方法。

然后开始po的翻译。这里有一点要注意,直接从roundup.pot拷贝来的文件头处有一行:

#, fuzzy

这一行一定要去掉。这个有什么用我没有研究过,反正是有这一行,你的po的翻译信息,如作者,编码集就不会在mo文件中出现。

po文件还是好翻译的,一个msgid对应一个msgstr。msgstr可能有多行。照样子翻译就行了。注意要保存为utf-8编码的。其它编码当然也可以了,但因为roundup使用的是unicode处理方式,因此这个文件的信息读出来后会转换为unicode,如果编码在别人的机器上不存在,则一定会失败的。因此使用utf-8是安全的方案。

在翻译的po文件中有时会出现这样的信息:

msgid "Required %(class)s property %(property)s not supplied"
msgid_plural "Required %(class)s properties %(property)s not supplied"
msgstr[0] ""
msgstr[1] ""

这是专门用于有单复数的语言环境的,中文没有这个问题,因此上面可以改成:

msgid "Required %(class)s property %(property)s not supplied"
msgstr ""

我的po文件头是这样写的:

msgid ""
msgstr ""
"Project-Id-Version: 0.8.2\n"
"Report-Msgid-Bugs-To: roundup-devel@lists.sourceforge.net\n"
"POT-Creation-Date: 2004-10-19 12:33+0300\n"
"PO-Revision-Date: 2005-04-27 14:13+0000\n"
"Last-Translator: limodou <chatme@263.net>\n"
"Language-Team: Simplified Chinese <chatme@263.net>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"

可以看出我使用的是utf-8编码,因此保存时要存为utf-8编码。

那么翻译完了就可以运行roundup试一试了。怎么?还没有生成mo文件呢。呵呵,不需要,roundup会根据po的创建时间自动生成mo,这样如果你更新了po文件,只要一刷新页面,roundup会自动把po编译成mo,真是挺方便的。

这样我就可以边翻译边看效果了,又不用重启roundup,很方便。

2005年04月27日

这两天没事搞了搞 roundup。搞这个是因为一位同事想要安装一个问题跟踪系统,我一下子就想到了roundup了。这位同事不知道 Python ,他只想要一个简单容易安装和使用的问题跟踪系统。我向他说,Python简单,roundup也简单。于是立马下载了一个,安装是很容易的,和一般的包一样。但配置可就有些麻烦。

roundup的安装文档内容非常多,配置说明写得也不够清晰和傻瓜化,如果不仔细看很容易出错。这不按照要求先建了一个目录,然后执行roundup-admin install来执行初始化工作。会有一些提示要求你输入。其中要输入tracker home的路径。这一点要注意,roundup会自动创建最后一个路径的,如使用相对路径demo,那么roundup会在当前目录下创建demo子目录,而并不是需要你事先创建的。但你运行时却需要在demo的上层目录运行。真是很奇怪。可能roundup把一个子目录当成一个实例的缘故。在初始化后,在demo子目录下会有一个config.ini文件。

在上面执行完毕后,它会提示你修改config.ini的相关配置项。但这里文档中我感觉就很混乱,当然也许是我没看太懂,原文如下:

You will now be directed to edit the tracker configuration and initial schema. At a minimum, you must set MAILHOST, TRACKER_WEB, MAIL_DOMAIN and ADMIN_EMAIL. The configuration file uses Python syntax, so almost every value must be ‘quoted’ using single or double quotes. If you get stuck, and get configuration file errors, then see the tracker configuration section of the customisation documentation.

意思就是要改MAILHOST, TRACKER_WEB, MAIL_DOMAIN和ADMIN_EMAIL这几项。在我经过看源代码之后,我才知道,这种描述根本就是有问题的。的确,你打开config.ini,你绝对找不到TRACKER_WEB这个配置项。这其实是程序处理后的结果。在config.ini是分节的,每节又有选项。在roundup读到内存之后会将节与选项合成一个项,并且将小写改为大写。因此你看到的TRACKER_WEB其实在config.ini是这样的:

[tracker]
web=http://localhost:8080/support/

这才是真正它应该描述的东西。这样看一看MAILHOST的写法都是错的,应该为MAIL_HOST才对。而且后面还说是按 Python 的语法,因此每个值要用单引号或双引号引起来。如果你这样做,在运行时绝对出错。因为我是我试验的结果。

在不太好的文档指示下,最终没能在同事面前安装成功。最后虽然是装成了,但脸没露成啊。上述的值按照转换前的样子去改一下就行了。

然后下一步是执行roundup-admin init来创建admin用户。

创建完就可以运行了:roundup-server support=demo

然后在浏览器中敲入:http://localhost:8080/support/ 即可看到界面。

更详细的config.ini配置还要看文档。

根据国外开源软件发布的惯例,第二段为偶数的表示是稳定版本。因此说明wxPython步入了一个新的稳定版本的时代,这可能也是一个升级你的wxPython版本的一个信号吧。

看了看更新记录,与2.5.5.1相比没有什么太大的变化。wxStyledTextCtrl有一些调整,加入了直接得到utf-8编码的功能。这一点在 NewEdit 为了实现中文的处理自已已经处理过了。

windows版本的下载链接有些问题,正确地放在这里:

软件:
http://prdownloads.sourceforge.net/wxpython/wxPython2.6-win32-unicode-2.6.0.0-py23.exe for Python 2.3
http://prdownloads.sourceforge.net/wxpython/wxPython2.6-win32-unicode-2.6.0.0-py24.exe for python 2.4
demo和文档:
http://prdownloads.sourceforge.net/wxpython/wxPython2.6-win32-docs-demos-2.6.0.0.exe

2005年04月26日

记得以前写过《开始Blog吧》《开始做个项目吧》,现在我又想建议大家“开始读源码吧”。

Blog是用来表达自已的心得之用,总得有的放矢吧。因此,开始做顶目就是给你找事做的。有了事情,自然好写一些东西了。但光自已做还不行,因为个人的经验毕竟是有限的,需要放眼四方,因此读代码就是另一个可以做的事情了。

有这个想法是由于目前有许多优秀的开源项目,它们很出色,很成功。但对于我自已,也对于中国的大多数 Python 爱好者乃至开源爱好者来说,如何读代码,如何从代码中进行学习,如何把学习的成果保留下来都是一件难事。

好的代码就象读书一样,只有多读,多写笔记才有可能融汇灌通。如果一个项目很大,绝对不是一天两天可以完成的。再加上读得是否准确也是一个问题。如果有可能汇集一些志同道合的人一同来读代码,经常进行交流不也是很快乐的事情吗?我想,读代码是痛苦,但也许比写代码更有意义。写代码许多时候是自身经验的体现,因此代码的好坏与经验的高低可能有关系。而且许多时候,在没有很好设计的时候,写出的代码基本上是乱糟糟,这样子对于自身水平的提高也没有什么好处。读代码可以学习别人的精妙之处,设计的精华,从而提高自已的功能。我想这就象是写文章,教给你许多字你是不是就可以写出好文章来呢?不一定。只有多看别人的文章,最终变成自已的,才有可能写出好文章来。熟读唐诗三百首,不会作诗也能吟。多少可以照猫画虎,有时比起全是大白话可有学问多了。

不管怎么样,读代码,读好的代码的确是一件对自已有好处的事。

不过读代码怎么读,心得如何写,我还真是没有什么经验。读代码本身是很跳跃的,一会看到这,一会看到那。代码有时也很长,一点一滴都写出来,太累,而且有必要吗?你写得心得终究是代替不了原程序的。我觉得,明白清晰的东西可以不用写。比如说一个流程,明明白白的就没必要写。但是特殊的处理,或自身的理解最好写出来。也就是把自已的东西写出来。一方面可以记录下自已的思考过程,也许对别人有帮助,另一方面是对原来可能不清晰的地方的一个补充。

不管怎么样,只要是把你自已真正理解的东西让别人也能看懂的话那就是有意义的,才有讨论的价值。现在时间很紧,真希望可以早些开始。

其实我个人早已经开始了,象 CherryPy 就是一个例子,希望对其它人有用。

中国Linux论坛 论坛中有人提供了一个开源代码阅读的论坛,的确很有趣。如何组织代码阅读与做项目真是没有什么不同,也同样需要组织和协调。只不过更多的是个人理解的问题。如果能够就某些问题产生讨论和辩论,真是很有意思的一件事情(我挺希望辩论的)。论坛可以用来组织,但看程序如果有一个平台是最好的。象我以前做过的翻译与评论网站其实也可以做这件事。大家可以对代码的每个段落发表自已的看法和想法,成熟的想法可以写成文章。想一想,有机会真是要再好好重新实现一下子翻译与评论网站的功能了。

我在 donews 上安家已经很久了,大概一年了。但同时在新浪Blog也有一个用户,那个是朋友给的。新浪Blog处于测试期,想要的话需要激活码才可以。因此可以说新浪的门槛比较高。但并不说明它的功能就强。

在得到新浪Blog的用户后,根据我使用donews的感受(donews还是很不错)提了不少意见。这些意见也都有人回复表示尽快修改。于是一段时间内,我在我的签名中同时留下了我的新浪Blog的地址,同时开始 donews 和新浪Blog一起同步更新。

但时间过去了,承诺没有兑现。可以看出的最后一次新浪Blog版本的更新是2005年3月15日,到现在已经一个月了,什么变化都没有。也许这就是测试版本的缘故吧。因为我了解到新浪Blog团队是自行开发的。曾经与朋友谈起自主开发的问题,我建议为什么不用现在的Blog呢?朋友的回答是新浪Blog将面临广大的用户并发,只有自已做才可以控制。也许这是一个理由,但现在开源的Blog也有许多,并发你也可以去改呀,许多功能为什么还要重头来过。我能做的只是提些建议,仅此而已。

因为有一个帐户,并且提过不少意见,再加上我的性格,在我停止更新新浪Blog后我有时还会去看一看新浪Blog有没有发生变化。但结果是失望的。在建议留言处几乎都是询要激活码的,而且有我说得让人感到…这一招可比当初gmail了。但声势是有了,变化却依旧。管理员对于激活码也只是说尽快会发布一批。

从此一比 donews 比起新浪Blog要好出不知多少倍了。新浪Blog,不知让我说你什么好。我已经把不再更新的新浪Blog地址从我的签名中去掉了。也许我还会继续关注新浪Blog的变化,也许…

邮件列表在大多数人的眼中只是一个讨论的地方,因为它流动快,查找不便,还需要个邮件注册,挺麻烦。但随着 google 和 yahoo 推出的讨论组邮件列表后,事情就变了。我用得最多的是 google 的邮件列表,因为我也创建了一个 Python.cn 讨论组,那是在 python.cn 曾经奇怪的 down 了一段时间建起来的。除了速度慢一些(一封信发出去要过一阵子才收得到),其它功能都非常好。

最近看到 CZUG.org 创建了三个分讨论组,而且打算逐步取代原论坛,这是一个很大的变化,潘兄也预见到了未来的变化,仔细想一想从技术上可能,而且还有诸多的好处,下面谈一谈个人的浅溥看法。

1. 关于注册

论坛也要注册,邮件列表要用邮件注册。差不多,只不过。因此没有邮件使用邮件列表是不可能的。

2. 发言

以前的邮件列表不用邮箱是发不了言的,只要收信人是邮件列表的地址就行了,邮件列表成员谁都收得到。现在有了 google,直接在邮件列表的web 页面上就可以发言,邮箱可以不用了。

3. 显示

google的邮件列表有web 页面,可以象论坛一样将相关的邮件组织成树状线索结构,非常方便。还有搜索功能。与论坛也没什么区别。

4. 精华

这个邮件列表没有。这种操作在google中是由个人通过加“星”来实现的。也就是由你来决定哪些是精华邮件,不再是“斑猪”的权力了。

5. 订阅

有些论坛提供RSS可以订阅。google的也提供。并且有多种选择。

6. 信息的获取

在论坛中,可以使用RSS得到最新信息,可以设置邮件回复得知别的是否有回复信息。使用邮件列表,邮件是必然看得到信息的,还可以使用RSS。基本上是一样的。并且邮件列表可以允许你设置信息获取的方式:如每封邮件单收,或每天收一封汇总的,或不发到信箱只在web上看等等。

7. 管理员

论坛中一般叫版主,邮件列表中叫管理员。权力都挺大的。我就是python.cn的管理员,可以加入新的成员,可以ban人,可以让某个取消订阅,可以改变某人的订阅选项。

8. 其它

有些论坛功能强大,什么头像啦,贴图啦,顶置了,投票了,短信了,功能多多。邮件列表没那么花哨,也显示得界面和内容干净得多。

如果google的讨论组+gmail相配合非常好用。

从上面看出,从技术上讲,使用邮件列表代替论坛完全是可以的,如果你是以功能为主。如果你是以娱乐为主,如贴图论坛什么的,建议还是算了吧。现在python邮件列表也几乎成了论坛了。

另外我还想到的是:google本身的功能和影响力。邮件列表以前不方便的地方就是搜索功能,现在使用google的邮件列表,搜索不是问题。论坛还有就是信息的保存问题,信息多了要占很多的空间。现在没问题,google有的是空间。

看上去怎么象给google做广告呢?这并不重要,重要的是我们可以免费使用。也许google已经融入我们的生活了,这有什么关系,好东西为什么要拒绝呢?入乡随俗才容易生存,百毒不侵就一定好吗?

原本认为 czug.org 分为在三个似乎显多,但上到 czug.org 的主页上看,邮件列表与网站结合非常好,也很清晰,也就不觉得很多了。只不过,如果你只是收邮件的话,是不容易分出来罢了。

2005年04月25日

虽然 Karrigell 的数据库操作简单,但我依然碰到了问题:

  1. 创建表时出错
    表名就是按照我的设计所写的,但发现创建时报错,总是说Group什么的错。我把gadflyStorage改成了sqliteStorage也是一样出错。后来才想到我起的表名 Group 与 SQL 的 group 子句关键字一样了,因此将表名改为Team,结果通过了。
  2. 如何初始化数据库
    使用Storage创建数据库后,可能会有一些数据要初始化。在文档和Demo中可以通过判断db.state的状态来实现。如果state状态为new就表示新建,可以在这个时候来执行一些初始化的操作。那么建库的标志建议为"c"。如果表建得有问题,那么使用"n"就可以删除旧的库而创建新的库。
  3. 记录的__id__
    Karrigell 在使用Storage来创建表时会自动为每个表增加一个__id__字段,这个字段是递增的,用来唯一标识一条记录,非常方便。但它的值我发现是从0开始的,因此要特别注意。要是从1开始就好了。同时__id__为一个整数,因此如果从form中上传这个值的话,要将字符串转成int类型。从这一点来看,如果可以象 Zope 中的对form变量名加类型的处理可能就更方便了。

文档发布系统对文档的处理要求集中体现在用户的管理上。那么主要的需求就是:

  • 管理员可以发布新的文档
  • 用户可以分组
  • 用户可以以个人身份或组身份登录
  • 每个文档可供不同的个人或组进行查看

基本上就这些。从这里看,我要做的文档发布系统对用户管理的要求并不多。相对复杂一些的只是在查看文档时要求多一些,发布文档只能是管理员才可以做的事情。

原本我想象 Zope 一样加入角色(role)的管理,并且可以有一个独立的管理层进行配置。但想来想去,都是 Zope 的模式,也就是用户管理是整个 web 平台自身的一部分,才能很好的实现独立的安全、用户的配置处理。因此我放弃了实现角色的处理。还是集中目标在我要实现的文档发布系统这个实际的系统上来。

从设计上用户管理为一部分功能,权限或功能管理为另一部分功能。

用户管理上将设计:User(用户表)、Group(组表)、GroupUser(组与用户关系表)

User(login, user, password,type)

login为登录用的名字。user为显示的用户名字。type为’u'表示一般用户,为’g'表示组用户。

Group(login, name)

login为登录用的名字。name为显示的组名字。

GroupUser(gid, uid)

那么在创建组时,系统应该自动根据组id在User表中生成一个组用户,这样用户就可以以组的身份进行登录。

在功能上将创建文档与查阅者之间的关系:ArticleUser(文档与用户关系表)

ArticleUser(aid, uids)

uids将是用户id的列表。

这样设计应该可以满足我的要求了。不过也可以看出,这样并不是很灵活,如果以后有变化再改吧,先这样。