2009年10月11日 星期日

工作後的第一個週末

公園宿舍窗外一景


這從我的寢室往外頭拍攝的,可能是早上七點或八點的景色,一幅田園風光,看似悠閒。


工作滿三週,前兩個週末都返家,直到這週才有空閒緩緩腳步,只是下週起又得到處爬爬照囉。工作滿三週的心情嘛,雖然碩士時已將求學心態改成近於公司上班的情景,但仍不夠強烈,還可以自由地選擇起床、上班、吃飯和下班的時間,現在的生活,完全地規律化,約莫六點五十起床、七點半出發,在餐廳或合作社買個早點,回到辦公室大概五十分不到,就差不多開始上工了。約十一點五十出發吃中餐,回來睡個午睡,又開始工作到五點近半。


這陣子有些感觸,記得以前我跟在上班的老姐提過,要否下班繼續進修,像是考公務人員等,說真的連我上下班都算正常,還都提不起勁。假設晚上七點回到寢室,晚上十一點半準備睡覺,這樣一天也才四個半小時可用,還不包括洗澡摸魚閒聊。想一想,時間比學生時代還要少,還要更緊湊,很難想像這已是科技業最符合人性的上下班時間了。









前陣子看了上面那則影片,主要的是它呈現的字句,的確很接近週遭人的感受,雖然有人說影片後面算是宅宅的幻想,算是最不實際的片段,因為鮮少有人會發現孤單的自己的。


這幾天的工作內容,大多是使用 facebook 相關的東西,讓我意外地看到以前國三認識的美術班同學,跟他好像高二後聯絡變很少,印象中最近的一次可能是他大一打電話跟我閒聊,那時他還在播弄著琴弦。從他稀疏的照片文字,我發現他應該是鮮少還保留那份青春動力,真令我感到佩服。記得學生時代發生的種種,加速自己體驗現實社會的一切,人真的很難輕易地瀟灑,有太多的重擔擺在前頭,唯一最輕鬆的面對方式,就是扛起它吧!


我覺得要改變自己之前,就要先了解環境,目前接近完成第一步驟吧?至於目前的目標嘛,先嘗試做個對團隊有貢獻的人,雖然還有一大段路要走。


冷氣房,大概是唯一的缺憾,灑在臉上的永遠是日光燈。悶的時候,出去晃晃曬曬太陽吹吹風看看天,將會是最享受的一種方式。


2009年10月10日 星期六

Facebook API Example - 客製化 Quiz 測驗教學筆記

雖然已經有一些制式的製作方式:



等等的,皆可以透過 Quiz 關鍵字在 Facebook 查詢到許多跟測驗相關的應用。大部分是已經製作好流程的,只要填寫一下問題、結果,就可以很快地完成一張測驗表。然而,有時候要推服務時,可能會用到許多 Javascript API ,往往那些 Quiz 製造機只適合用來填寫文字跟圖片,這時候就還是得靠人工方式了!沒錯,就是要寫程式!此例以 PHP 跟 Javascript 為範例實作。


製作一個 Quiz 的流程,主要可以分成四部份:



  1. 顯示問題及收集答案

  2. 顯示結果前,詢問是否要邀請朋友參與

  3. 顯示結果和留言

  4. 將結果發佈至塗鴉牆


整體上可以簡化到兩步,就是顯示問題收集答案跟顯示結果,但這樣會使得最後一頁要做的事很多,我做了一兩個制式的測試,發現還有每一個問題就要換一個頁面,這種理由多半是要顯示廣告用的,使得每到一頁就多了一次廣告流量。我覺得分成四部份應該還滿恰當的,再細分下去有點不妥,除非是介面的設計或是問題太多。


在實作上,依上述分類可以分成 3 個頁面,第一個頁面負責顯示問題跟收集答案;第二個頁面則是提供使用者便利地點選朋友寄送邀請函;第三個就是顯示結果,以及留言的顯示,至於第四部分則可在第三頁搭配 Javascript 來提供發送,故可以少一個頁面。


