發表文章

目前顯示的是有「所有文章列表」標籤的文章

PhantomJS 擷圖 亂碼修正

使用PhantomJS拮取網站擷時,有時會因為網站Server的Content-Type沒有指定 charset 造成亂碼。Github 上有一個 issue  也是同樣的問題還沒解決。後來想到可以用 chardet 配上HTTP Proxy 來改寫Content-Type header。以上是一個簡單的script來解決這樣的問題:

MongoDB as queue

想要把 MongoDB 裡的其中一個 collection 做為 queue, 讓多個 worker 存取來做事,可以利用 MongoDB 的 findAndModify。 findAndModify 是 atomic operation,執行的結果會回傳一個物件並且更新他的狀態。 例如現在有一個 collection 名為 keys, 裡面存著 {"id": id, "queued": false} db.runCommand({"findAndModify": "keys", "query": {"queued": false}, "update": {"$set": {"queued": true}}})

使用 pppd 連接 VPN 時連線凍結

本來都是用學校的 Junos Pulse SSL VPN  連線到學校查論文,不過最近學校的SSL VPN一直壞掉,所以只好自己在 Lab 的電腦上裝 PPTPD。不過問題來了,用 Network Manager 連進去都可以,可是用 pppd 連線時確一直無法上網,不過倒是可以 ping 到 server。 比對了一下 routing table 發現是一樣的,而且我有在/etc/ppp/ip-up.d 底下加上了 01-route.sh,所以會把所有的 traffic route 到 ppp 去 #!/bin/bash route del default wlan0 route add default $1

azhuang.me 網域

買下了 azhuang.me 這個網域,所以 blogger 也一起轉過來了 :P 以後請使用 http://blog.azhuang.me 連到我的網誌。

MongoDB 初體驗

因為 Web Mining final project 我們想做 twitter tweet 的 clustering 及 classification,所以需要從 twitter 下載大量的 Tweet 做為實驗用途。一開始我是把這些 tweet 存成 JSON 在文字檔裡,不過隨著 tweet 量越來越多,用文字檔實在很難處理。由於本來就是存成JSON的格式,所以就想到了 MongoDB。 之前只有玩過try MongoDB, 從來沒有好好用過他,這次剛好有這個機會就來用一下 :P 裝好MongoDB後就可以開始始用了。由於這次 project 是用 ruby 寫的(因為有方便的  Twitter Gem  可以用),所以我用了 Mongo Gem   。Mongo Gem 的用法跟 Mongo shell 裡的用法差不多,簡單的用法如下,更多的說明可以參考 Mongo Gem 的 wiki 。

ActiveRecord like API for Python

之前看到 ActiveRecord 有一個很方便的功能: find_by_COLUMN,而 COLUMN 是那個 Table 裡的 columns。這用 Ruby 的 define_method 很好實做,當然 Python 也可以做到。下面是一段 POC (Prove of Concept) code:

Monkey Patching: Python V.S. Ruby

之前在寫Rails的時候還不是很熟悉Ruby,所以很多Ruby的特性沒有去深究。最近剛考完期末考比較有時間了,所以好好來看了一下Ruby。目前覺得學Ruby的好處就是會讓我想去比較Python,因為我個人還是Python的愛好著,所以看Ruby可以做到的功能就想要看Python可不可以做到。拿Ruby最有名的名能之一來說好了: Monkey Patching,從Wikipedia: A  monkey patch  is a way to extend or modify the  run-time   code  of dynamic languages without altering the original  source code . Ruby 可以很容易的動在舊有的Class/Module中加入新的Class/Method,舉例來說我們可以新增一個  method 到 Array 中: def Array.test puts "This is a singleton method `test' of the Array class" end

SQL Job Queue的寫法

