07 3 月

python pipe 到 more 或檔案會出現 UnicodeDecodeError

好久沒有更新這個部落格了。今天剛好有東西可以 share 一下。

這個問題困繞我很多次, 不過我之前都沒有仔細看到底是怎麼回事。今天查了一下, UnicodeDecodeError when redirecting to file 這篇就寫得很清楚。基本上就是用 pipe 導出去的時候無法判別 encoding, 所以非 ASCII 的就會出錯。這篇文章提到用下列的方式就可以解決這個問題:

import codecs
import locale
import sys

# Wrap sys.stdout into a StreamWriter to allow writing unicode.
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)
uni = u"\u001A\u0BC3\u1451\U0001D10C"
print uni

這樣不管是直接執行

yychen$ python test.py

或是把他導出來

yychen$ python test.py > test.txt
yychen$ python test.py | more

都 ok 了。

12 10 月

antispam: DNSBL

這一陣子廣告信變多, 困擾同事。所以看來讓 postfix 吃一下 DNSBL 還是必要的。所以看了一下, 上了這 xbl.spamhaus.org, sbl.spamhaus.org 跟 bl.spamcop.net。在 postfix 的設定上面極為簡單

smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination,reject_rbl_client xbl.spamhaus.org,reject_rbl_client sbl.spamhaus.org,reject_rbl_client bl.spamcop.net

在 smtpd_recipient_restrictions 用 reject_rbl_client 這個 keyword 即可。

一開始還為了這個把 SPAM 都收集在某個 Maildir 的目錄底下, 用 python 把 last hop sender IP 給揪出來。後來想想, 直接上 DNSBL 好像比較快又簡單。

12 10 月

以 django 來開發網頁

今天剛好碰到以前的同事問我關於 django 開發網頁的事情。我才想到, 上一次想到 django 相關的 packages 似乎講得不夠詳細。這邊稍微補充一下。

Web Server

如果不是很 heavy 的網站, 流量不大的話, 其實 apache2 就很足夠了。個人偏好是因為從很早就開始使用 apache, 也習慣他的 configuration 了。至於如果常見大家所使用的 deployment, 就是使用 nginx 外加 gunicorn 了。
A Django setup using Nginx and Gunicorn 這篇文章寫得頗清楚的。我個人是使用 Ubuntu, 因此選用 upstart 來寫他的 service script。

Environment

上一段提到的部落格文章有特別提到一個東西就是 virtualenv, 個人也相當推薦使用。他會將你的 python environment cage 在某個目錄, 因此 django 所使用到的套件並不會跟系統的 python 混淆。Tools of the Modern Python Hacker: Virtualenv, Fabric and Pip 這篇文章有提到。目前我還沒有使用 fabric 來做 deployment, 不過 virtualenv + pip 就非常好用了。

Settings

Django package ship 出來的 settings.py 其實不太適合 development/production 使用。SplitSettings 這個頁面寫了很多種方式來把兩邊分開來。

Template

Django 1.4 的 template 其實已經比以前好用非常多, 不過看到 instagram 使用 jinja2, 再看到 jinja2 官網的說明, 就會想要做這個 optimization。缺點就是如果你有使用第三方套件, template tags 以及 plugin 可能需要自己重刻。比較常見的搭配方式就是 jinja2 + coffin

CSS / js compression

django 有幾個套件可以做這件事情, 我目前有使用的是 django-pipeline。其他 solution 可以參考 Django packages – asset managers。用這個東西的時候, 如果有 include 額外自己寫的 js, 記得要將變數 export 出來給 window, 否則變數都會被 cage 起來。

幾個月前看到這篇很棒的文章 – What Powers Instagram: Hundreds of Instances, Dozens of Technologies, 裏頭提到了非常多不同面向的 solution, 值得參考。剛剛也在 quora 上看到這個 What technology stack is Instagram built with? 裡面也提到不少東西。

01 10 月

console.log in IE

測試功夫做得還不夠。今天早上同事打來說, 還是有很多客戶反應 IE 註冊都沒有任何的提示。我上次想說就已經看過也修了, 為什麼還是一樣。今天到公司自己測了一下, 都 ok。直到我跑到同事的電腦請他做一次給我看, 才發現我跟他測的差別。我每一次都開了 developer tools 在做測試 (既然是在 debug, 當然會把這個打開), 殊不知就因為我有打開就看不到 bug。

此時我大概猜到了, 我應該是用了 console.log 所以開 developer tools 的時候都正常, 一關掉就爛掉了。

所以加了一個避免爆炸的小 code

// For IE
if (typeof console === "undefined" || typeof console.log === "undefined") {
console = {};
console.log = function() { };
window.console = console;
}

因為有做 js compress, 所以要把 console 給 expose 到 window 這個物件, 不然這段 code 會被 cage 住而讀不到資料。

26 9 月

Django + jinja2 + mptt

當初毅然決然的把 template 換成 jinja2, 其實真的是 over-optimized 了。不過既然都已經換了, 就換了, 代價就是 3rd-party package 有使用到 template tags 的, 要自己重寫!

