Fork gedit-git-plugin

gedit-git-plugin 這個 plugin 不錯,就類似 vim-gitgutter 的功能,但是它用的是 libgit2-glib,這個還真麻煩,所以就 fork 出來改,看可不可以擺脫 libgit2-glib。

為此,我先讀了 vim-gitgutter 的程式,vim-gitgutter 主要是在 GitGutter 函式裡,這邊會先去 git diff,然後解析結果,再去作畫面的處理,gedit-git-plugin 也很類似。

程式主要是在 viewactivatable.py ,在啟用 plugin 的時候,會觸發 do_activate(),這時會去繫結相關的事件到程式裡。主要的處理在 update_location(),這裡就調用 libgit2-glib 函式庫去取得 git repository,然後再取得當前檔案的 blob ,最後再去呼叫 update();update() 是在做檔案比對,根據比對結果去顯示,這裡的比對用的是 python 內建的 difflib,而不是用 git diff 的結果。

分析完,大致知道要處理的部份就在 update_location(),只要這裡將使用 libgit2-glib 改為用 subprocess 呼叫 git 取得結果就可以了。第一個要做的事情是取得當前檔案的位置,這個只要套原來的程式,呼叫 self.location.get_path() 就可以。接著要去找 .git 資料夾,這邊我參考了 repo 裡找 .repo 的函式去找 .git 。基於以上兩者,可以取得相對於 .git 所在路徑的檔案路徑,也就是假設 .git 是在 /home/user/project1/.git ,編輯的是 /home/user/project1/dir1/readme,就可以得出 dir1/readme,接著只要用 git show HEAD:dir1/readme 就可以取得原始 blob 內容。依照原來程式的邏輯,把原始 blob 內容替換為 git show 程式的輸出之後,就可以擺脫 libgit2-glib 了!

最後,將 git.plugin 裡的 Loader=python3 改為 python ,再更新 README 並補上 setup.py 就收工了。現在就不用 libgit2-glib 啦~

我 fork 出來的專案放在 github 上。

activemq 的 persistent

因為希望 ActiveMQ Queue 裡的東西在重新啟動後還能存在,就特別做了實驗,結果真的 Queue 裡的東西會消失。

查了很多的文件,也試了不少設定,像是在 broker 裡設 persistent=”true” (預設本來就是 persistent) 或是加了 jdbcPersistentAdapter 等,都不行,後來才發現是 stompest.async 這邊在送的時候,得特別在 headers 裡加上 {‘persistent’: ‘true’} 才可以讓訊息保存在 Queue 裡。

程式一樣是用官方的範例,主要修改的地方在 producer.py:[python] yield client.send(self.QUEUE, json.dumps(
{‘count’: j}), headers={‘persistent’: ‘true’},
receipt=’message-%d’ % j)
[/python]

這次找資料也找到不少解說 ActiveMQ 的文件:

activemq 與 python stompest.async 的安裝

簡單的進行幾個 MQ 的比較之後,決定用 ActiveMQ,原因是因為它使用 Java 編寫,在佈署上顯的比較簡單,只要下載下來,有 JDK 就沒問題了。

要搭配 STOMP 的話,得修改 conf/activemq.xml ,找到 transportConnectors 節段,加入:
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613"/>

以前景模式啟動的話,是輸入 bin/activemq console,當作 daemon 啟動的話,是輸入 bin/activemq start 。
用 STOMP 的話,依照 Apache ActiveMQ 網站上的說法,會比較缺少安全性,所以會建議搭配 SSL 或 NIO [2]。

Python 的部份,我是直接使用 stompest.async,它是建構在 twisted 之上,這個用 pip 安裝就可以。範例我是參考 stompest.async examples

範例沒什麼問題,接下來就是要熟悉跟了解如何使用了。

參考資料:

  1. STOMP protocol
  2. activemq Unknown data type: 69

將 python package 快速打包為 debian package – stdeb

這兩天看到 clonedigger,這是一個可以找尋程式裡是否有相似重複片段的工具,在找到重複的片段以後,就可以加以重整。老樣子去 ubuntu ppa 找了一下,發現沒有人打包,那麼就只能透過 east_install/pip 來安裝或是自己打包了。

這次就試著自己打包看看。