最近網站要Deploy到MySQL上才發現之前寫得很多都有問題或是效率不好。 之前對於Job Queue的寫法是這樣寫: def pop(): stamp = time() db.query(Table).update({'stamp': stamp}) return db.query(Table).filter_by(stamp=stamp).all() 後來發現原來MySQL有SELECT .. FOR UPDATE的用法(是不是該修一修Database了XD) 加上了FOR UPDATE後,目前被選到的row就會被Lock起來。而其他的Process如果選到了 同樣的row,就必需等到commit後才能繼續。 所以就可以寫成: def pop(): records = db.query(Table).with_lockmode('update').filter(Table.status == 'NEW').all() db.query(Table).filter(Table.id.in_([x.id for x in records])).update('status': 'QUEUED') db.commit() return records 由於我們把status設成了'QUEUED',而在select時選擇Status為'NEW'的row,所以並不會造成conflict或是lock wait。 這樣的寫法好多了,而且在MySQL裡也比較不會出問題。

嵌入系統實驗PXA300 Lab3

圖片
Ubuntu on ARM Machine? No way. 其實是嵌入實驗做的數位相框XD

資結HW2

讓我想到我小時候在哈電族上寫的文字編輯器XD 那時候寫的是有多個Mode的編輯器,有Insert和Normal Mode 所以那時候也要寫像這次資結的東西,移動遊標啊,插入,刪除等... 還因為要輸入中文,所以要偵測雙位元字元... 真的好懷念啊XD

Reference counting

前幾天有人在板上問了個有關C++ class內部member的記憶體管理問題,我那時後就寫了一小段Code來玩玩,所以順便丟上來XD Reference counting 是一種物件對內內部記憶體管理的方式。主要的原理是: 假設現在我有一個Class RefObj內部有一個char*的member用來存字串,那今天我把一個物件assign給另一個 RefObj A("testing"); RefObj B = A;

PttXP 更新至0.1.5

Version 0.1.5 * 終於修好了刪除標頭的功能 * 登入重試次數增加為5次 * 修正GUI Lag的問題 * 這次大大的修正了登入問題,幾乎不會再登入失敗了 詳細資訊請至: http://berelent.blogspot.com/p/pttxp-ptt.html

PttXP 更新至0.1.2

* 修正了容易登入失敗的問題 * 修正了Windows下換行的錯誤 * 新增功能: 'delete post header' 刪除PTT文章的標頭(網宣常用) 詳細資訊請至: http://berelent.blogspot.com/p/pttxp-ptt.html

Open Source, Open Mind.

