星期四, 12月 11, 2008

[tips] 針對特定model改變django ORM預設delete()行為的方法

Django ORM裡的預設delete行為是去模擬ON DELETE CASCADE, 主要是為了保證資料的一致性, 但是雖然在自帶的admin介面裡會提示是否要刪除其他相關聯的資料, 不過仍然可能會對某些需求帶來一些困擾, 而且到目前為止並沒有一個標準的方法來更改這個機制, 這邊我提供一個簡單的方法將model的ON DELETE CASCADE行為改為RESTRICT, 就是在需要不同機制的model裡去override orm原本的delete行為 :

 
def delete(self):
s = CollectedObjects()
self._collect_sub_objects(s)
if len(s.items()) == 1:
super(self.__class__, self).delete()
else:
pass



這可確保當沒有任何關聯物件時才會刪除, 否則只會安靜的pass,
this hack probably need django 1.0+.

星期一, 9月 29, 2008

[link] django-mako

mako template是我除了django預設的template之外,
唯一真的有在product上使用過的template,
mako對於我來說的優點是其簡單非XML的語法,
此外mako無需任何C/pyrex extension,屬於純python的實作,
非常適合在無需django及host上沒有C compiler時單獨安裝。

現在有網友替mako template做了一個django-mako的plugin,
使用mako跟django整合又更容易了。

連結:
mako:
http://www.makotemplates.org/ (LICENSE: MIT)

django-mako:
http://code.google.com/p/django-mako/ (LICENSE: apache 2.0)

星期四, 9月 25, 2008

挺不錯的pyinstall

distutils跟setuptools有些什麼什麼好又有些什麼什麼不好,
其實不少python使用者是心知肚明的,
不過一般來說python programmer除了喜歡pythonic之外,
發佈套件也通常都會遵守發佈python package的標準格式,
發佈setuptools的eggs跟distutils的source tarball
雖然每個python user遵循標準程序的原因未必相同,
不過這似乎已是一種不得不的慣例.

最近在distutils跟setuptools之外出現了新選擇:
Tarek Ziadé的distributeIan Bicking的pyinstall

比較完整也比較吸引我眼球的是Ian Bicking的pyinstall,
一來Ian Bicking的東西向來簡單好用,
二來pyinstall的確解決了一些煩雜的問題,
三來Ian Bicking的社群影響力較大,成為新標準的可能性極高.

pyinstall大致相容於setuptools的easy_install並且提供了一些新的功能跟補強,
我自己認為pyinstall最重要的東西,
是在unix上提供了一個足以取代egg格式的新格式: bundle,
bundle格式有兩個我認為很重要的特點:
第一個就是dependencies include,所有相依的套件全都被放在同一個bundle檔案裡.
第二個是source based.
bundle有點像是一整個相依的freebsd ports或gentoo
ebuild加上其distfiles集合在一起的source整合格式,
所有的source跟編譯及安裝規則都放在同一個檔案裏面,在安裝的同時才進行編譯(.pyc and .so)
所以不像binary格式的eggs需要依版本分2.4的eggs跟2.5的eggs,只要下載同一個檔案就可以安裝了.
當然source based distro/package system的好壞見仁見智, 也會有些限制.
不過至少編譯時間過久這個缺點對於python來講應該是不存在的.
因為大部分的python packages依靠c的部份不多, 另外產生.pyc檔也並不會太慢.

此外pyinstall除了支援同一作者的virtualenv外,
對於整個python環境也有提出了一個解決方法 -- Requirements
事實上對於easy_install base安裝的工具最害怕的就是: 下一次裝不知道其相依的套件還會不會是相同版本.
因為安裝最新版未必是我們最希望的事情, 因為很有可能最新版將我們需要的功能給改變了,我會比較希望能夠有一個版本的控制
Requirements不僅可以由撰寫Requirements file來限制整個相依性的版本,
還可以用pyinstall.py --freeze=require.txt的方法,將整個開發環境的所有python版本套件版號都紀錄下來
方便你移到所以需要新安裝的機器上. 如果再結合上bundle, 幾乎就是非常完美的佈署方案.

pyinstall目前只有0.1.1版, 而且似乎還會有更多加強, 不過我認為這個工具的方便性跟應用的潛力非常大, 值得作個推荐.

更詳細的資訊請參考:

pyinstall:
http://www.openplans.org/projects/topp-engineering/blog/2008/09/24/pyinstall-a-new-hope/
http://pypi.python.org/pypi/pyinstall

distribute:
http://tarekziade.wordpress.com/2008/09/24/distribute-a-setuptools-fork/
http://mail.python.org/pipermail/distutils-sig/2008-September/010031.html
http://bazaar.launchpad.net/~tziade/distribute/trunk/files

星期一, 9月 15, 2008

Django有吉祥物囉!

今年9月6-7日的Django Conf 第一天的最後一個議程是Cal Henderson的Keynote: Why I Hate Django,其中提到很重要的一點: Django沒有吉祥物,Django需要一個具有"Awesome"跟"Magical Powers"特性的吉祥物來作代表。於是在全球Django愛好者的腦力激盪下,屬於Django自己的吉祥物出現囉! 就是avalonstar的Bryan Veloso所設計的這隻可愛的pony喔!






ponybadge

更多django pony的有趣資訊請參考:
http://avalonstar.com/blog/2008/sep/9/web-framework-ponies/

http://code.google.com/p/django-pony/


http://www.djangopony.com/