一般 python package 都會提供 setup.py ,這是使用 python 內建的 module:distutils 來建立的,在官方 distutils 的文件有提到使用方法。裏面就已經提供了打包為 RPM package 的選項,但是就沒有 debian packages。上網找了一下,這篇 Python distutils – does anyone know how to use it? 提供了不少可以參考的文件,循線找到這篇 Standard way to create debian packages for distributing python programs? ,裏面提到了 stdebstdeb 可以透過 easy_install/pip 來安裝,很幸運的是我的 Ubuntu 12.04 剛好有打包這個進去,所以只要用 apt-get 安裝 python-stdeb 就可以了。

接著,就可以參考 stdeb 文件,用 python setup.py –command-packages=stdeb.command bdist_deb 建立 debian package 了,打包好的 debian package 可以在當前目錄的 deb_dist 下找到。

教育部電子辭典轉星際譯典(stardict)字典檔心得

大約在4月底的時候,在 http://3du.tw 上看到還文於民的活動,就認領了轉換字典檔為 stardict 字典檔的工作。

首要的工作就是瞭解字典檔的格式,stardict 字典檔可以從很多格式轉換,像是 XML、Tabfile 等等的。轉換的工具已經有提供了,安裝 stardict-tools 套件以後,就有一堆工具放在 /usr/lib/stardict-tools 下,也有提供 GUI 工具 (stardict-editor)。

我最早是想用 XML 格式 (Textual Dictionary File Format),所以我就利用工具將現有的字典檔轉換為 XML,並且參考文件,來寫程式產出檔案,結果並不順利。即便是一個只有一個詞的檔案,轉換為字典檔以後,stardict 也無法辨識到。

後來就使用最容易,而且網路上最多人分享的 Tab file format。格式很簡單,詞與說明用 Tab 字元分隔,說明裡如果有需要換行或是做排版,可以用 \n  \t 等逸出字元來排。

程式則是用 python 來撰寫,主要使用 jinja2 來配合模版產出詞與說明,用 multiprocessing 模組善用 CPU 資源,程式放在 https://github.com/elleryq/moe2stardict 。以下記錄一下我有遇到的問題跟解決方法:

  • 使用 multiprocessing 時無法使用 profiling,上網 Google 的結果,都是建議要先在單一 process 的情況下去 profiling ,解決問題以後,再來搭配 multiprocessing。
  • 在執行程式時,所花費的時間一直很長。我是等到完成的都差不多時,才看這問題。用 profiling 去查看,才發現問題出在 jinja2 上,我把初始化模版的程序放在迴圈裡了,導致每處理一個詞都要初始化一次,非常浪費時間,大約要十分鐘以上。當我把這初始化的程序移出迴圈以後,速度提昇了超過十倍以上,不到一分鐘就執行完畢。
  • 同理,我也把 regular expression 的 compile 移到程式的一開始就執行,避免在會被多次呼叫的函式裡去 compile。
  • http://3du.tw 所提供的 json 原始檔裡有些像 {[8e41]} 的字元,沒有顯示出字來,發信件到 g0v.tw 聊天室問,唐鳳回應說,直接把這些字先忽略掉就好,這些字是異體字。所以我就把這些忽略掉了,非常謝謝她的回應。

目前我只有做國語辭典的轉換,其他還有客語、台語、成語的部分,就看之後有沒有人認領了,或者是等有空的時候再來弄。不過說真的,現在用 stardict 的人應該不多了吧,stardict 專案開發進度在原作者 hu zheng 失蹤後,僅在今年初有釋出 3.0.4,修正幅度不大,也沒有新功能。很多都建議轉用 goldendict,幸好 goldendict 也吃 stardict 字典檔,所以我這不算是做白工。

PySide – Custom Label

自訂 QT Widget 的練習,網路上關於 PySide 的教學文不多,所以是找 C++ 範例文章來試著轉換為 PySide 看看。基本上還蠻簡單的,就是一些函式要去查查 QT 文件。

不囉唆,直接貼 code。

PyCon 2013 Day 2 記錄

5/25 因為大公子要登記入學,二公子學校有活動的情況下,就直接放棄了,聽朋友說,第一天的晚宴跟 Lighting talk 很歡樂。