Revolution OS ( http://v.youku.com/v_show/id_XMTEwMDA4MjA=.html ) 這是一部有關開放源始碼社群的記錄片 很久以前看過一次,前幾天在噗上又看到很多人在轉噗 所以我就一邊coding一邊要看了一次XD 想要瞭解什麼是Open Source, Linux的人可以看看這部。 不過聽Bill Gates的news letter內容那段還滿火大的XD 現在越想越覺得Stallman真是偉大啊! 如果沒有FSF,大概連Linux都不一定會出現,更別說這麼多開源、免費的軟體了! 雖然他的想法是有些極端,不過也要有這種人,才能創造出這種理念 我也相信商業軟體絕對有他的必要性 像是現在Open Source界就還沒出現能夠媲美商業界的遊戲XD

Debian/Ubuntu套件打包

很久以前寫過利 用dpkg-deb來打包套件 ,其實這個方法非常麻煩,我後來都改用dh_make了。 利用dh_make加上CDBS(The Common Debian Build System),可以很方便的建立出一個deb包,這也是標準的打包方式。CDBS演變到現在己經非常方便了,打包者幾乎不用作什麼事。CDBS可以處理非常多常見的build system包括GNU Autotools、Python的setup.py、Qt的qmake、make、cmake等等,支援的列表可以在 CDBS的Documentation 裡找到。 打包的步驟大約如下: 將套件壓縮成 套件名稱_版本.orig.tar.gz,並放在套件目錄的同層目錄 在套件根目錄執行dh_make -s -b。-s表示包裝成single binary,-b表示使用CDBS 編輯debian/control、debian/rules 在套件根目錄執行dpkg-buildpackage -rfakeroot 完成。

cbase

之前寫了一個簡單的進制轉換程式 叫做cbase。不過那時候架構沒有設計的很好,程式碼也很亂,所以我暑假閒著沒事就把他重寫了一次,這次程式碼短得多了,也比較靈活。 記得那陣子好像常常遇到要對數字做不同的基底變換,所以我才會想寫這樣的程式。cbase是一個非常簡單的程式,估計有稍微學過程設的大家都能瞬間寫出來,所以在這裡現醜了XD。 源碼丟在 github ,然後我也順便包了個deb包,要用的自行下載吧XD 其實cbase主要目的就是執行數字間的任意基底變換,比如說 IP IP其實可以看成是256進位的數字,所以如果要把他轉10進制(這可以做什麼我應該不用多說了): ~$ cbase -i 256 -o 10 -d . 119.160.246.241 2007037681

Web Crawler

今天無聊就想說來改一下manpages-cpp的crawler 因為原本那個實在是太慢了... 爬過全部的頁面太概要2個多小時@@ 原來的設計,cppman -r (rebuild index)這個選項本來就不是為user end設計的 而manpages-cpp裡本身就包含了已經cache好的index database。 所以我在rebuild index的功能上設計得很陽春,基本上只是個簡單的DFS。 不過今天我重新檢視了時間會如此慢的原因,發現原來問題是出在urllib.urlopen() 開一個頁面太概要0.7秒,不過這不是網路速度的問題。原因是在urllib預設的text buffer大小是0 所以每讀入資料就要重新分配記憶體,所以才會花到0.7秒。 我的解法是用multi-thread。不過有個很的問題是linux的thread limit 在我的電腦上最高只能開到323個thread,可是利用DFS隨便跑下去都幾百個thread 所以只好設了thread_max,如果要超過了就先join 這樣大概可以將時間縮短到13分鐘。2小時多到13分鐘這算是非常大的進步了。

cool RegExpr

原文在 這裡 判另方程式是否有解 ax + by = c => /^(.*)\1{a-1}(.*)\2{b-1}$/ 而被match的文字是用任意字元重覆c次 實測:13x + 19y = 70 Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import re >>> if re.search(r'^(.*)\1{12}(.*)\2{18}$', '1'*70): ... print 'Has solution.' ... else: ... print 'No solution.' ... Has solution. 想一下其實原理不難。

HTML5 Rocks

最近在學Web Design,雖然還很不熟,不過至少HTML+CSS+JavaScript會用了XD 剛看了一下HTML5的介紹,真是另人震驚啊 這個Slide: HTML5 Presentation 本身就是用Ajax寫的,不管是看起來或是用起來,都像桌面應用程式一般。 HTML5 ~= HTML + CSS + JS APIs 個人覺得那些CSS實在太扯了,連webgl都出現了,而且只要幾行code就可以做出漂亮的效果。如果是寫桌面應用程式的話,這樣的效果可能要多寫很多code,郊果還不一定有CSS好呢! 覺得HTML5實在是太方便了,不過都是把麻煩的工作丟給瀏覽器,所以Web Designer可以很輕鬆的寫出漂亮的網頁。 現在Web UI這麼發達,難怪連Nessus的操作介面都改用網頁來控制了。

Fixing Live CD boot error: Ext3fs unsupported optional features: (240)

Scenario: Live CD boot without problem in qemu, but boot failed in a real machine with ext4 filesystem in local hard drive. The boot failed because of the following error: Ext3fs: sdaX: unsupported optional features: (240) root filesystem is not mounted and the boot sequence either fell into an infinite loop displaying the error or into busybox. Explaination I first encountered this error years ago in clonezilla Live CD, as I choose a new version of the Live CD image, the problem was gone. This time, I encountered this error again with BackTrack 4 Live CD Image. However, BackTrack Linux doesn't have a release roadmap and even if it does, the problem is not likely to be fixed since there is a workaround for it. As I insists in keeping my live usb layout neat, I decided to fix it myself.