凌晨三點,讀完了《三體》的第二部。
咒語,這個東西的確很有意思。第二部比第一部好看,故事情節上完全展開,成功地製造了懸念。如果一部小說,刪掉很多文字仍不影響故事情節,那這部分就是多餘的,可惜在這部書裡這是個很大的問題,所以直到最後三分之一才真正出彩。
Posted via UltraBlog.vim.
凌晨三點,讀完了《三體》的第二部。
咒語,這個東西的確很有意思。第二部比第一部好看,故事情節上完全展開,成功地製造了懸念。如果一部小說,刪掉很多文字仍不影響故事情節,那這部分就是多餘的,可惜在這部書裡這是個很大的問題,所以直到最後三分之一才真正出彩。
Posted via UltraBlog.vim.
|
分类 : 青梅煮酒
|
此前預覽文章是通過調用系統默認的網絡瀏覽器實現的,缺點是這些功能完備的瀏覽器啟動速度不甚理想,尤其是火狐,誰用誰知道。
前兩天看了TuxRadar的一個Podcast,幾分鐘內就可以用pywebkitgtk拼裝出一個五臟俱全的網絡瀏覽器,pywebkitgtk這個東西實在是非常的好用。不過我實測後發現這東西加載頁面的速度比較慢,而且貌似是單線程的,因為圖片都是放在最後才加載,不知道是這個綁定本身的問題,還是有API可以實現的。於是突然想到拿這個東西實現一個簡單的瀏覽器,很適合在UB裡預覽文章。
增加了一個選項“ub_use_ubviewer”,默認值是1,即默認使用這個內建的瀏覽器預覽文章。當這個選項的值被設為0時,仍然使用系統的默認瀏覽器,並且在Vim啟動時不會加載內建的瀏覽器。這樣做一是為了多一種選擇,再一個也可以避開煩人的GTK警告:
** (gvim:13629): WARNING **: Trying to register gtype ‘GMountMountFlags’ as enum when in fact it is of type ‘GFlags’
** (gvim:13629): WARNING **: Trying to register gtype ‘GDriveStartFlags’ as enum when in fact it is of type ‘GFlags’
** (gvim:13629): WARNING **: Trying to register gtype ‘GSocketMsgFlags’ as enum when in fact it is of type ‘GFlags’
這些警告是GTK或其它一些程序庫的Bug造成的,雖然只在虛擬終端中啟動Vim時會顯示並且不影響使用,但總會有警告恐懼症患者會覺得這種東西很鬧心。如果這樣,就把這個選項的值設成0,用回巨型瀏覽器好了。
本次更新的全部內容如下:
關於UB的詳細信息在這裡。
這是那個Podcast:
Posted via UltraBlog.vim.
|
分类 : 編程
|
這次的更新主要引入了支持正則表達式的全文檢索、批量替換和調試模式。
我一直覺得原來的全文檢索有一個遺憾,雖然可以通過多個關鍵詞實現較為精確的查詢,但還是不如正則表達式靈活和精確。
這是個蓄謀已久的需求,但直到真正做起來,才發現很多有意思的東西。雖然SQLite3提供支持正則表達式查詢的“REGEX”關鍵詞,但並沒有實際實現這個功能,而是需要寫程序實現並在數據庫接口中註冊這個函數:
import sqlite3 conn = sqlite3.connect('/tmp/your-database-file.db') # 使用正則表達式匹配給定內容的函數,返回布爾類型 def regexp_search(expr, item): """Check if the item has a sub-string which matches the expr""" reg = re.compile(expr) return reg.search(item) is not None # 在數據庫中註冊這個函數 conn.create_function('REGEXP', 2, regexp_search) cur = conn.execute('select id,title from post where content REGEXP ?', '\babc\b') row = cur.fetchone() print row conn.close()
在SQLAlchemy中具體的實現方式是:
# 註冊函數 dbe = sqlalchemy.create_engine("sqlite:///tmp/your-database-file.db") conn = dbe.connect() conn.connection.create_function('REGEXP', 2, regexp_search) # 在SQL Expression Language中創建查詢條件 tbl = Post.__table__ cond_1 = tbl.c.title.op('regexp')(r'\babc\b') cond_2 = tbl.c.content.op('regexp')(r'\babc\b')
和普通的全文檢索一樣,正則表達式的全文檢索也支持使用多個表達式作為查詢條件,多個條件之間是與的關係。現在可以這樣查詢所有包含“UltraBlog.vim”但不把推廣代碼算在內的文章了:
:UBRegexSearch [^\[]UltraBlog\.vim[^\]]
在我換過新域名後,我就覺得這個功能很有必要了:
:UBReplace https://sinolog.it https://0x3f.org
包含第一個參數內容並被替換的文章數目會顯示在Vim的命令輸出緩衝區中。
有了前面實現全文檢索支持正則表達式的嘗試,再實現支持正則表達式的批量替換就容易多了:
# 轉換字符串成raw格式的函數 def raw(text): """Returns a raw string representation of text""" escape_dict={'\a':r'\a', '\b':r'\b', '\c':r'\c', '\f':r'\f', '\n':r'\n', '\r':r'\r', '\t':r'\t', '\v':r'\v', '\'':r'\'', '\"':r'\"', '\0':r'\0', '\1':r'\1', '\2':r'\2', '\3':r'\3', '\4':r'\4', '\5':r'\5', '\6':r'\6', '\7':r'\7', '\8':r'\8', '\9':r'\9'} return "".join([escape_dict.get(char,char) for char in text]) # 使用正則表達式替換字符串的函數 def regex_replace(string, expr, repl): """Do substitutions on the string for repls matching the expr""" r = re.compile(raw(expr)) return r.sub(repl, string) # 在數據庫中註冊這個函數 conn.connection.create_function('regex_replace', 3, regex_replace) # 在SQL語句中使用這個函數 sql_replace = "update post set title=regex_replace(title,:needle,:replacement),content=regex_replace(content,:needle,:replacement)" conn.execute(sql_replace, {'needle':r'\babc\b', 'replacement':'xyz'})
最終,這個命令是這樣的:
:UBRegexReplace \babc\b xyz實現批量替換容易,但要解決由此引出的一個問題就費周折了,就是批量替換過文章內容後怎樣和博客同步的問題,現在我還沒有好的想法,留作以後實現。
開啟調試模式可以將所有被執行的SQL語句顯示在Vim的命令輸出緩衝區中,在有異常拋出時,也可以顯示堆棧信息。由於開啟調試模式既不需要修改代碼,也不需要重啟Vim,這可以極大地方便開發時對UltraBlog.vim的調試,也能使用戶提交問題時能反饋更多更詳細的信息。
以下三個命令用於控制調試模式的開啟狀態:
:UBEnableDebug:UBDisableDebug:UBToggleDebug本次更新的內容如下:
關於UB的詳細信息在這裡。
Posted via UltraBlog.vim.
|
分类 : 編程
|
使用xdebug跟蹤程序性能時發現fsockopen()函數耗時一秒,單步調試發現實際在這裡超時了,而超時時間設置的就是一秒。
如果把目標地址由原來的“localhost”換成“127.0.0.1”,馬上就可以連上。在PHP的Bug跟蹤系統中找到這個問題:
https://bugs.php.net/bug.php?id=50953
看起來像是在5.2.12以後已修改,但我發現在5.2.17中仍存在這個問題。另有說法在5.3中不存在這個問題,我沒有測試。
Posted via UltraBlog.vim.
|
分类 : 編程
|
用xdebug跟蹤程序性能時,發現一個定義了約七百個常量的文件,include_once()時消耗約六十毫秒的時間。事實上define()的效率比較低,如果需要定義大量常量,使用APC擴展提供的apc_define_constants()效果會好得多。
下面是對這個文件改造前後效率跟蹤結果的對比:
| define()方案(ms) | apc_define_constants()方案(ms) | |
|---|---|---|
| 啟動Web服務和PHP,第一次運行 | 58 | 4 |
| 不重啟Web服務和PHP,第二次運行 | 65 | 1 |
| 不重啟Web服務和PHP,第三次運行 | 66 | 1 |
由此可見,apc_define_constants()不但在初次調用時效能就超過define(),而且由於APC自身的緩存功能,在後續調用時效率會有進一步的提高,而define()基本沒有變化。
以下是apc_define_constants()的代碼示例:
if(!apc_load_constants('my_constants')) { $constants = array( 'ONE' => 1, 'TWO' => 2, 'THREE' => 3, ); apc_define_constants('my_constants', $constants); }
Posted via UltraBlog.vim.
|
分类 : 編程
|
UB一歲了,這算是個週年紀念版吧。
在這一年裡,因為各種原因,博客寫得沒有以前多了,但每篇都是用這個插件寫的,我覺得很好用。斷斷續續地做了一些修改,因為一切都是一個人在做,所以大的變化不多。這次這個版本裡有些改動還是要感謝荒野無燈童鞋,他的建議很大程度上催生了這個新版本:比如加入保存命令的熱鍵映射選項,這樣可以使用保存普通文件的熱鍵保存UB中的內容,我自己以前也經常習慣性地用錯熱鍵;還有socket超時時間的選項,最近我這裡也經常性地在UB操作博客時報超時的異常,荒童鞋關於自定義socket超時時間的建議一語驚醒了夢中人。
此外,似乎與近期Vim的一次升級有關,在Vim中調用Python接口打印任何內容到標準IO都會導致Vim崩潰,所以這次把所有的輸出都改成了調用Vim的輸出命令來做。
本次修改的內容中,還有一項比較重要的內容就是實現了國際化,目前只提供英文和簡體中文兩種語言,由於Vimball不能處理二進制文件,所以從此以後UB改用zip格式壓縮包打包。
以下是本次更新的詳細內容:
關於UB的詳細信息在這裡。
Posted via UltraBlog.vim.
|
分类 : 編程
|
Archlinux目前對Thinkpad風扇的自動控制效果並不好,氣溫上升後很容易出現一直在三千多轉一直跑的問題。thinkfan是目前用的比較多的自動控制風扇轉速的程序,但Google到的配置thinkfan的文章大多語焉不詳,可能是跟具體的發行版有關,因為貌似有些發行版中安裝了thinkfan後會自動生成缺省的配置文件,但在目前的AUR中的包被安裝後卻沒有生成任何配置文件。
下面是我在Archlinux下配置的步驟,實際效果很好,現在只要不看視頻、不編譯程序、不啟動Chromium,一般是兩千九百轉的速度,安靜多了。
安裝lm_sensors並執行命令初始化:
# 一路回車 sudo sensors-detect
將sensors加入rc.conf中DAEMONS中,開機啟動。
启动sensors服务:
sudo rc.d start sensors修改文件“/etc/modprobe.d/thinkpad_acpi.conf”:
options thinkpad_acpi fan_control=1
我這裡雖沒有把thinkpad_acpi加到rc.conf的MODULES中,但lsmod也是可以看到它的,說明還是自動啟用了。要使上面這項配置生效,必須重啟電腦,我這裡重啟thinkpad_acpi模塊時報錯說該模塊正在被使用。
安裝thinkfan並修改文件“/etc/default/thinkfan”:
START=yes
修改文件“/etc/thinkfan.conf”:
sensor /sys/class/hwmon/hwmon0/temp1_input (0, 0, 55) (1, 48, 60) (2, 50, 61) (3, 52, 63) (4, 56, 65) (5, 59, 66) (7, 63, 32767)
將thinkfan加入rc.conf的DAEMONS中,開機自動啟動。
啟動thinkfan:
sudo thinkfan# 看CPU温度和风扇转速 sensors # 看風扇詳細信息 cat /proc/acpi/ibm/fan
Posted via UltraBlog.vim.
|
分类 : 計算機
|
TurboCRM Cluster Express是TurboCRM的集群實施工具。