http://twitter.com/djangopony/

星期四, 9月 04, 2008

Django 1.0 released !!

http://www.djangoproject.com/weblog/2008/sep/03/1/

Django 1.0 released!

1.0是Django project一個很重要的里程碑,因為一直以來官方對於Django 1.0有個很重要的承諾,就是在1.0之後的所有版本都將維持向前相容性,就是不論是到1.x多少版,都將維持對1.0版本程式的相容性而不會再作任何會打破相容性的重大變動。這也是為什麼1.0版本會遲遲不推出的原因。

不過1.0 release的這一天終於來了,
根據Django官方網頁的說法,自從上一個穩定版Django 0.96.2以來,到這次的1.0版本發佈,已經有超過三十五萬行的Django程式碼被修正或改變,足見改變之大。(改動350000行的python, orz)

這次總算是讓我可以使用Django的新版本了,畢竟用了0.95.x跟0.96.x實在是很久了,而Django的SVN trunk對於真的要上線的系統畢竟還是個比較危險的使用方式。不過美中不足的是debian lenny似乎還是會來不及將Django 1.0包進debian linux系統,看來以後安裝上線系統又要多費一番功夫。

想知道更詳細的改變內容跟新增功能請看Django 1.0 release notes

星期一, 8月 25, 2008

coscup 2008遊記

時間過的飛快, 其實感覺去年的coscup 2007似乎才剛結束而已. coscup 2008又開始了,
這次kalug的朋友去了好多, 平常會掛在irc頻道上的至少就有去了一半以上,
一些平常少出現的朋友也都遇到了, 還遇到了一些原本只在irc或網路上看過的前輩跟朋友.

星期六早上雖然有點睡過頭,
不過還是跟lloyd大大坐著高鐵順利的來到了台大應力所的會場,
(走好久啊,難怪有人迷路), 這次小弟我也有準備了兩個20分鐘左右的session要介紹,
主要是簡短的講了一下django跟py3k這兩個有關python的議題,
第一天下午講django時由於臨時因為筆記型電腦接上投影機後畫面出不來,
倉促的商借了yurenju(小朱)的筆電 但是似乎因為是沒有字型的關係,
替代字型其實有點不好看 有些字重疊在一起 不過還是硬著頭皮把他講完了
另外20分鐘其實很短, 所以講的好像有點倉促 主要還是講一些觀念上的個人看法
希望能引起一些朋友對django的興趣.
這場講完後見到了非常客氣謙虛的WilliamYeh葉秉哲大大,跟他作了一些心得交流,
其實我有好幾本他的翻譯書 應該要拿來給他簽名才是.
另外感謝這場大家對我的笑話還挺捧場的,
似乎沒有人睡著,不然講下午第一場實在是有點辛苦,
連我自己都會覺得昏昏欲睡.
下午也有跟freenode irc上#python.tw我們python幫的gasolin, keitheis碰到,
上次coscup 2007跟gasolin聊比較久,
這次gasolin好像比較忙 聊了一下就不見人了
第二天下午我要跟keitheis找gasolin的時候, 就發現人海茫茫 真是難找
這次第二天結束吃飯的時候其實在跟thinker聊台灣pycon下次會不會辦的時候
lloyd有跟thinker提到說, 台灣的pycon其實也可以借coscup BOF的時間來辦,
我也覺得實在應該要排一場BOF讓#python.tw的人互相認親聊天才對.

今天晚上的晚餐是像海浪一樣的pizza海, 兩百五十人份的pizza果然是壯觀,
BOF我是參加我們自己kalug主辦的OpenStreetMap, 拿了一些pizza跟雞翅飲料進場地, 邊吃邊聊.
人比我原先預期的多,陸陸續續大概有三十到四十個左右的朋友來,
BOF內容主要是這次OpenStreetMap的講者louis來講一些josm跟openstreetmap的一些情形.
Arne講到了一些tag標示的東西及提到一些路名中文拼音上的混淆,
lloyd大大講了一些gsm logger支援的狀況. 大家有得吃又有得聊 實在滿不錯的.
不過下次應該要在場地準備一些面紙之類的 不然大家吃東西吃的油油的
又要跑廁所洗手 這樣歡樂的BOF就被打斷了.

晚上跟keitheis,還有我們kalug的lloyd大大,凍翔,
study area的billy回到住宿的飯店, 聽說凍翔跟billy聊到很晚,
keitheis從台南坐夜車上來之後還跑到誠品 另外我跟lloyd大大也很累 所以也就先睡了.

第二天一大早爬起來其實還是有點累 不過早上我有py3k的簡報要報
這次一樣借了yurenju的筆電, yurenju有幫我修改了字型 字型效果就好了不少.
真是非常感謝小朱大力幫忙. Ping長輩一開始介紹我的時候提到提姆之禪,
我自己一時還會意不過來 只有python之禪 我哪來的提姆之禪,
原來他所說的提姆是指曾在python mailing list上有tim bot之稱,
撰寫The Zen of Python (Python之禪) 的Tim Peters, 不是在說我有什麼禪,
Tim Peters其實是python界的傳奇人物之一, 我取ID時的確是沾了他的一點光,
希望我寫的程式也能得到他的庇蔭. (笑)

