用 Microsoft Translator API 翻譯 properties 檔案

因為另外一套要錢,所以來用 Microsoft Translator API

#!/usr/bin/env python

# coding: utf-8

import urllib
import sys
import xml.dom.minidom

# Get Bing AppID from https://ssl.bing.com/webmaster/developers/appids.aspx
BING_APPID = 'KERO~'

FILE_FROM = 'lang.properties'
FILE_TO = 'translated.properties'

LANG_FROM = 'en'
LANG_TO = 'zh-chs'

def translate(text, from_lang, to_lang):
    base_url = 'http://api.microsofttranslator.com/v2/Http.svc/Translate?'
    data = urllib.urlencode({'appId':BING_APPID,
                             'from': from_lang.encode('utf-8'),
                             'to': to_lang.encode('utf-8'),
                             'text': text.encode('utf-8')
                            })

    url = base_url + data
    response = urllib.urlopen(url).read()

    dom = xml.dom.minidom.parseString(response)
    result = dom.documentElement.childNodes[0].nodeValue

    return result.encode('utf-8')

def parse_properties(filename):
    langs = {}
    with open(filename, 'r') as f:
        lines = [ line.strip() for line in f.readlines() ]
        for line in lines:
            idx = line.find('=')
            if idx == -1:
                continue

            (key, val) = (line[:idx], line[idx+1:])
            if not key:
                continue

            langs[key] = val

    return langs

def main():
    langs = parse_properties(FILE_FROM)
    translated = { k: translate(v, LANG_FROM, LANG_TO) if v else ""
                   for k,v in langs.items() }

    with open(FILE_TO, 'w+') as f:
        for k,v in sorted(translated.items()):
            f.write("%s=%s\n" % (k,v))

if __name__ == '__main__':
    main()

隨手寫寫,一年沒寫文章,也許有點刻意,差不多該是改變的時候了。

關於 Agile 我想說的是

坐在床上,老實說我沒想到在連續忙了好多天之後,還想打出這樣一篇混亂而隨性的文章。

有時候我覺得瘋狂,或是覺得難以想像,耳邊忽然冒出許多像是 Agile, Scrum 這樣嶄新的名詞,許多工程師、或是 Project Manager 開始上這些「認證」的課程。所以我身邊多了一些 Scrum Master,或是一些帶領工程師進入新 process 的人。 Continue reading

去那更遙遠的地方

遺忘之後,然後遠行

你在凝望些什麼?
是那車水馬龍轉眼消逝的既視記憶,
又或者是內心底部那沈澱莫名的空靈感。

我說或許,
我(或者我們)都只是必須離開。
如果必須如此,
那我們絕對必須以極盡歡愉(甚至狂喜)的腳步跳躍著吧!
因為,
我們將奔向另一個遙遠的國度。

於是我在你面前駐足,
以這張相片,
簽署我們遠行的約定(即使形式並不完全)。

Farewell,my friend
再會了,另一個旅人。

Use VERSIONER_PYTHON_PREFER_32_BIT=yes in Snow Leopard

In python, you can use ctype (dl is deprecated now) to load dynamic link library. In 10.4 and 10.5 it may work fine, but it may occur errors in 10.6, such as

/Library/Frameworks/dummy.framework/dummy: no matching architecture in universal wrapper

Since the python in Snow Leopard is 64-bit in default, for those libraries which does not support 64-bit. You can test your library by

% file /Library/Frameworks/dummy.framework/Versions/Current/dummy

If you library is i386 only, you may need to handle it in this way.

% export VERSIONER_PYTHON_PREFER_32_BIT=yes
% python your_script.py

ericsk has also mentioned this for wxPython in his plurk

For more information, you can read the man page in your Snow Leopard.

Using minimock for Python unit testing

我也忘了什麼時候開始習慣作 unit testing 了,可能是前一個專案在 Xcode 上就開始學著寫一點測試了。

這次在閱讀 Writing Testable Code 對於 6. Static methods: (or living in a procedural world),格外有感覺。

尤其是修改別人的程式碼的時候,如果他總是直接呼叫 static method,不讓你用 mock object 把 implementation 換掉的話,這樣在測試起來就顯得麻煩的多。舉例來說,有一個 class method 會呼叫 SSHHelper.execute_ssh 這個指令去遠端執行一些東西,但這對 unit testing 而言就是一種外部的 dependency,你絕對不希望他真的在測試的時候跑出個 ssh 真的連過去執行些什麼吧。

剛好這次用 MiniMock 作我們的 mock library,因為他的因素,你就可以這樣作

minimock.mock('SSHHelper.execute_ssh', returns=ssh_output)

如此一來,execute_ssh 這個 method 的結果就可以簡單的換成你預期的 ssh_output。

如果是本來就有比較好的設計的話,你也可以用 minimock.Mock (注意大小寫),去產生一個 mock object 出來。

mock_fs = minimock.Mock('MockFileSystem')
mock_fs.size.mock_returns = 1
mytools.fs_imp = mock_fs

如此一來 mock 就顯得簡單多了……

話說回來,之前想寫的 objective-c 跟 DTrace 的 topic 真的都忘的差不多了,算了,以後再說吧,也許之後把 python 的 Exception Chaining and Embedded Tracebacks 的想法整理一下再丟出來吧。

Hide Menu Bar in Firefox 3.6

Firefox 3.6 開始可以隱藏 Menu Bar 了,所以這樣再搭配上 Tree Style Tab,整個可視範圍就大了起來!不過,也因為這樣,這次主打的 Pesonas 在這種環境下就顯得很無奈了,能妝點的範圍太有限了……。

My Firefox 3.6

接著等著看,HTML 5 能改變世界多少,看什麼時候會真的有 File API 的服務出來。

Media Temple 小感想

原本的網站(不是這個 blog)放在國內某家知名的主機商,因為每個月都在付超流費,再加上曾經傳出客戶資料外流的問題,所以我們就決定把現在的網站搬到 Media Temple。流量跟 storage 一次到 1000GB 跟 100GB,一年刷下來 200 美金,乾脆省事。

從 9 月底租到現在,大概也差不多三個月了,覺得他還算穩定,還可以讓我用 SSH 連進去,再用 rsync 去 deploy 一些東西(也方便用 rsnapshot 去備份)。再加上可以依照 domain 開不同的帳號,讓我們把 admin 帳號跟 domain 帳號隔開,對於現在的使用上其實也很方便。

不過最近爆出來的一些 security issue 讓人覺得很無言,像是官方 blog 的這兩個 issue
#1047 Cluster.05 Storage Segment 1
#1026 (gs) Security Advisory

Twitter 也有爆出來
http://twitter.com/macgillavry/status/6497221013
http://twitter.com/mdravnieks/status/6491481100

然後因為放在美國的關係,過去大概也要 150ms,對於 response time 來說是蠻高的,就現在來說,我也只能對 YSlow 有的東西修一修,支援一下 deflate,把 expire 設定起來,然後 CMS 能做 cache 的先上一下,要 compress 的 js 跟 css 丟給 Closure 看看會不會好一點。

不過最近 web 偶爾就給我連不上,不知道是怎麼樣,也許弄個 mtr 跟 httping 來監控看看吧。

現在我們把影音的流量也分一部分到 vimeo 上,也許一年之後再評估看看,到底哪邊比較適合我們吧。