行前一直在想要怎麼過去南港,想了很久,決定還是走以前去南港的路,走寶橋路到木柵路,左轉往焚化爐的路,到崇德公墓,再走研究院路,經過中華科技大學,然後到胡適公園。快到胡適公園的時候就一直在看停車場跟側門,還真的被我看到。側門的對面就是胡適公園,再往前一點有停車場,機車停車場沒管制,所以我就大剌剌停進去,從側門步行進入。

在中研院區往人文會館的路上,我看到有人在拍鳥,我抬頭看看,想知道鳥是什麼樣子,看了一下,就繼續往前走。想不到突然頭皮一陣劇痛,有翅膀拍擊的聲音,是鳥!! 我摸摸頭,加快腳步,經過愛鳥攝影師時,他說,可能是因為我經過鳥巢,它感到危險,才攻擊我。唉,只能當作是好兆頭囉。繼續往前時,就看到有會眾往人文會館,就跟著走。

登記完,領到袋子跟東西,就往前天已經想好要去的 R1 會議室走,早上就都待在 R1。中研院的會議廳設備很不錯,有有線網路也有無線網路,網路都很暢通,位子旁邊也有插座。如果說真的要抱怨什麼的話,大概就是沒有飲料紙杯,下次如果要再去,我會記得帶杯子去的。

第1場的 Allen Downey 是 Thinking Python, Thinking Stats … 等書的作者,他分享他用 Python 以後的一些心得,主要是說他的思考模式慢慢 Python 化,像是統計等等的,可以當作虛擬碼來用,而且可以執行,很方便。在 R1 沒辦法播放投影片,工作人員有來通知說,無法播放投影片,有需要同時看投影片的人,可以移動到 R0 去。我後來就把筆電丟著,跑到 R0 去了。這次只要是這種3個會議室同步轉播的情況,都有一些問題。

第2場是「CPython 程式碼解析」,講者是高國棟。主要是 Python 源碼入門,一開始是介紹 C 如何做物件導向,然後帶到 Python 源碼裡的 PyObject、PyVarObject,PyObject 是一切物件的基礎,而 PyVarObject 則是表示該類型的物件是可變長度特性的物件。然後再帶到 PyInt、PyString、PyList … 等等,很可惜的是 PyList 沒講完,後面明顯還有十幾頁投影片。

第3場是「天元突破, 鑽開 python 的限制」,講者是魏澤人。這一場比較偏向於 Hacking,講者先講他對於 Hacking 的看法,然後就開始介紹他怎麼去 Hacking CheckIO 這個網站。介紹完接著介紹一個好玩的檔案,這個檔案可以被 Python, Perl, Ruby 執行,也可以當作 HTML/JavaScript, Jar, Gif 來用,講解他怎麼做出這個特殊的檔案。簡報在隔天,也就是今天釋出。

第4場是「駭客看 Django」,講者是之前受到好評的 Orange。大致上就是講 Djano 還蠻值得信賴的,歷年來的漏洞很少,比 Rails 還少。接著就是講要注意哪些地方,除了一般該注意的之外,就是要注意 3rd party module 的使用。這邊提到一個 XXE/XEE,跟 XML entity 相關的漏洞,要注意到 XML Library 有沒有把 Entity 濾掉或是做檢查。

中午找到之前認識的朋友,一起吃便當,下午決定都在 R2。

第5場是 David Crammer 的 Building to Scale ,從 IRC 聊天室裡得知之前這個議題有在別的 Conference 分享過的樣子。也托了有在別的 Conf 分享過的福,在投影機杯具的情況下,可以直接連到該網址去看簡報,簡報跟這個場次講的有些微不同。這個場次蠻多人因為投影機杯具而移動了。

第5場結束有蠻長的一段休息時間,到了快結束時,才從 IRC 知道樓上有點心可用。接著的 R2 很多人想聽,所以人數爆滿。

第6場是「Big data analysis in Python」,講者是賴弘哲。講者有點緊張,到後面漸入佳境。主要是分享他在撈資料、分析資料所用到的一些 module,從 scrapy 到儲存用的 mongo 到分詞、搜索到可視化等等的,都有帶到。

第7場是「The life of an Ubuntu Developer」,講者是王榮祥。主要是介紹 Ubuntu 的 LaunchPad 跟 Bazaar,坦白說,跟 Python 比較沒關係一點。這邊我學到一些以前不知道的指令,像是 gpg –fingerprint 可以顯示自己的 key、gpg –keyserver keyserver.ubuntu.com –send-keys xxxxxxxx 可以送 key 到 keyserver、dch 指令可以維護 changelog 檔案等等。