流程:



  1. 新增與設定 App



  2. 顯示問題及收集答案

    • 一般的 HTML Code



  3. 顯示邀請朋友參加的介面

    • FBML 版

      • <fb:fbml>
                <fb:request-form action="?status=2" method="POST" invite="true" type="MyAppName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/my_app_name/\" label=\"Authorize My Application\"") ?>"
                        <fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
                </fb:request-form>
        </fb:fbml>



    • Iframe 版


      • <fb:serverfbml style="width: 100%;">
            <script type="text/fbml">
                <fb:fbml>
                    <fb:request-form action="?status=2" method="POST" invite="true" type="XFBML" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/my_app_name/\" label=\"Authorize My Application\"") ?>"

                        <fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
                    </fb:request-form>
                </fb:fbml>
            </script>
        </fb:serverfbml>





  4. 顯示結果後,提供 Post 到個人塗鴉牆(採用舊式申請 template 的方式,facebook 已打算在 2009/12/20 停用此功能,此例先保留給舊式範例,新式用法歡迎參考:發佈到個人塗鴉牆的樣版設定教學)


    • FBML

      • <script type="text/javascript">
        var template_id = number_id;
        var user_message_prompt = 'What do you think of this book?';
        var user_message = {value: 'write your review here'};

        var template_data={
                'test_name':'Taipei' ,
                'test_result':'OK',
               
        'images':[{'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg',
        'href':'http://tw.yahoo.com/'}]
        }
        var body_general='';
        var target_ids = '';

        var continuation = function() {
                // do something
        };
        Facebook.showFeedDialog( template_id, template_data, body_general, target_ids , continuation, user_message_prompt, user_message );
        </script>


      Iframe

      • <script type="text/javascript">
        FB_RequireFeatures(["XFBML"], function(){
            FB.Facebook.init( 'appapikey' , '/path/xd_receiver.htm' , null );
            var template_id = number_id;
            var user_message_prompt = 'What do you think of this book?';
            var user_message = {value: 'write your review here'};

            var template_data={
                    'test_name':'Taipei' ,
                    'test_result':'OK',
                    'images':[{'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg', 'href':'http://tw.yahoo.com/'}]
            }
            var body_general='';
            var target_ids = '';

            var continuation = function() {
                    // do something
            };

            FB.Connect.showFeedDialog( template_id, template_data, target_ids , body_general, null, FB.RequireConnect.require, continuation, user_message_prompt, user_message);
        </script>



    • 至於 template_id 部分,則是要先去製作樣版




  5. 新增留言板

    • <fb:fbml>
              <fb:comments xid="a_unique_id" showform="true" canpost="true" candelete="false">
                      <fb:title>請留下寶貴的意見</fb:title>
              </fb:comments>
      <fb:fbml>  






常見問題:



  • 什麼是 templates

    • 這是一個預先刻劃好的樣版,可重複使用,只需要填寫關鍵字就行了!最大好處是可以很漂亮的排好擺在塗鴉牆上,而搭配關鍵字的變動,就可以拿來當做測試結果的顯示,好比如 A 得 90 分、 B 得 75 分等等,就只要把關鍵字弄成可變動囉!詳細部份可以到 http://developers.facebook.com/tools.php?templates 玩玩,可以為自己的應用程式製作專屬的樣版,而上述就是一個使用樣版的塗鴉牆例子。

    • 採用舊式申請 template 的方式,facebook 已打算在 2009/12/20 停用此功能,此例先保留給舊式範例,新式用法歡迎參考:發佈到個人塗鴉牆的樣版設定教學



  • 無法顯示 templates

    • 要特別留意傳給 templates 的資訊,連 images 變數中的 src 位置不存在也會導致不會顯示,當初以 IE 測試,發現很久都沒顯示訊息,改用 Firefox 才蹦出 src 位置不對的消息,另外,還可以參考下面連結的 showFeedDialog 的相關文章,有的跟隱私有關。



  • 使用 fb:request-form 之 略過 / Cancel 問題

    • 當第二頁採取呈現 Invite Friends 頁面時,當使用者點選 [略過] 或 [寄送邀請] 時,頁面將導向於 action 的位置,然而,有時我們會使用 GET 的方式來掌控頁面流程,但有些時候不希望將訊息暴露在瀏覽器的 url 資訊上,此時可以解決的方式是將資料改採用 POST 傳遞


    • 留意的是當使用者點選 [略過] 或 [Cancel] 時,這份資訊卻不會送給 action 所指定的頁面,最簡單的處理方式,就是使用 SESSION 變數來處理

      • 在進入第二頁時,將 $_SESSION['flag']  =  1 

      • 當使用者用了 [略過] 或 [Cancel] 時,就可在 action 所指向的 url 進行處理囉,例如得知此 flag 資訊,自動將 status 設成 2 。設定完後,可以再將 flag 清掉

        • unset( $_SESSION['flag'] );








參考資訊:



簡單的 FBML 範例程式,需填寫 API Key 、Template ID 等設定:


<?php
// Copyright 2007 Facebook Corp. All Rights Reserved.
//
// Application: TEST
// File: 'index.php'
// This is a sample skeleton for your application.
//

require_once 'facebook.php';

$appapikey = 'your_app_api_key';
$appsecret = 'your_app_secret';
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook->require_login();
$template_id = 0123456789;

$status = isset( $_REQUEST['status'] ) ? intval( $_REQUEST['status'] ) : 0 ;
switch( $status )
{
case 1:
?>
<p style="width:100%;text-align:center;">
...等待結果運算...<br /><br /><a href="?status=2">觀看結果</a><br />
</p>
<fb:fbml>
<fb:request-form action="?status=2" method="POST" invite="true" type="MyQuizName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/your_app_name/\" label=\"Authorize My Application\"") ?>" >
<fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
</fb:request-form>
</fb:fbml>
<?php
break;
case 2:
?>
<script>
function do_post()
{
var template_id = <?php echo $template_id; ?>;
var user_message_prompt = '想說的話:';
var user_message = {value: ''};
var template_data={
'test_name':'Tapie' ,
'test_result':'OK',
'images':[
{
'src':'http://pad.thedigitalmovement.com/_blaise/2007-06-15-dgen-breakfast.jpg',
'href':'http://tw.yahoo.com/'
}
]
}
var body_general='';

var continuation = function() {
// do something
};
Facebook.showFeedDialog( template_id, template_data, body_general, '', continuation, user_message_prompt, user_message );
}
</script>
<p style="width:100%;text-align:center;">
測試成果:100分<br /><a href="#" onclick="new Dialog().showMessage('測驗結果', '100分').onconfirm = do_post ; return false;">詳細資訊</a><br />
</p>
<?
break;
default:
?>
<form id="testForm" method="POST" action="?status=1">
<input type="hidden" id="Q_number" name="Q_number" value="1" />
<table width="100%">
<tr>
<td>Q1:你會製作表單嗎?</td>
</tr>
<tr>
<td>
<input type="radio" name="Q[0]" value="1" />會 <br />
<input type="radio" name="Q[0]" value="2" />不會
</td>
</tr>
<tr>
<td>
<button style="submit" onclick="document.getElementById('testForm').submit();">Submit</button>
</td>
</tr>
</table>
</form>
<?php
break;
}
exit;
?>



2009/10/28 筆記:


上述例子採用單一檔案(index.php)搭配參數(status)來決定目前的狀態(1:填寫答案,2:邀請朋友,3:顯示結果與張貼個人塗鴉牆),在部分情況會有一些問題,如新增留言板服務時等等的。


測試結果,建議可以改成 3 個頁面獨立運作比較乾淨,依序是 index.php 、 invite.php 和 result.php,程式碼範例如下:



  • base.php

    • 這個是下面這幾支程式的最上頭都要 include 進來的片段

    • <?php
      // Copyright 2007 Facebook Corp.  All Rights Reserved.
      //
      // Application: TEST
      // File: 'index.php'
      //   This is a sample skeleton for your application.
      //

      session_start();

      require_once 'facebook.php';

      $appapikey = 'your_app_api_key';
      $appsecret = 'your_app_secret';
      $facebook = new Facebook($appapikey, $appsecret);
      $user_id = $facebook->require_login();
      $template_id = 123456789;
      ?>




  • index.php

    • <?php
      require( 'base.php' );
      ?>
      <form id="test" name="test" method="POST" action="invite.php">
              <table width="85%">
                      <tr>
                              <td><br /><hr width="70%" /></td>
                      </tr>
                      <tr>
                              <td>
                                      Q1:請問太陽是否都從西邊出來?
                              </td>
                      </tr>
                      <tr>
                              <td>
                                      <input type="radio" name="Q1" value="1" checked /> Yes <br />
                                      <input type="radio" name="Q1" value="2" /> No <br />
                              </td>
                      </tr>
                      <tr>
                              <td><br /><hr width="70%" /></td>
                      </tr>
                      <tr>
                              <td>
                                      Q2:請問月亮是否都從東邊出來?
                              </td>
                      </tr>
                      <tr>
                              <td>
                                      <input type="radio" name="Q2" value="1" checked /> Yes <br />
                                      <input type="radio" name="Q2" value="2" /> No <br />
                              </td>
                      </tr>
                      <tr>
                              <td>
                                      <button>送出</button>
                              </td>
                      </tr>
              </table>
      </form>





  • invite.php

    • <?php
      require( 'base.php' );

      // 計算分數
      $_SESSION['score'] = 0;
      if( isset( $_REQUEST['Q1'] ) && $_REQUEST['Q1'] == 1 )
              $_SESSION['score'] += 50;

      if( isset( $_REQUEST['Q2'] ) && $_REQUEST['Q2'] == 2 )
              $_SESSION['score'] += 50;

      ?>
      <fb:fbml>
              <fb:request-form action="result.php" method="POST" invite="true" type="MyQuizName" content="快來挑戰!<?php echo htmlentities("<fb:req-choice url=\"http://apps.facebook.com/your_app_name/\" label=\"Authorize My Application\"") ?>" >
                      <fb:multi-friend-selector showborder="false" actiontext="邀請朋友參加此測試">
              </fb:request-form>
      </fb:fbml>





  • result.php

    • <?php
      require( 'base.php' );
      ?>
      <script>
      var message = '你真厲害';
      function do_post()
      {
              var template_id = <?php echo $template_id; ?>;
              var user_message_prompt = '感言:';
              var user_message = {value: ''};
              var template_data={
                      'images':[
                                      {
                                              'src':'http://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Facebook.svg/200px-Facebook.svg.png',
                                              'href':'http://www.facebook.com/'
                                      }
                              ] ,
                      'level' : message
              }
              var body_general='';

              var continuation = function() {
                      // do something
              };
              Facebook.showFeedDialog( template_id, template_data, body_general, '', continuation, user_message_prompt, user_message );
      }
      </script>
      <h1>測驗結果: <?php echo $_SESSION['score'] ; ?> 分</h1>
      <a href="#" onclick="new Dialog().showMessage( '分數' , '<?php echo $_SESSION['score']; ?>' ).onconfirm = do_post;return false;">張貼至個人塗鴉牆</a>
      <hr witdh="95%" />
      <fb:comments xid="a_unique_id" showform="true" canpost="true" candelete="false">
              <fb:title>請留言</fb:title>
      </fb:comments>




