在Lion server上啟動sshd
上次那篇真有白痴到了, 開個userdir還自己手動改config, mac嘛, 總有GUI的, 這次發現不能ssh連入本來也想手動改, 後來發現, 開啟sshd的方法跟設定userdir其實都一樣在系統設定內:
設定就在"共享"內:
網頁共享是"userdir"的設定, 遠端登入是sshd
Enable user web directory in Mac OS Lion Server
最近去美國出差回來買了一台Mac mini server, 買來當然要物盡其用囉, 架個server, web也自然免不了的
剛試著要使用user dir (也就是 http://my_domain/~julianshen) 發現行不通, 看起來它是使用Apache 2.2.19, 所以看了一下httpd.conf, 原來是沒enable, 因此試著打開它, 不過發現它似乎沒有做好的GUI setting可以讓你很簡單打開, 還是得修改些東西:
- 它的"Include /private/etc/apache2/extra/httpd-userdir.conf"其實是躲在"<IfDefine WEBSHARING_ON>“這段內, default似乎沒定義這個值
- ”/private/etc/apache2/extra/httpd-userdir.conf"定義的userdir是"Sites"
- Http daemon的啟動config在: /System/Library/LaunchDaemons/org.apache.httpd.plist
因此只要
- 在 “/System/Library/LaunchDaemons/org.apache.httpd.plist”(<array></array>內)加入
<string>-D</string>
<string>WEBSERVICE_ON</string> - 把你的html/php檔案放到你的家目錄(比如說/Users/julianshen)的Sites目錄下, chmod 755
OK, 這樣就大功告成, 可以用 http://my_domain/~julianshen 連上了…
Backup Picasa Album
寫了一個script來備份picasa album, source在這
基本上應該可以備份你有權限看到的, 只是目前還有點bug, 已知的bug是針對沒設定file name的photo會有問題
使用方式是, 在跟這個script同一目錄下建一個 conpig.py 內容是:
email = ’[email protected]’
password = ‘yourpassword’
用Browser找到你要備份的相簿, copy下URL (URL格式大多像是這樣: https://picasaweb.google.com/12223123123213/kKNvm )
然後執行 python pgrab.py album_URL
這樣就可以了 (必須要有安裝python gdata module才可以執行)
Bug以後再改….
startActivityForResult and callback in WebView
想半天標題不知道怎下, 有點不是很貼切, 內容也寫的有點懶 :P 有可能會看不懂吧
最近開始想要一個禮拜想一個東西來實踐一下(不知道可以持續多久:P), 這禮拜想到的是這個: 從WebView內的javascript去叫起一個Activity, 然後把這Activity回傳的結果回傳給WebView內的javascript
具體的假想應用範例: import contact information, 從Javascript內叫contact picker, 並把所選的contact資訊匯入WebView內的form中
首先, 呼叫contact picker的範例如下:
public void launch()
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
startActivityForResult(intent, PICK_CONTACT);
}
基本上, 是要使用startActivityForResult, 這樣才能把所選定的contact給回傳給我們的Activity
但如何讓這lauch被javascript call到呢? 我們必須把這個method封裝到一個class內, 我用一個名叫ContactLauncher的class來做封裝, 並且將這個interface指定給WebView:
webView.addJavascriptInterface(new ContactLauncher(), “contactPicker”);
這樣一來, 我們在javascript內就有一個contactPicker可以供呼叫了, javascript的範例如下:
function launchPicker()
//call picker
{
if(contactPicker) {
//register callback
window.activitycallback = function(response) {
$(’#name’).val(response.name);
};
contactPicker.launch();
} else { //no picker }
}
我們可以在javascript內透過"contactPicker.launch()“來叫起Contact picker, 這個就會直接呼叫ContactLauncher裡的lauch()
那在這之前的程式碼是幹啥用的呢? 由於launch()並不是一個blocking call, 並不會等到結果回傳後才結束, 而我們又要startActivityForResult回傳回來的資料, 因此我們需要一個callback來接收回傳的資料
那怎讓javascript可以接收回傳回來後的資料呢, 這邊我利用一個類似javascript injection的方式來做(原理是利用WebView可以接收"javascript:"這種形態的url)
以下是onActivityResult的實作 (這邊偷懶只取一個Display name):
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == PICK_CONTACT) { Cursor c = managedQuery(data.getData(), null, null, null, null); c.moveToNext(); String name = c.getString(c.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); String json = "{name:'"+name+"'}"; webView.loadUrl("javascript:window.activitycallback("+json+");"); } }
因為在WebView內的那個javascript page我已經先安插了一個activitycallback, 所以就利用loadUrl來呼叫它, 這樣就大功告成了!
這只是一個簡單的範例, 還可以做的更generic一點, 比如說把傳入的資料轉化成json這段, 這招應該還可以做一些應用才對