去年我曾經寫過一個配置集群的Bash腳本“cluster.sh”,TCE是對這個腳本的圖形界面封裝,通過可視化的操作簡化集群的實施工作。
TCE的最新版本和使用說明可以在這裡找到。
Posted via UltraBlog.vim.
|
分类 : 編程
|
貌似Lose系統下看在線視頻的時候不會超時自動關閉屏幕,但是我在Arch下就一直晃鼠標、按鍵盤來著,這嚴重違反了DRY原則。於是昨天終於寫了這個腳本,當全屏播放視頻的時候,關閉屏保和顯示器的節能特性,否則則激活它們。由於是在X的級別實現,理論上應當適合所有桌面環境。
#!/bin/bash # Baby-sitter of the monitor's DPMS idle_period=60 ss_switch_off=0 ss_is_off=0 while true; do # Read DPMS state xset -q|grep "DPMS is Disabled" > /dev/null && ss_is_off=1 || ss_is_off=0 # Get pid of the current window active_window_id=`xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)" | cut -d" " -f5` decimal_id=`xprop -id $active_window_id | grep PID | cut -d" " -f3` # Traverse all libflashplayer.so for pid in `ps -ef|grep -v grep|grep libflashplayer.so|awk '{print $2}'`; do # If the current window is libflashplayer.so if [ "$pid" -eq "$decimal_id" ]; then ss_switch_off=1 break else ss_switch_off=0 fi done if [ $ss_switch_off -eq 1 ]; then # Turn off DPMS echo Turn off DPMS if [ $ss_is_off -eq 0 ]; then echo Action xset s off xset -dpms fi else # Turn on DPMS echo Turn on DPMS if [ $ss_is_off -eq 1 ]; then echo Action xset +dpms xset s on fi fi sleep $idle_period done
似乎對非全屏播放的情況沒有什麼好方法。
Posted via UltraBlog.vim.
|
分类 : 編程
|