除了要更改 base.php 中的資訊外,要記得在 result.php 中的 template 等資訊也要適當修改,我記得如果連 src 位置打錯或不存在時,此時就不會蹦出樣版喔,要分外留意啦


2009年10月8日 星期四

將 dmg 檔轉成 img 檔或 iso 檔 @ Ubuntu & Windows XP

一隻將 MAC OS 的 dmg 格式轉成 img 格式,另外還有相似的 dmg2iso ,顧名思義就是轉成 iso 檔,只是在網站上並沒看到後續的維護,那就使用轉成 img 檔。有需要在從 img 轉成 iso 檔吧。


下載 dmg2img 、dmg2iso 網站位置:http://vu1tur.eu.org/tools/


實作上以 dmg2img 為例,畢竟 dmg2iso 已經很久沒更新。



  • Ubuntu 9.04

    1. 下載與解壓縮

      • # wget 'http://vu1tur.eu.org/tools/download.pl?dmg2img-1.6.1.tar.gz'

      • # tar -xvf dmg2img-1.6.1.tar.gz



    2. 編譯 dmg2img

      • # cd dmg2img-1.6.1

      • # make dmg2img

        • 若出現錯訊息,大概是找不到 bzlib.h,需先安裝 libbz2-dev

        • # sudo apt-get install libbz2-dev





    3. 轉檔

      • # ./dmg2img test.dmg test.img



    4. 掛載

      • # sudo mkdir /media/my_tmp

      • # sudo mount -t auto -o loop test.img /media/my_tmp




  • Windows XP with SP3


    • 下載 win32 binary

    • 指令跟上述一樣


      • dmg2img test.dmg test.img