最近在重新整修後臺系統, 索性也把 template 換成 jinja2, 不過這時麻煩了, 我們使用 django-mptt 來做 tree structure, 在 template 這邊有使用到 mptt 自己的 tags。有時候自己真的很衝動, 昨天就開始看 code, hack, 想要自己把它 port 成 jinja2 的版本。碰到重重的困難後, 突然發現 jinja2 自己就有 recursive 可以使用。而且也弄成了。

我真的是太衝動了。不過還好, 更了解 jinja2 的 extension 怎麼寫的, 也可以準備來 rework 之前寫的 pipeline tags for jinja2。

25 9 月

mac, screen, vim

這陣子只要開了 screen, 使用 vim 的時候用滑鼠 copy & paste, 他就會連同後面的空白一起貼上, 造成很大的困擾。Google 又找不太到解答, 不過解的方式很簡單。把 term 從 screen 改成 xterm-color 就可以了。(真是感到慚愧阿)

以下是我的 .screenrc (前頭好像也是從網路上找到的)

# 關閉啟動訊息。
startup_message off

# 加入狀態列。
caption always "%{=u .r} %-w%<%{=ub .Y}%n %t%{=u .r}%+w "
hardstatus alwaysignore
hardstatus alwayslastline "%{= .K} [%l]%<%=%{= .Y}$USER%{= .R}@%H %=%{= .m} %Y/%m/%d%{= .M} %0c "

# 將預設編碼設為 UTF-8。
defutf8 on

term xterm-color
cjkwidth off
20 9 月

bootstrap 的 navbar-fixed-top

如果使用 navbar-fixed-top 的話, 要記得在 body 加上 padding。沒有看文件直接參考別人的 code 真的是會碰到問題阿! Trace 了半天才發現 style 加在 body 上。

body {
padding-top: 60px;
}

緣由其實是我想要看有沒有 fluid + fixed 的 bootstrap layout 可以參考, 於是乎找到了 Bootstrap: Fixed gutter width in fluid layout? 這篇文章。他的方式就是讓中間的 fluid layout 空出左邊或右邊的 margin 達成。

19 9 月

django 的 staticfile

今天一直在搞這個, 搞不定。以下是整理的結果。

若 DEBUG = False, django 會跑去 STATIC_ROOT 設定的 folder 底下找 css/js 等檔案。如果這邊找不到, 會直接在 manage.py 噴 error 並且出現下列訊息

ValueError: The file 'mod.font.css' could not be found with
<pipeline.storage.PipelineCachedStorage object at 0x7faca89dbf90>

另外, 也是在 DEBUG = False 的情況之下, urlpatterns += staticfiles_urlpatterns() 也是沒有用的。詳情請見 https://github.com/django/django/blob/master/django/conf/urls/static.py

18 9 月

踩到 ubuntu libjpeg 的 bug

今天花了一些時間, 想要把 gunicorn 的 script 整理一下。於是找了幾個 solution, 最後決定搭配 upstart 以及一支自己寫的 start.sh 讓 gunicorn 跑起來。後來我發現有一個很奇怪的訊息, 每一次跑起來, 有 request 進來, 就會丟

Error opening file for reading: Permission denied

非常奇妙的事情在於, 不同權限執行 gunicorn 會有不同的結果。以上的錯誤發生在我用 root 執行 gunicorn –user=web 才會發生。我如果使用 web 執行 gunicorn, 或是用 root 執行 gunicorn (但是不加上 –user=web) 都不會有這樣的問題。

Trace code 了許久, 最後發現是在 import PIL 的這一行出錯

import Image from PIL

上網查了一下, 是 ubuntu libjpeg 的問題。Reference 第二篇寫得很明確來龍去脈。

 

Reference:

  1. Error opening file for reading: Permission denied
  2. seteuid apps report perror() on trying /proc/self/auxv
15 9 月

開發網頁相關的 packages

以前大概就是用簡單的 HTML, 加一點 CSS, 然後刻一刻 javascript。最近越來越多東西出來, 例如幾年前 AJAX 出現, 然後 jQuery。現在寫網頁已經跟以前不太一樣了。從今年二月開始比較密集的在做網頁, 也算邊做邊學吧。

前端, 大推 Bootstrap。如果不想花太多精力去雕刻 CSS 以及網頁的 components, 用他就對了。他除了把視覺美美的東西都弄好, 大概也處裡 cross-browser 到差不多。而他連 grid & responsive 都處理好了。另外 jQuery 大概就是一定會使用的了。

後端, 其實太多偏好了。我最後選用 django。他的很多東西真的還挺好用的, 不過我個人認為在 ajax 的部分還沒有到很成熟。也許哪天會換 ruby on rails 來試試看也說不定。

曾經一度想要使用 mongodb 來當 database storage, 但最近發現, 我目前還挺依賴 django 的 models。而若是使用 mongodb, 則很多東西變成要自己去做掉, 因此反而最近新的功能都是做在 relational database 上。