歸檔 2012

最后更新于 .

寫在前面: 博客很久沒有更新了,主要是事情實在太多,不過最近也確實做了些比較有價值的事情,后面和大家慢慢分享

筆者在騰訊主要負責開放平臺openapi的工作,由于工作關系,這幾天遍歷了 百度、人人、新浪、淘寶 4個平臺,研究了一下他們對于站內應用、網站登錄、移動應用的整合方式,并開發了一個百度站內應用的demo。

百度站內應用demo: 體驗地址(要體驗的話,請先聯系我開通白名單): http://app.baidu.com/app/enter?appid=385894&debug=1&is_from_dev=1&canvas_pos=platform

代碼已經開源在github上: https://github.com/dantezhu/baidu_app_demo,里面封裝了一個baidu的sdk,有需要的朋友可以直接拿去用。

開發語言用的是 python+flask 移動應用 和 網站接入,這兩種接入都是走的oauth的方式,這個基本所有平臺都是一樣的。

而對于站內應用則和騰訊目前不太一樣,所以著重說明一下在這里的處理,僅以百度舉例:

百度的教程在這里: 百度站內應用開發文檔

1. 當用戶點擊應用列表進入時 ...

最后更新于 .

離上一次寫博有點久了,留言也回復的比較慢,主要事情確實有點多,今天想想還是把這篇給寫了吧,可能有點亂。 先說說最近折騰了些啥 部分開源項目的代碼從googlecode遷移到github,其實還是主要是svn和git的原因,因為公司一直是用svn,所以對svn會熟一些,不過最近發現越來越多的項目都在使用github,所以免不了好奇起來,本著越是抵觸越是要搞的心理,硬著頭皮總算懂了些皮毛。之前還對git的分布式代碼管理沒什么感覺,這幾天恰巧去上海參加chinajoy,網絡時好時壞,svn一直不能ci,這才懷念起git的好來。所以目前的結論就是,兩者都用著,新項目就統一往github上遷移了。 研究了一下bootstrap from twitter,這個號稱能讓開發人員寫出漂亮頁面的前端庫真心不錯,把頁面用12個柵格來表示,之前從沒想過頁面可以這樣規劃(好吧,也可能是我孤陋寡聞。。),而且支持交互式布局,做出來的界面都iphone、ipad等移動設備都會自動適應,的確是后臺開發寫前端的一大利器,超贊! OK,碎碎念結束,接下來還是分享一段代碼吧 關注本博的朋友應該會了解之前我在python的微框架使用flask還是bottle之間選擇了很久,現在無論如何,事實就是我多的在用flask,原因就不扯了,反正也扯不清楚。 這里主要是分享一點,無論是django,flask,bottle 都有一個通過 endpoint 生成 url的函數,在django中是reverse(模板中是url),flask是url_for,bottle中是url ...

最后更新于 .

這篇文章寫的比較晚,主要也是要真正用起來才會發現,django1.4的這次升級在項目目錄結構,配置文件上都有比較多的調整,恰好這次也受這樣的困擾,所以就拿出來和大家分享一下。 django1.4增加了一個很重要的目錄: static,在之前,django的所有靜態文件都是放在media目錄下的,但是同時用戶在后臺主動上傳的文件也會放到這里,所以會引起一些不必要的混亂. 而且在之前的版本種,django的admin會霸占/media的路徑,導致我之前不得不在配置里面強制修改一下:

ADMIN_MEDIA_PREFIX = '/admin_media/'

或者讓網站自己的靜態文件路徑使用的別的前綴:

MEDIA_URL = '/site_media/'

對應的nginx.conf也要做一些相應的配置,對于之前版本相關的內容,這篇文章就不做贅述了,有興趣的朋友可以去我之前寫的博文看一下: linux下nginx+python+fastcgi部署總結(django版),PS:當時還沒用uwsgi,大家將就一下。。 回到我們說的django1.4的變更,增加的static目錄用來存放網站需要的靜態文件,如css,img等,而/media目錄用來存放用戶上傳的文件,admin使用的靜態文件是放到/static/admin下。 這樣的調整是要比原來合理很多,但同時nginx.conf的配置也需要做響應的變更,如:

