最近去美國出差回來買了一台Mac mini server, 買來當然要物盡其用囉, 架個server, web也自然免不了的

剛試著要使用user dir (也就是 http://my_domain/~julianshen) 發現行不通, 看起來它是使用Apache 2.2.19, 所以看了一下httpd.conf, 原來是沒enable, 因此試著打開它, 不過發現它似乎沒有做好的GUI setting可以讓你很簡單打開, 還是得修改些東西:

  1. 它的"Include /private/etc/apache2/extra/httpd-userdir.conf"其實是躲在"<IfDefine WEBSHARING_ON>“這段內, default似乎沒定義這個值
  2. ”/private/etc/apache2/extra/httpd-userdir.conf"定義的userdir是"Sites"
  3. Http daemon的啟動config在: /System/Library/LaunchDaemons/org.apache.httpd.plist

因此只要

  1. 在 “/System/Library/LaunchDaemons/org.apache.httpd.plist”(<array></array>內)加入
    <string>-D</string>
    <string>WEBSERVICE_ON</string>
  2. 把你的html/php檔案放到你的家目錄(比如說/Users/julianshen)的Sites目錄下, chmod 755

OK, 這樣就大功告成, 可以用 http://my_domain/~julianshen 連上了…

寫了一個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以後再改….

想半天標題不知道怎下, 有點不是很貼切, 內容也寫的有點懶 :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()
{
    if(contactPicker) {
         //register callback
          window.activitycallback = function(response) {
                  $(’#name’).val(response.name);
          };

          //call picker
         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這段, 這招應該還可以做一些應用才對

用了Google+之後就有種感覺…Flickr總有一天會撐不下去的, 但我在Flickr五年來已經放有數千張照片了呀~~因此萌生了搬家的念頭, 至少多一個避風頭的地方

找了找, 似乎好像沒有一個好的工具…..加上這幾天學到了一句話, 想奉為座右銘: “How hard it is”…其實想想也不會很難啦…所以DIY DIY一下應該就有了

這個東西還可以順便驗證Google說的:

Free storage limits

Photos up to 2048 x 2048 pixels and videos up to 15 minutes won’t count towards your free storage.

Automatic resizing

All photos uploaded in Google+ will be automatically resized to 2048 pixels (on their longest edge) and won’t count towards your free storage quota.

第一點, 那是對的….不過第二點, 實在是騙人, 我把Flickr上的原始大小的圖往Picasa塞, 果然還是碰到塞爆的狀況了, 所以這次要release的這個版本就是會先resize到2048再上傳

看來看去Python最簡單, 事實上我也花一個多小時就而已, 不過太久沒寫, 我也不常寫, 不是跟他很熟, 就寫得不是很漂亮

Source code 底家啦!!

首先, 你必須要有:

  1. Beej’s Python Flickr API : “easy_install flickrapi” 安裝即可
  2. Gdata API : “easy_install gdata” 安裝
  3. Python Imaging Library (PIL) : “easy_install pil” (不過mac Leopard下, 用原本的python會裝不起來)
  4. Flickr API key : 請自行去 http://www.flickr.com/services/api/ 申請一把
  5. Gmail account (就Picasa account)

如果在Mac Leopard下, 建議用MacPort的Python2.6

使用方法:

  1. 在config.py內, 把API key, API secret以及Gmail的帳號密碼設定好
  2. 用python flickr_listsets.py 列出你帳號下所有的Photo sets, 以及他們的photoset_id
  3. 用python flickr2picsa.py photoset_id即可搬家了, 如果要一次搬多個photo sets就指定多個, 用空白隔開即可

Ok, 就寫到這, 這只是私用的小工具, 沒寫的很好, 不過目前應該夠我用了, 很歡迎有高手可以改造.. :P

    Nfc

    想不出啥好idea來利用NFC, 所以呢, 身體力行勝於一切, 寫隻小範例體驗一下比較真切, 所幸Android NFC API並不難, 從研究API到寫出這個範例, 比我畫上面那張圖花的時間還更短….

    接收的範例已經有了NFC Demo, 而且我比較想體驗一下P2P的狀況, 所以就寫了隻push的範例

    這範例的功能如:

    Idea

    功能很簡單: 在Browser瀏覽網頁時按下Menu->Share page->NFC Push demo, 然後拿另一支NFC裝置來讀取分享的頁面, 因此這一頁面需要能透過NFC push去發送一個含有欲分享的URL的Message

    首先要讓這隻程式支援NFC, 在AndroidManifest.xml有三個必要的要素:

    1. SDK level >= 10: <uses-sdk android:minSdkVersion=“10” />
    2. NFC feature : <uses-feature android:required=“true” android:name=“android.hardware.nfc”></uses-feature>
    3. Permission for NFC: <uses-permission android:name=“android.permission.NFC”></uses-permission>

    然後我們必須要一個Activity來支援URL的發送, 這個URL要包裝成NdefMessage

    NdefRecord rec = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, new byte[0],share.getBytes());

    new NdefMessage(new NdefRecord[]{rec})

    要支援push, 只需要在onResume時使用enableForegroundNdefPush就可以了, onPause記得把它disable (沒disable會怎樣? 我碰到狀況是, 沒disable, 可能連之後讀取似乎都有問題) , 文件裡面是說要在main thread裡呼叫, 但試驗結果是, 也不能放在onCreate

    Android API 網站上有一篇介紹NFC的, 還算蠻簡單的

    完整的範例程式在此