LiveConnect OAuth2

講的比較仔細的是這幾篇:Mobile and Windows desktop appsOAuth 2.0 (Live Connect)Server-side scenarios (Live Connect)Developers – Learn how to bring data from Hotmail, Messenger, and SkyDrive to your mobile apps,第1篇比較粗略,但夠簡單。第2篇是有仔細講解參數以及流程(含圖),可以在遇到問題時做參考。看過以後,發現步驟的確是OAuth2,但就是沒辦法用 python oauth2 去套,就只能照步驟來硬刻了。

有試過httplib2,看能不能parse HTML再去摹擬POST登入,結果會回一個400的錯誤,拿到錯的頁面。python內建的webbrowser,只會用browser開出畫面,但沒有提供方法可以取回在網址列的網址。看來在拿 access token/authorization code 的部份,就只能先組出sign in的url,把瀏覽器開出來,讓使用者先去登入,然後允許以後,再請使用者把網址複製下來,貼到程式的輸入,讓程式去擷取 access token/authorization code,再保存下來。就先這樣子做吧,以後有更好的方法再來修正。

pyskydrive/skydrive .net api client

靈機一動用python+skydrive去找,有找到pyskydrive這個project,試用結果,是不行。專案是去年釋出的,追蹤了一下,發現是因為Skydrive頁面HTML一整個改掉,已經不能用原來的方法去parse了。

改看SkyDrive.Net API Client的source code,看能不能fork出來改。可是看跟試驗的結果,發現也不行使用。他使用的方法也不是正規作法,因此認証那關都過不了。

看來只能自己刻了。在LiveAPI的網站上有看到是使用 OAuth 2,就先安裝了 python oauth2 的library,可是參考範例以後,發現怎麼樣也套不上微軟的LiveAPI OAuth。於是就只能看官方的介紹跟文章來實驗與重刻了。

skydrive+fuse?

好像沒人寫,先找資料看看。

收集資料:

整體看起來,不要使用python,使用 mono+fuse+SkyDrive .Net API Client 似乎是比較好的解?!

學校教材的下載

有些科目的教材好多,用滑鼠可能會按到死。本想用 curl 來硬幹的,可是從登入頁面一路解析到教材下載頁面的時候,發現 ASP.NET 的頁面還真是難搞,後來選擇放棄。

於是想了一下看Firefox有沒有現成的AddOn可用,有,的確是有,那是DownthemAll,可是,教材下載頁面的”下載”是用javascript埋起來,所以必須解析div的onclick屬性,把真正的連結拿出來。這時候GreaseMonkey又再次派上用場,就是你啦!!於是就弄了這個userscript,他會在原來的下載圖形下方增加一個download連結,這樣DownthemAll就可以抓到。要用的話,可以直接到userscripts.org這邊安裝,下面是原始碼:

wordpress以SSH自動更新

考量到以後wordpress的更新問題,可是又不想開FTP的洞,所以研究了一下不使用FTP的方式,大致上就是照這一篇WordPress Automatic Update with SSH來操課即可。第一次更新失敗,在調整 wp-content/plugins 與 wp-content/themes 以後,就解決了。我把這兩個目錄的owner調整為apache:groupname,然後permission調整為0775。

wordpress開多站(blog)

好久沒用,印象中有WPMU,上去wordpress看,發現已經被廢棄了,現在只有一套wordpress。

一開始是找到這篇Installing Multiple Blogs,但裏面介紹的方法,第1種是教你把wordpress放到多個目錄,然後用多個資料庫來切,第2種也是把wordpress放到多個目錄,然後以table的prefix來切。不管怎麼樣,這兩種方法都會讓維護變得麻煩。後來是看到這篇Create A Network,這個是3.0以後才有的新功能,正是我要的。