server {
    listen ...

最后更新于 .

前段時間有朋友在微博上@我推薦了一款vim的插件,用來顯示對齊線,感覺效果不錯,就給大家推薦一下.

下載鏈接: Indent Guides

截圖如下:

1

一. 安裝

不用多說,直接解壓放到vimfiles or .vim下

二. 配置

基本可以不用配置,不過由于默認的對齊線寬度太寬,不太美觀,所以我改成1了,如下

let g:indent_guides_guide_size=1

詳細的配置,可以參看他的文檔,這里不再多說

三. 使用

默認的鍵盤映射是

<mapleader>ig

OK,插件就介紹到這里,其實如果只是單純的介紹插件,就不用寫這篇文章了。

我在用這個插件的時候,又發現了另一個需求,即標尺的功能。vim7.3里面默認提供了colorcolumn,例如執行:

:set cc=80

就可以高亮第80列,效果如下:

1

但是有時候我們想看一下幾行的字符是不是在同一列上時,手工去輸入列數實在太麻煩了,所以我就單獨寫了一個函數,來滿足這個需求:

map ,ch :call ...

最后更新于 .

不是第一次寫nginx的自定義模塊了,之前有寫過根據POST數據轉發請求的模塊(參見nginx自定義模塊編寫-根據post參數路由到不同服務器),不過上次寫的是處理模塊,而這次寫的是過濾模塊,還是有一些區別的。 在正式開始前,先說一下寫nginx自定義模塊要注意的幾個點:

  1. 上次的文章提到,在函數里用r-connection.log打印log會core,今天發現是ngx頭文件和lua頭文件引用順序的問題,把ngx的頭文件放在最前面即可解決
  2. nginx的一個字符串類型 ngx_str_t 有兩個參數, len 和 data,這兩個參數一定要一起使用,因為data的\0結尾,不一定是len的長度,這一點千萬要注意
  3. 需要和cpp文件聯合編譯是,在ngx的編譯參數里面加上--with-ld-opt="-lstdc++"

OK,廢話不多說,開始正式說我這次寫的統計模塊吧 需求背景呢,就是現在已經在nginx后面掛了很多服務器,需要用nginx來統計成功率,響應時間等等參數,在網上翻了半天,大部分居然是用access_log,然后用程序掃描$request_time來實現的,這對一個每秒幾千次訪問的服務器是不可忍受的,所以最終沒辦法,那就自己寫一個唄~ 重新看了nginx自定義模塊的開發文檔,整個調用過程如下:

1

但是實在是沒找到請求整個結束時的回調函數,最接近的也就是用filter模塊了(即過濾模塊),當然這樣統計出來的請求時間,可能會比實際時間短一些。 OK,定了要寫那種模塊后,我們來考慮一下具體的實現

  1. 為了性能最大話 ...

最后更新于 .

之前對bottle做過不少的介紹,也寫過一些文章來說明bottle的缺點,最近發現其實之前有些地方說的不太公平,所以趁此機會也來更正一下。

  • bottle是支持類似flask url_for的語法的,具體使用方法在下文介紹
  • bottle的request.query之類的參數默認是str類型,也是有原因的,比如我在給google做代理的時候,編碼就不一定是utf8的,如果強制轉化utf8就會報錯
  • 之前的bug也得到了修正,比如mount('/x',app)之后,/x/和/x都可以訪問到

OK,現在正式進入主題,我們來介紹一些bottle的一些高級使用

一. 智能創建url

這部分在bottle的文檔上是沒有介紹的(其實bottle明明實現了很多貼心的功能,不知道為啥都不寫在文檔上)。 在Bottle類里,有一個成員函數:

def get_url(self, routename, **kargs):
    """ Return a string that matches a named route """
    scriptname = request.environ.get('SCRIPT_NAME', '' ...

最后更新于 .

還是和往常一樣,沒啥主題,就是記錄下這段時間遇到的技術問題,分享一下。

1. 在javascript中實現簡單的模板替換 最近搞了一下js,最不習慣的就是字符串生成都要用字符串拼裝或者join的方式,所以嘗試一下看能否實現簡單的模板替換,效果還不錯。

function str_format(str, obj) {
    return str.replace(/\{\s*(\w+)\s*\}/g, function(_i, _1) {
        return obj[_1] != null ? obj[_1] : '';
    });
};

很多朋友會說性能差一些,可能確實如此,不過對我來說,相比編寫的舒適來說,這點性能差別實在無足輕重了。

2. uwsgi報readv() faild 用uwsgi+nginx搭建的server,發現當用post請求時,會返回數據超時。查了一下uwsgi的error.log:

9825#0: *745262 readv() failed (104: Connection reset by peer ...

最后更新于 .

前段時間有博友在群里問了一個關于vim排序的問題,因為時間問題一直沒幫忙解決,今天時間正好空出來,就幫忙搞了一下。 原文的問題如下:

vimuser 說:
2012年03月1日 于 5:04 下午  (編輯)
今天折騰了一下午,研究vim的排序,看了教程和搜索了一些文檔,還是沒弄明白,vim的正則表達式跟一般的又不一樣,來請教下博主。

|1 | 11 | 111| 1111|
|2 | 22 | 222| 2222|
要根據第3個|和第4個|之間的列進行排序該如何寫命令呢?

其實之前也只是簡單的用過vim的sort命令,沒有想過vim是否能完成如此復雜的排序,不過抱著試試看的態度,我看了一下sort的描述(:h :sort),其中一段話如下:

:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]

When /{pattern}/ is specified and there is no ...

最后更新于 .

nginx可以輕松實現根據不同的url 或者 get參數來轉發到不同的服務器,然而當我們需要根據http包體來進行請求路由時,nginx默認的配置規則就捉襟見肘了,但是沒關系,nginx提供了強大的自定義模塊功能,我們只要進行需要的擴展就行了。 我們來理一下思路,我們的需求是:

nginx根據http包體的參數,來選擇合適的路由

在這之前,我們先來考慮另一個問題: 在nginx默認配置的支持下,能否實現服務器間的跳轉呢?即類似于狀態機,從一個服務器執行OK后,跳轉到另一臺服務器,按照規則依次傳遞下去。 答案是可以的,這也是我之前寫bayonet之后,在nginx上特意嘗試的功能。 一個示例的配置如下:
server {
    listen       8080;
    server_name  localhost;

    location / {
        proxy_pass http://localhost:8888;

        error_page 433 = @433;
        error_page 434 = @434;
    }
    location @433 {
        proxy_pass http://localhost:6788;
    }
    location @434 {
        proxy_pass http://localhost:6789;
    }

    error_page ...

最后更新于 .

其實之前就有寫過關于python web開發框架選擇的文章,之前最終選擇了bottle,并給出了bottle開發的物理設計,詳見之前的文章:回歸簡單,向Django說再見bottle做web開發的物理設計,然而經過最近兩個星期的實踐,又有了一些新的想法。

Bottle作為一個微框架,本身確實有些小型項目的缺點,嘗試列舉如下:


  • 沒有原生支持unicode

  • 例如route('/')獲取的name并不是unicode類型,get和post的參數也默認并非unicode類型,雖然作者后來在0.10版本中給query和forms加入attr方式來解決這個問題,但是還是有所限制
    而flask則是 unicode based,對unicode支持的非常好
  • 影響力小,與其他組件的結合比較差

  • 一個典型的例子就是wtforms不支持bottle的files字段,而flask雖然也不支持,但是flask的插件flask-wtforms則完美修正了這個問題
  • 功能太基本

  • 關于這一點,可以說是優點也可以說是缺點。絕對的純粹看起來是件好事,但是真正開發起來又發現完全不是那么回事,自己要重新開發的輪子實在太多了。比如session的支持
  • bottle由個人開發,有些地方并不那么專業

  • 比如route的參數method=['GET','POST'],因為是數組,所以用methods更合適;request.forms其實用request.form更合適
    再比如static_file函數,必須要求傳入一個root_path和一個filename;而flask則有兩個函數一個send_file和send_from_directory,支持直接返回file內容

反觀flask,不能說flask的一切都是好的,但是確實在這幾點上要比bottle做的要好一些,而且flask還有一些很實用的功能,比如實時debug ...

每月存檔

去年

2011

明年

2013