其實py3k這場講起來感覺時間更短, 有點意猶未盡, 才一下子就被後面的舉牌美眉舉牌了,
不過為了怕影響到後面的講者更精彩的議題, 就講的稍微快了點,
雖然原本就只打算講一些py3k的重要觀念跟想法,
但是還是覺得好像有點倉促, 可能下次繼續在kalug講一場好了, (有人想聽的話 orz)
順便恢復一下據lloyd大大說我老是把20分鐘的投影片講成3個小時的功力 XD

第二天下午的場次時跟以前高中的優秀學弟, Mozilla TW的Bobchao小聊了一陣,
我跟他都覺得雖然很多網友其實平常網路上有所聯絡,
但是辦個實體的聚會其實還是有他的效果, 所謂見面三分情嘛!
irc跟網路上的朋友通常是分散四處的關係 其實平常也很難見到,
人生相逢便是有緣, 珍惜緣份就是一種福氣 不是吗?

晚上跟著一群coscup的大大們,還有kalug在台北的朋友們去吃飯聊天,
不過我因為要趕著搭高鐵回家, 另外chihchunhychen也要先走,
就請shawn順便先送我去車站, 結束了短短兩天的coscup 2008之旅.

我這次的投影片都會放在kalug的這邊,
另外coscup 2008的官方網站之後可能也會有錄影跟投影片的下載,
還請各位前輩朋友多多指教囉.

星期三, 7月 16, 2008

[tips] 淺嘗 lift

lift是個由Scala語言所開發的web framework,由於想試玩一下據說連James Gosling都玩的Scala,索性就試著裝裝看lift,看看有沒有機會在上面開發Web APP。據說Scala在.NET及java平台下都可以執行,不過我試的平台是sun jdk 1.5。

首先先安裝好jdk跟maven2,再來打入這一大串,


mvn archetype:create -U \
-DarchetypeGroupId=net.liftweb \
-DarchetypeArtifactId=lift-archetype-basic \
-DarchetypeVersion=0.9 \
-DremoteRepositories=http://scala-tools.org/repo-releases \
-DgroupId=mytestorm.group -DartifactId=mytestorm.app


這會自動建立一個可連結derby database ,有models的ORM骨架的web application. 最厲害的是maven這個工具連scala,jetty這些你缺的dependency都能幫你裝到好。

接下來可以修改mytestorm.app/src/main/scala/bootstrap/liftweb/Boot.scala將db的connection string改成:"jdbc:derby:mytest;create=true" 這等一下會在我的專案目錄mytestorm.app裡建立一個名為mytest的derby db,再打入mvn jetty:run 就可以啟動webserver了(這裡打入mvn tomcat:run的話會幫你裝好tomcat). 因為lift已經事先幫你建好了model,所以現在連到server的8080 port或http://127.0.0.1:8080,就可以看到一個可以登入的歡迎畫面:





到這邊其實就已經有一點django admin模組的味道了,可以註冊帳號跟login什麼的,
如果用django的術語來講,整個lift的架構也不難解釋,django的urlconf跟settings被放在bootstrap/Boot.scala,
model.py被放到scala/your-proj's-group/model這個目錄裡,template是在webapp裡,template tag在scala/your-proj's-group/snippet裡,view在scala/your-proj's-group/view/,
說來說去,實在也是換湯不換藥,大底上目前的web開發就是如此。

如果你還有興趣的話,可以到抓下lift 0.9的release tarball, 然後解開之後到lift-0.9/sites/example裡,用mvn jetty:run 將example都跑起來玩一玩。裏面有幾個sample還滿有趣的,還包括一個comet的聊天室實作。

稍微玩了一下其實沒啥大感覺,主要覺得lift用的maven工具太複雜了,讓整個開發像在變魔術一樣,老是要找東西被裝到那,反而覺得scala沒什麼玩到,主要都在搞設定,另外mavan在裝dependency的時候整個download的過程都要連到國外總站,要裝的package又不少,導致安裝速度變得有點慢,如果能有台灣mirror應該會好一點。

星期一, 7月 14, 2008

[tips] rewrite debian/ubuntu 's lighttpd conf script from perl to python

Today I want to port lighttpd on another platform which basically a debian sarge system but without perl and dpkg package system on it. Since it's a debian based platform so I start from porting debian's binary lighttpd package, however I've found there're some perl script lays in /usr/share/lighttpd which are used when lighttpd startup.

While I can easily dump the result of perl script into a textfile,
and then startup my lighttpd correctly, I thought "maybe port it to python is not a bad idea." (since my target platform has python!), so here is the effort:
create-mime.assign.py

#!/usr/bin/python
#
# This script directly translate from debian's lighttpd perl script:
# create-mime.assign.pl
#
# Author: timchen119.at.nospam.gmail.com
# License: Public Domain
#
import sys

try:
f = open("/etc/mime.types",'r')
extensions = {}
print "mimetype.assign = ("
for line in f:
line = line.strip()
if line.startswith('#'): continue
if line != "":
splitlist = line.split()
if len(splitlist) < 2: continue
mime = splitlist[0]
for ext in splitlist[1:]:
if ext in extensions.keys(): continue
extensions[ext] = 1
print '".%s" => "%s",' % (ext,mime)
f.close()
print ")"
except Exception,e:
print e
sys.exit(1)


include-conf-enabled.py
#!/usr/bin/python
#
# This script directly translate from debian's lighttpd perl script:
# include-conf-enabled.pl
#
# Author: timchen119.at.nospam.gmail.com
# License: Public Domain
#

import os,glob

confdir = "/etc/lighttpd/"
enabled = "conf-enabled/*.conf"

os.chdir(confdir)