第8場是「當 Python 遇上魔術方塊」,講者是戴嘉駿。這個議題比我想像中還有意思,講者先介紹魔術方塊的解法,然後介紹他怎麼用 Python 去寫求解程序,並且視覺化解題過程,很有意思。他的源碼放在 bitbucket 上,有用到 SimpleCV 去拍照判別魔術方塊顏色,以及用 property() 這個函數去動態換掉物件的 getter/setter。

議程結束後就是抽獎了,抽獎的程式很有意思,是像小蜜蜂那樣的射擊程式,但卻是以聲音來控制。由於人數不到 1000,程式又是以打到3個號碼來決定,常常打到 9xx、8xx、6xx 等號碼,所以抽獎的過程相當漫長,蠻多人受不了而離去。下次還是應該要以有來參加的人的號碼當作母體來抽獎,這樣會比較精準,也比較不會浪費時間。

最後是大合照,天公不作美,開始下起雨來,就在飄著小雨的情況,完成合照。回家的時候,想了想,在天色不黑的情況下,還是不走南港那邊,走原路回家。如果天色黑了的話,我可能就會走南港、八德路、基隆路回去,晚上走公墓那兒,還是有點毛毛的。

 

Python CSV writeheader

本來是用 writerow() ,就可以順利使用。但是想要讓輸出結果多個標頭,資質駑鈍,看了 Python CSV module 文件,還是看不懂。

Google 到這篇 use csv to write out data in python,例子淺顯易懂。第一個是要用 csv.DictWriter(),帶 fieldnames 參數。第二個是 writerow/writerows 時,則是要帶 dict 下去才行。

[python]
import csv
result=[(1,2,3,4), (5,6,7,8)]
fieldnames = [‘rev’, ‘committer’, ‘affected_files’,
‘affected_lines’]
with open(options.filename, ‘wb’) as csvfile:
writer = csv.DictWriter(csvfile, delimiter=’,’,
fieldnames=fieldnames,
quoting=csv.QUOTE_MINIMAL)
writer.writeheader()
rows = [{‘rev’: a,
‘committer’: b,
‘affected_files’: c,
‘affected_lines’: d} for a, b, c, d in result]
writer.writerows(rows)
[/python]

Python Performance Enhancement Tips筆記

以下是摘要:
  • python -m cProfile -s cumulative $1
  • time 指令
  • 用 pypy 與 python 對比:time python a.py 與 time pypy a.py
  • 可以考慮組合應用,一部份用 pypy,一部份用 python,因為 pypy 無法使用某些模組。
  • thread 效能不彰,因為 GIL 的關係,儘量使用 multiprocessing module 來代替 thread。要注意不可以使用函式內的函式,否則會有 Exception 發生,參數函式跟回傳值都要是 pickable 的。
  • 可以考慮使用 gevent:淺談coroutine與gevent

 

 

django-navbar

django-navbar 簡單說就是提供 navigation 的解決方案,類同於 ASP.Net 裡的 sitemap。

使用方法不難,但也讓我摸索了一陣子,這邊記錄一下:

  1. INSTALLED_APPS 加入 navbar
  2. TEMPLATE_CONTEXT_PROCESSORS 要加入 “navbar.context_processors.crumbs”, “navbar.context_processors.navbar”, “navbar.context_processors.navtree”, “navbar.context_processors.navbars”,預設原來的 settings 裡並沒有 TEMPLATE_CONTEXT_PROCESSORS,所以要自己加。但不是只加入這4個就好,而是還要加入原來的幾個
  3. 要 syncdb ,這會加入兩個 table。
  4. admin 裡會多出 NavBarEntry 的項目設置,注意:在 admin 設置完成以後,要重新 runserver,這是因為 navbar 是把資料預先塞到 Context Processor 裡,只有一開始才會去資料庫撈資料。
  5. 樣板有好幾個用法,但都要先 {%load navbar%},這可以參考 navbar/templates/navbar/ 下的檔案來進行使用。
  6. 有提供 breadcrumbs (就類似 “首頁 / 大功能 / 小功能” 這樣),但是沒有提供樣板,你可以自己刻,變數是在 crumbs 裡,用 {{ crumbs }} 就可以看到。