此外,在 Mac OS X 的環境中,可以透過 磁碟工具程式 要將 DVD/CD 備份成 DMG 檔,若要轉成 ISO 檔的話,可透過 command line 執行:


$ hdiutil convert input.dmg -format UDTO -o output.iso
...
created: output.iso.cdr

$ mv output.iso.cdr output.iso


即可 


2009年10月3日 星期六

iPhone 3G IPSW Path @ Windows XP

C:\Documents and Settings\"UserID"\Application Data\Apple Computer\iTunes\iPhone Software Updates


2009年9月30日 星期三

[Linux] 安裝 Rainlendar 免費好用的行事曆 @ Ubuntu 9.04


圖片來源:Rainlendar 網站


Rainlendar 算是很不錯的行事曆軟體,過去我都在 Windows 上使用,這幾年它已分成免費版跟專業版,整體上我覺得免費就夠用了



  1. 下載 Rainlendar :http://www.rainlendar.net/ ,現在已出到 2.6 版

  2. 安裝就使用 dep 的方式,有視窗介面應該不難

  3. 下載中文語言包:Rainlendar Languages

  4. 解開後會有 zh_TW 的目錄,將它移到 /usr/share/rainlendar2/locale 即可

    •  # sudo mv zh_TW /usr/share/rainlendar2/locale

    • 接著只需在行事曆上點右鍵選 Refresh 後,即可在 Options 中設定顯示語言