for file in sorted(glob.glob(enabled)):
print 'include "%s"' % file

use-ipv6.py
#!/usr/bin/python
#
# This script directly translate from ubuntu's lighttpd perl script:
# use-ipv6.pl
#
# Author: timchen119.at.nospam.gmail.com
# License: Public Domain
#

import socket

##this sometimes not accurate. (like in vserver mode)
#if socket.has_ipv6:
#

try:
if socket.socket(socket.AF_INET6,socket.SOCK_STREAM,0):
print 'server.use-ipv6 = "enable"'
except:
pass

All of these files can be found in http://kalug.linux.org.tw/~tim/lighttpd-debian-python-script/
Well something quite interesting happened when I port the debian's create-mime.assign.pl into python, It's that my python script's final result is not equivalent to perl one and has more mime types than its :
--- perlmime.txt    2008-07-14 15:29:23.000000000 +0800
+++ pymime.txt 2008-07-14 15:29:33.000000000 +0800
@@ -114,6 +114,11 @@
".dvi" => "application/x-dvi",
".rhtml" => "application/x-httpd-eruby",
".flac" => "application/x-flac",
+".pfa" => "application/x-font",
+".pfb" => "application/x-font",
+".gsf" => "application/x-font",
+".pcf" => "application/x-font",
+".pcf.Z" => "application/x-font",
".mm" => "application/x-freemind",
".gnumeric" => "application/x-gnumeric",
".sgf" => "application/x-go-sgf",
@@ -193,6 +198,11 @@
".pk" => "application/x-tex-pk",
".texinfo" => "application/x-texinfo",
".texi" => "application/x-texinfo",
+".~" => "application/x-trash",
+".%" => "application/x-trash",
+".bak" => "application/x-trash",
+".old" => "application/x-trash",
+".sik" => "application/x-trash",
".t" => "application/x-troff",
".tr" => "application/x-troff",
".roff" => "application/x-troff",
@@ -282,6 +292,7 @@
".tgf" => "chemical/x-mdl-tgf",
".mcif" => "chemical/x-mmcif",
".mol2" => "chemical/x-mol2",
+".b" => "chemical/x-molconn-Z",
".gpt" => "chemical/x-mopac-graph",
".mop" => "chemical/x-mopac-input",
".mopcrt" => "chemical/x-mopac-input",