大致描述一下方法,我用的是分目錄的方法,而非分網域的方法:

  1. 先把wordpress裝好。看你是要放在根目錄還是建個wordpress的目錄來放都可以。
  2. 改wp-config.php,找到註解”Happy blogging!”,然後把 define(‘WP_ALLOW_MULTISITE’, true); 放在該行上方。
  3. 重新登入,你可以在管理介面的左邊找到 Tools,裏面多了一個Network Setup,點選,然後填資料,Network Title填你要的名字,Admin E-Mail address填你的e-mail位址,點選Install。
  4. 依照畫面的顯示去修改wp-config.php、在wordpress目錄下建立.htaccess並且在wp-content/下建立blogs.dir目錄。這裡可能會遇到的陷阱,比較常發生的是.htaccess未生效,請檢查httpd.conf,看有無載入mod_rewrite,然後檢查AllowOverride,AllowOverride不能是None,應該填All。我個人是因為眼花,少貼了一行在wp-config.php裡,導致我重來了好幾次。第2塊說要改_SALT的那邊,我都沒改,這邊我要再查一下,看要怎麼產生,再填入。不過看起來對後面沒啥影響。
  5. 登出,再登入,到右上角的下拉選單,就可以發現有Network Admin,選了這個以後,就可以去管理站點了,像是建立新站、刪除站點…等等的。這樣就大功告成了。

Create A Network的後面還有介紹一些plugin,讓你可以每個站點有自己的plugin,不需要透過Administrator來安裝。

Tail call

簡單的說是遞迴的特例,好處是可以避免call stack的損耗。Stack Overflow上的回答蠻清楚的,還附了python範例:algorithm – What is tail-recursion?,英文維基百科上的說明:Tail call比中文維基百科上的來的好。
跟遞迴比較大的差別,目前我認知到的是會利用另外一個參數來傳遞結果,實際應用上應該只要是遞迴都可以改寫成Tail call吧,再想想可以怎麼應用。

Greasemonkey-輔助續借學校圖書

還是忍不住寫了,畢竟每次要為十幾本書打勾還是蠻累的。基本上就是多加兩個按鈕,一個幫我全打勾,一個幫我取消打勾。不過第二個按鈕好像永遠都用不到,這就是所謂的 over design 嗎? :-p

currying

前兩天看Wikipedia上的Currying時,突然頓悟了(可見之前都沒認真)。這個不看英文Wikipedia的說明,還真的是不容易看懂。簡單的說,假設有個 function 是 f( x, y, z ),currying 就是令 f1=f(1),當呼叫 f1( 2, 3 ) 時,就等於是呼叫 f( 1, 2, 3 )。

目前想到可以應用在 c/c# 沒辦法帶預設參數的情況上,像:[c]void func( int x, int y, int z ) { }
void new_func1( int y, int z ) { return func( 1, y, z ); }
void new_func2( int y, int z ) { return func( 2, y, z ); }
[/c]
你可以想像到,這是一項複製、貼上的體力活,用 currying 的話,可以很快創造出新函數:[c]/* 以下為虛擬碼 */
void func( int x, int y, int z ) { }
new_func1 = func(1); /* new_func1 仍是函數 */
new_func2 = func(2); /* new_func2 仍是函數 */
[/c]
在 python 裡,透過 *arg、**kwargs 可以很容易實現,文章可以參考 Currying and Python, a practical example,裏面有點複雜,其實只要看 curry 類別的部份,下面就是直接摘錄出來的實例:[python]class curry:
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
self.kwargs = kwargs.copy()
def __call__(self, *args, **kwargs):
if kwargs and self.kwargs:
kw = self.kwargs.copy()
kw.update(kwargs)
else:
kw = kwargs or self.kwargs
return self.fun(*(self.pending + args), **kw)
def func( a, b, c ):
print( a, b, c )
return (a+b+c)
func1 = curry( func, 1, 100 )
func2 = curry( func, 2 )
print( func1( 200 ), func2( 300, 400 ) )
[/python]
原理就是利用類別的特殊方法 __call__ ,呼叫 func2=curry( func, 2 ) 時,實際上是得到 curry 類別的實體。curry 類別的 __init__ 裡去做參數的判斷跟預存,等到把 func2 當函數執行時,就會執行到 __call__,這裡再去呼叫真正的函數。