So I start to dig why this happened, and I've found a strange perl regex filter all these mimetypes out, I believe it's a minor bug in original perl program. (or it does implicitly doing something meaningful? well I can't figure it out.)
--- create-mime.assign.pl    2008-07-14 15:35:58.000000000 +0800
+++ create-mime.assign.pl.new 2008-07-14 15:36:07.000000000 +0800
@@ -7,7 +7,7 @@
chomp;
s/\#.*//;
next if /^\w*$/;
- if(/^([a-z0-9\/+-.]+)\s+((?:[a-z0-9.+-]+[ ]?)+)$/) {
+ if(/^([A-Za-z0-9\/+-.~%]+)\s+((?:[A-Za-z0-9.+-~%]+[ ]?)+)$/) {
foreach(split / /, $2) {
# mime.types can have same extension for different
# mime types

replace this line and this will produce same results as mine.

usage:
just copy these py scripts to /usr/share/lighttpd
and change these lines if you're using debian based system
#### external configuration files
## mimetype mapping
#include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/create-mime.assign.py"

## load enabled configuration files,
## read /etc/lighttpd/conf-available/README first
#include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.py"

星期六, 6月 21, 2008

[link] mysql now use bzr !

http://blogs.mysql.com/kaj/2008/06/19/version-control-thanks-bitkeeper-welcome-bazaar/

又一個重量級軟體投入DVCS的懷抱,
不過我倒是沒預期到mysql會倒向bzr,
因為sun之前的專案如Openjdk,OpenSolaris等, 大多都是用hg,
而mysql被sun買走, 似乎被水銀化的機會很大,
所以這次使用bzr可以說是意外的驚喜.
這麼一來dvcs三強天下三分的局勢似乎已經形成了.

剛好svn 1.5.0也正式release, 如此一來bzr-svn之前不方便安裝的問題也解決了(因為bzr-svn用到了svn1.5.0的python-binding才有的功能, svn1.4要打很多patch, 如今只要升級到最新的svn 1.5就好了),對於我這個bzr的使用者來說可以說是好消息不斷.

另外話說Emacs要從cvs轉換到bzr其實已經講一陣子了,
目前可用的是Jason Earl每小時更新的bzr readonly repo (http://bzr.notengoamigos.org/emacs/trunk/) , 似乎要等到一些merge-history的問題解決後, 官方才會完全轉換過去. (當然這還是未定數, 不過以RMS強烈支持bzr的態度來說, 應該是遲早的事)

星期五, 6月 13, 2008

[link] 有吵有糖吃... Django 1.0 is coming...

根據這篇Roadmap的說法, Django 1.0 會在7月alpha, 8月rc, 9月release. 雖然不知道到底準不準時, 但是"準備好了就會出來"這種話我已經聽膩了... XD

星期四, 6月 12, 2008

[link] django's problem.

http://metajack.wordpress.com/2008/06/11/the-problem-with-django/

基本上我還滿贊同這篇文章的觀點,
事實上我甚至覺得大部分正在開發中的軟體專案都應該建立一個以時程為主的release週期, (即regular release)
而非是現在主要是以功能完成度為主的週期.
因為開發者通常都過於樂觀還有自信太強,
常常低估了完成軟體的時間, 對於沒做過的功能不管聽起來再怎麼簡單都最好還是保守點比較好,
像django的1.0也實在是拖太久了 難怪ticket#2070會被拿出來鞭... 一個http streaming upload 的patch前前後後改了兩年多還是沒進trunk...真不知道是該說追求完美還是太龜毛了... :(

像Ubuntu這樣的release週期我就覺得滿不錯的, 儘管每次的新版變動不會太大, 然後或多或少都會有bug, 但是至少是在建立一個正向循環並且能鼓勵新的開發者投入.

當然還是要說Django真的很不錯就是了. :)

星期二, 6月 10, 2008

Acrobat大冒險.



沒有替Acrobat廣告的意思, 只是發現原來Acrobat比折凳更強.. XD



Acrobat大冒險

[tips] evaluate python dictionaries from file safely.

有時候程式設計師總是會有點奇怪的潔癖,
例如這個讀設定檔的module就是這一類的產物,
說真的python有內建csv,ini跟xml之類的parser,
3rd party的parser也到處都是, 特定情況下其實execfile,exec,eval也都沒什麼錯,如果設定檔可以用.py結尾, 直接import 就可以了,再加上其實python 2.6就要支援direct modify ast tree了...實在看不出有什麼必要硬要用python的parser來讀進設定檔,不過話說回來如果只是想要安全的從檔案裡取出一個dictionary,這個小巧的module倒也不失為一個好方法.

# -*- coding: utf-8 -*-
#!/usr/bin/env python
"""
safe_dict
~~~
The `safe_dict` module helps you read a dictionary from a file using python syntax.

The key and values in dictionary are string only.

File `dict.file` (file which we read dict from) should only contain an anonymous dictionary.

Support only Python 2.5+.

reference:
http://docs.python.org/dev/library/_ast
http://dev.pocoo.org/hg/sandbox/file/08541da989dd/ast/ast.py
http://pyside.blogspot.com/2008/03/ast-compilation-from-python.html
~~~
:Author: http://timchen119.blogspot.com
:license: Python License
"""

from __future__ import with_statement
import _ast
#need python 2.5+

def safe_eval_literal(node_or_string):
"""
Safe evaluate a literal.
"""
_safe_names = {'None': None, 'True': True, 'False': False}
if isinstance(node_or_string, basestring):
node_or_string = compile(node_or_string, "<unknown>", "eval" , _ast.PyCF_ONLY_AST)
if isinstance(node_or_string, _ast.Expression):
node_or_string = node_or_string.body
def _convert(node):
if isinstance(node, _ast.Str):
return node.s
elif isinstance(node, _ast.Dict):
return dict((_convert(k), _convert(v)) for k, v
in zip(node.keys, node.values))
elif isinstance(node, _ast.Name):
if node.id in _safe_names:
return _safe_names[node.id]
raise ValueError('malformed string')
return _convert(node_or_string)


def safe_read_dict_from(file):
"""
Safe evaluate a dictionary from a file.
"""
try:
with open(file,'r') as f:
source = f.read()
node = compile(source, "<unknown>", "eval", _ast.PyCF_ONLY_AST)

if isinstance(node.body, _ast.Dict):
return safe_eval_literal(node.body)
else:
raise
except:
raise

if __name__ == '__main__':
try:
dict_we_want = safe_read_dict_from('dict.file')
except Exception,e:
print e



用法: 只要在你的dict.file裡加上一個python dictionary即可, 就可以用這個module讀入dict.file,為了安全性考量,也只讀入字串.

星期三, 6月 04, 2008

"""習武不是拿來傷害別人的..."""

"""
「習武不是拿來傷害別人的!」陳夆昀(卅七歲)說,被打時他曾一度很火大,曾朝其中一人鼻子出拳,而勾倒另一人後,也起腳要往頭部踹下去,但兩次都忍下來,硬是把拳腳縮回來。

身高一百八十一公分、體重超過一百公斤的陳夆昀,十三歲開始練習各種格鬥武技。民國八十六年被已故日本知名摔角選手「馬場」選為「台灣唯一接班人」,還到日本接受訓練;後來因傷回台,成立「風雲」隨扈公司,在李敖參選總統及藝人林青霞父喪回台時擔任隨扈工作。

二○○二年美國大西洋城舉行的國際職業摔角大賽,陳夆昀以「白獅」身分出賽,僅花了四分鐘,就用自創絕招重創美國好手「愛國者」,拿下台灣第一座世界職業摔角冠軍。

去年八月三日凌晨,陳夆昀騎機車載女友,在板橋市館前西路四十六巷,與正在倒車的徐祥恩(廿八歲)、黃梓曦(廿八歲)擦撞,當時陳夆昀與女友未受傷,機車受損輕微。陳夆昀說,原本不想追究,徐祥恩卻持鋁棒攻擊,黃梓曦也對他揮拳毆打,兩人還警告他「如果敢報警,就到醫院堵你」。

陳夆昀說:「如果我真的出手,我擔心被害人變成他們。」他要保護女友,才用左手格擋,「我算一算,左手大概擋了五十多下鋁棒,手才斷了」。

後來陳夆昀提出傷害、恐嚇告訴,檢方起訴徐、黃兩人,並具體求刑七月。

板橋地院昨天開言詞辯論庭,徐、黃否認恐嚇,陳夆昀的辯護律師才揭露陳夆昀世界職業摔角冠軍的背景,並稱因他有體格優勢才不致受重傷,若一般人可能會被打死。兩人得知打的是世界摔角冠軍,甚感訝異。公訴檢察官以徐、黃兩人下手兇殘,又不知悔悟,當庭加重求刑至十個月有期徒刑。
"""

轉自聯合新聞網

看到聯合新聞網的新聞, 覺得這位陳夆昀實在真了不起.

令人打從心底佩服. 這才是真強者啊...

要我是世界職業摔角冠軍大概就會搞個炸彈摔然後徒手把對方劈成兩半再扔到垃圾筒了...

還好我只會摔車還摔的不大好看 XD

==

突然想起國小那位很兇的老師常講的話: "讀書不是爽就好..." 嘖嘖...

星期二, 6月 03, 2008

[tips] add bzr sftp support when you have no compiler on target platform (pure python )

bzr depends on paramiko to provide sftp support. While paramiko itself is pure python, its dependency pycrypto is not. PyCrypto have lots of C-extenstion and you'll need a compiler to install it. However since we only use part of pycrypto (to have sftp support for bzr), we could just add some stub files to prevent the [deploy] problem.

I have made a modified pure python version pycrypto and packaged it with paramiko 1.7.3, so after you installed bzr (use standard python setup.py or easy_install), you just extract paramiko-1.7.3-bzr-sftp-purepy.tgz
at your python site-package directory (make sure you don't have paramiko and pycrypto already exists, if you do, you don't need to install this package anyway) and happy bzr...!

This also makes bzr only depend on python so you could easily deploy it on a machine which doesn't have c compiler and still have sftp support.

Warning: this pacakage only add bzr sftp support and provides nothing besides this, and these COULD break other python packages which also used paramiko and pycrypto, so don't use it if you don't really need it. And the only tests I've done is on my own (embedded linux) machine, Basically it's just for my own use, I have warned you.

星期二, 5月 06, 2008

[tips] 如何讓你的ext2/ext3在神出鬼沒的地雷戰場上存活.

喜歡用自由軟體的人其實應該都滿常遇到地雷,
通常也練就了一身人間即時掃雷機的本事,
但有些時候實在是地雷太小顆 (但是倒炸的很大力),
又發生在想都想不到的地方, 要讓人不嗚呼哀哉也難.
就像開車時你不超車會有別人超車,
你不想用新版會有別人用新版,
軟體相容性的問題往往是會不請自來的.

lloyd大大今天跟我說了一個最近踩到地雷的故事,
他拿了一顆用ext2格式化過的400g硬碟,
拿到他弟弟灌了ext2 driver的windows上執行,
之前好一陣子都能讀取寫入, 操作上都沒問題,
最近卻怎麼格式化都不能用.
(在windows上會問你要不要重新格式化)
換了小一點的硬碟也不行. 最後他深入追查才發現es2fprogs這個最近更新的套件更新了mkfs.ext2這個程式, 預設的inode改變成256 bytes. 所以要用
mkfs.ext2 -I 128 讓預設的inode設成原本的128 bytes.

ok問題解決了, 聽起來只是windows ext2 driver跟e2fsprogs相容性的問題對不對?
但仔細一想問題可能就很大了, 今天你在debian lenny格式化了一顆ext2硬碟, 要放到穩定的重要server上(恰巧是debian sarge),卻不能讀了.
今天如果你沒有"恰巧"讀到這段,


E2fsprogs 1.40.5 (January 27, 2008)

Fix a potential overflow big in e2image if the device name is too long.

Mke2fs will now create new filesystems with 256 byte inodes and the ext_attr feature flag by default.
This allows for much better future compatibity with ext4 and speeds up extended attributes even on ext3 filesystems.

並把他放在心上的話, 你很可能就炸掉了.
(不過事實上可能就算你讀到這段也還是會被炸掉...)

此外/boot通常有人會用ext2而非格式化成xfs或raiser3什麼的(甚至連ext3都不用, 因為穩定),也免不了會踩到這個雷,
這裡"恰巧"就有個血淋淋的例子. (GRUB vs. the Inodes: Who Needs a Bootable System, Anyway? ) 喔, 只是不能開機而已嘛...orz

備註:
e2fsprogs version:
Gentoo-stable: 1.40.8
lenny (next debian stable): 1.40.8
etch (debian stable): 1.39+1.40

重要指令:

mkfs.ext2 -I 128 /dev/???
mkfs.ext3 -I 128 /dev/???

如果你還要向前相容性的話, 從現在開始別忘了mkfs.ext3時加上-I 128 , 否則... 就歡樂的炸吧... XD

感謝lloyd大大更正: 在debian etch (kernel 2.6.18) 上應該還是可以讀取256 bytes inode的格式, sarge是2.4 kernel可能就不行了. (根據mkfs.ext2的man page說法是2.4 kernel會沒辦法mount)

update: fix link.

星期二, 4月 22, 2008

[tips] poorman's uudecode

For those who cursed by ash and awk, welcome to 80's !

now you can send everything in ASCII -- hooray!!

#!/bin/sh
#
# uudecode.sh
#
# Author: Ximian, Inc.
#
# Modified: by timchen119 at http://timchen119.blogspot.com from Ximian go-gnome's GPL code
#
# Usage: uudecode.sh encodedfile > decodefile
#
# License: GPL
#
# Download: http://kalug.linux.org.tw/~tim/gpl/uudecode.sh
#
# Ref: http://ftp.cesnet.cz/pub/ximian-gnome/installers/go-gnome
#
# The Ximian Desktop Pre-Installer
#
# Comments to:
# distribution@ximian.com
#
# Copyright 2000-2001, Ximian, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
# USA.
#
#
# This script and its embedded programs are distributed with
# absolutely, positively NO WARRANTY WHATSOEVER, without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. The author and Ximian, Inc. take no responsibility for
# the consequences of running this script.
#
#

CACHEDIR=/tmp
_awk="awk"

# poor man's uudecode
_awkprog="$CACHEDIR/uudecode.awk"
# encoded file
_uudecode_in=$1

#awk-script
cat > ${_awkprog} <<EOF
function x(l, p) {
n="!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_";
return index(n,substr(l,p+1,1));
}
/^begin/ {}
/^[^be]/ {
len = x(\$0, 0);
for (i=1;len>0;i+=4) {
a=x(\$0,i);b=x(\$0,i+1);c=x(\$0,i+2);d=x(\$0,i+3);
printf("%c",a*4+b/16);
if (len>1) {
printf("%c",b*16+c/4);
if (len>2) {
printf("%c",c*64+d);
}
}
len-=3;
}
}
EOF
${_awk} -f ${_awkprog} < ${_uudecode_in}
rm -f ${_awkprog}


get uudecode.sh at here.

[funny] [links] [kuso] Python がイマイチ人気にならないたった一つの理由

http://d.hatena.ne.jp/seiunsky/20080417/1208454191

話說不小心點到這... 原本還想認真看看理由的... 結果... @@


1. 日本Python的入門書不好 !?


* 「最初(に読むPython本)はみんPyだよねー」

==> 「最初はみんなおっぱいだいすきからスタートする」

2. 著名書商 O'reilly 也很糟糕 ?!


* 「おれ、今Pyチューで勉強してるんだ!」

==> こんなセリフを女子に聞かれたら間違いなく「おっぱいにチューして何の勉強をしているの!へんたい!」と思われるのですから、これは本当に卑猥ですね。

3. PyPy實作不好 !?

* 「おれ、いま PyPy の開発してるんだ!」
* 「ただの人間には興味ありません。PyPy 開発に興味のある人は私のところに来なさい!以上!」
* 「PyPyを高速で動かす方法を思いついた!」

接下來就開始把python跟おっぱい扯在一起的大爆走了 XD (pychinko, Dive Into Python... 原來Python是完全的成人向啊...orz)

星期二, 4月 15, 2008

[tips] upgrading to gentoo 2008.0

Well just as usuals, you can upgrades to gentoo 2008.0 quickly. (beta?)

#eselect profile list
Available profile symlink targets:
[1] default-linux/x86/2006.1
[2] default-linux/x86/no-nptl
[3] default-linux/x86/2006.1/desktop
[4] default-linux/x86/2007.0
[5] default-linux/x86/2007.0/desktop
[6] hardened/x86/2.6
[7] selinux/2007.0/x86
[8] selinux/2007.0/x86/hardened
[9] default/linux/x86/2008.0
[10] default/linux/x86/2008.0/desktop *
[11] default/linux/x86/2008.0/developer
[12] default/linux/x86/2008.0/no-nptl
[13] default/linux/x86/2008.0/server
[14] hardened/linux/x86

For my case, just type 'eselect profile set 10'
and emerge world again.

I'm not migrating to OpenRC and baselayout2 yet, however I'm using KDE4.0.3 now, so I think I have enough un-stable-ness to worry about. ;0

[tips] using pyrex to do the argv[0] trick in linux using python.

A trick to rename python process in output of 'top' and 'ps'.


set_argv.c:

#include
#include
#include

int get_argc(){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
return argc;
}

void set_argv_via_number(int num,char *str){
int argc;
char **argv;
Py_GetArgcArgv(&argc, &argv);
strncpy(argv[num], str , strlen(str));
memset(&argv[num][strlen(str)], '\0', strlen(&argv[num][strlen(str)]));
}


set_processname.pyx:

#Warning: this module is not safe and may involve some dirty hacks.
import sys,dl,glob
cdef extern int get_argc()
cdef extern void set_argv_via_number(int num,char *buf)
def set_argv0(thename):
set_argv_via_number(0,thename)

def set_argv(thename):
argc = get_argc()
print argc
for i in xrange(argc+1):
if i==0:
set_argv0(thename)
else:
pass
def set_name(thename):
if sys.platform == 'linux2':
# Set process name. Only works on Linux >= 2.1.57.
try:
libc_loc = glob.glob("/lib/libc.so*")[0]
libc = dl.open(libc_loc)
libc.call('prctl', 15, thename, 0, 0, 0) # 15 is PR_SET_NAME
except:
pass

def set_processname(thename):
space_padding_num = len(sys.argv[0])-len(thename)
if space_padding_num < 0:
#thename is longer than original name
newname = thename[:len(sys.argv[0])]
else:
#thename is shorter. add padding.
newname = thename + " " * space_padding_num

set_name(newname)
set_argv(newname)

compile.sh:
#!/bin/sh
CC=mipsel-linux-gcc

pyrexc set_processname.pyx
$CC -c -fPIC -I/usr/include/python2.5/ set_argv.c
$CC -c -fPIC -I/usr/include/python2.5/ set_processname.c
$CC -shared set_argv.o set_processname.o -o set_processname.so

[tips] building psyco on non-x86 platform. (ie. linux mips little endian)

The trick is to build psyco in ivm mode. The mode slower than the native mode(ivm mode involves a prolog generated-vm, you guess), however it's the only way to compile psyco on non-x86 system. And cross-compiling with distutils is not a trivial stuff, so I just compile it directly.


mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/psyco.c -o build/temp.linux-mipsel-2.5/c/psyco.o
mipsel-linux-gcc -pthread -fno-strict-aliasing -DNDEBUG -fPIC -DALL_STATIC=1 -Ic/ivm -I/usr/include/python2.5 -c c/platform.c -o build/temp.linux-mipsel-2.5/c/platform.o
mipsel-linux-gcc -pthread -shared build/temp.linux-i686-2.5/c/psyco.o build/temp.linux-mipsel-2.5/c/platform.o -L/usr/lib -lpython2.5 -o build/lib.linux-i686-2.5/psyco/_psyco.so


This generates the C-module extension, and just copy all of py files to correct path and enjoy psyco speed-up! (well, not quite a case for me. It just use way too much memory on our embedded system. But I think maybe it'll useful in other project.)

ps: I should mentioned that I'm doing this on a uclibc linux system.

[tips] if as a pure function in python

http://okmij.org/ftp/Scheme/if-function.txt

here is a trick that we could rewrite a customized not-a-special-form IF in python.


iftrick.py:

#!/usr/bin/env python
def func_true():
print "true!"

def func_false():
print "false!"

def my_if(my_cond,then_func,else_func):
eval((then_func, else_func)[not my_cond].func_code,vars())

condition = True

my_if(condition,func_true,func_false)

condition = False

my_if(condition,func_true,func_false)

===
#python iftrick.py
true!
false!

星期三, 2月 06, 2008

Am I getting old or ....The lenny is coming this year???

根據 http://lwn.net/Articles/267722/的說法,

下一個版本的 debian (lenny) 將在今年9月release.

這可真是出乎我預期的快... etch... 不是去年四月才出的嗎?

**<小孩勿看>** 大便 難道真的落屎了嗎? **< / 小孩勿看>**

然後話說 /bin/sh link to dash 有了ubuntu帶頭衝之後 還真的debian就跟進了.

我的預言(詛咒)成真?! 看來lloyd大又要怨恨了 :P

(話說 難道再下版inittab也是難逃upstart之手了嗎??? ...有待下回茅房分解...)

這一行果然是很難混的啊.... XD

還有python 2.5.X 啥時要給我進default啊... 時間也該到了吧...

星期四, 1月 31, 2008

Arc is released. and is it a Blub?

http://arclanguage.org/

這兩天幾乎網路上所有lisp programmers都在討論Arc,
這個著名lisp hacker, Paul Graham所發明的lisp dialect, 一度被認為是vaporware的語言,在前天release了.

Paul Graham對於lisp社群的貢獻是無庸致疑的,
但這次他所公開release的Arc則是讓不少人大失所望.
畢竟這是他從他首次宣稱Arc is a better lisp以來已經過了6-7年之後釋出的版本,
"just another lisp dialect"似乎是不少lisp programmers的一致意見,
另外此次版本不支援unicode只支援ascii也引發大波瀾.
我自己最近時間不多, 但也小試了一下, and just didn't 'get' it.
我當然理解PG的"Syntax Do Matters",
但我也不完全同意less typing是higher level programming language唯一的路,
非常希望時間能證明, 這只是我們這些 "Blub" programmers的愚昧, 而Arc is indeed a better lisp and a better programming language.

註: Blub是PG發明的字眼. 在著名的Beating the Averages一文裡用來回答一個有趣的問題: "如果lisp這麼好,為什麼都沒人用?" 而描述出一個所謂的Blub弔詭的情境:
Blub是任一種介於比lisp低階 而比machine language高階之間的一個一般強度(power)的程式語言. (比如: python,java,ruby,perl,C/C++,haskell,ML-family,erlang,php,javascript,fortran,cobol.....anything not in lisp-family)
Blub programmer則是Blub programming language的支持/使用者,
Blub programmer的想法是, Blub語言 擁有某些特性X,
他無法想像更低階語言怎麼能夠沒有特性X而能拿來認真的使用.
同一時間他則認為Blub語言已經擁有所有他所需要的特性, 覺得所有比Blub語言更高階的特性全是無用而浪費時間的.

註2: 我的標題意思是Paul Graham在文章裡說他自認為他的Arc語言已經好到可以讓他不想用CL或scheme才release了, 是否也是陷入了Blub弔詭裡?

btw: you need patches to run current Arc on latest mzscheme(352+) or you're on windows(sadly),
see http://arclanguage.org/item?id=319 and http://jfkbits.blogspot.com/2008/01/digging-into-arc-in-24-macros-or-less.html

星期一, 1月 07, 2008

Python: programming language of 2007!

January Headline: TIOBE declares Python as programming language of 2007!

"""
Python has been declared as programming language of 2007. It was a close finish, but in the end Python appeared to have the largest increase in ratings in one year time (2.04%). There is no clear reason why Python made this huge jump in 2007. Last month Python surpassed Perl for the first time in history, which is an indication that Python has become the "de facto" glue language at system level. It is especially beloved by system administrators and build managers. Chances are high that Python's star will rise further in 2008, thanks to the upcoming release of Python 3.
"""

well, the reason is so obvious to me...it's all about gravity thingy ;)