2009-03-18

增加文章更新時間 (Show Post Update Time)

我的 Blog 大多都是一些個人筆記,有參考性的筆記除了分享給大家看,連自己有需要時三不五時也要來回顧和參考一番。不過因時制宜,有些東西總會因為時間變化而些要作調整,尤其像之前關於 LinkStation 的改機資訊,也因為機器變動、軟體和參考下載的網址有更新,所以在閱讀筆記的時候,不時也會一併更新已經失效和變更的部份。Blogger 顯示的文章時間,用的是「發表時間」,也就是說文章一旦公開,發表的日期和時間就不會變了(除非手動修改發表時間),這樣方便文章排列時依發表前後順序來整理,但也因為這樣,哪天如果有修改過這篇文章、想標示文章最後更新的時間,只好手動在文章裡告知了!(因為 Blogger 的樣板變數,Post 裡只有發表的 timestamp,並沒有更新的時間..)

不過之前在處理 Feed 內容的時候,有注意到 Feed Content 裡除了有文章的發表時間 (published),也還有更新時間 (updated) 啊,所以只要能透過該篇文章的 Feed 內容,就可以找出該篇文章最後的更新時間,把它抓出來用不就能達到目的了嗎?從 Feed 透過 JSON 抓資料顯示是小事,但遇到的障礙有兩個,首先,現在有的 Feed 標準是「全部文章」、或「全部留言」的資訊,我要的只是單篇文章的 Feed 內容,不會要我從全部文章的 Feed 來搜尋吧?其次,就算找到單篇文章的 Feed 資料,裡面的格式又為何(會這麼說,是因為和 Google 公告的格式不大一樣)?經過幾天的奮鬥,終於讓我解決問題做出這個 Hack,由於部份用法都不在官方的說明文件裡,所以格外花時間(在確定資料內容)。

顯示文章最後的更新時間

首先是單篇文章的 Feed 網址格式。之前找到的資料,Feed 的種類有 Posts Feed (所有文章)、Comments Feed (所有留言)、Labels Feed、還有 Post Comment Feed (單篇文章的所有留言),單純一篇文章的 Feed 其實沒什麼用(而且需要先找出 Post ID),找半天好不容易被我 try 出來,單篇文章的 Feed 網址是:

http://xxx.blogspot.com/feeds/posts/default/POST-ID

有了 Feed 就簡單啦,接下來用 JSON 來抓 Post 的 Update Time。根據 JSON 的 Parse 規則,Update Time 的變數是 json.feed.entry[i].updated.$t,不過我是單篇文章啊,沒有一堆 Feed Entry,所以資料結構和一般的 Feed 又不一樣啊!後來透過直接解讀該 Feed 的內容、並用 JSON 的規格來判斷,才知道該變數應該是 json.entry.updated.$t 啊!解決這兩個關鍵的問題,要顯示文章更新時間就一如反掌了!看不懂的人沒關係,一樣複製、貼上、修改就能用這個功能了。打開管理介面、版面配置、修改 HTML 樣板原始碼(一樣要展開小程式範本),在程式碼 <head> 區段內(</b:skin> 標籤後、</head> 標籤前),塞入 Javascript 程式:

<script type='text/javascript'>
//<![CDATA[
<!-- Function used for generating the last update time for each post: showPostUpdateTime() -->
function showPostUpdateTime(json) {
  var updateTime = json.entry.updated.$t;
  var publishTime = json.entry.published.$t;
  if (updateTime.substr(0,10) != publishTime.substr(0,10))
    document.write(' | 更新於 '+updateTime.substr(0,10)+' '+updateTime.substr(11,5));
}
//]]>
</script>

說明一下,這段 Javascript 的工作原理是:先取得該文章的「發表時間」和「更新時間」,如果「日期」一模一樣,那麼就不顯示更新時間(因為我覺得,在發表文章的同一天內對內容做一點修改無可厚非,可能只是打錯字)。如果日期不一樣,那麼就顯示該文章最後更新的日期和時間。(如果要改顯示格式、內容和判斷規則的,自己修改這段 Javascript,不要再來找我客制化了!)

接下來,要把觸發以上 Javascript 的函式呼叫塞到原始碼裡,這裡主要也是決定這段更新時間要顯示的位置。以這的範例來看,我把最後更新時間放在「發表時間」的後面,而且,只有在顯示該篇文章全文的時候,才會顯示出來(所以首頁看不到,判斷規則可以參考這篇文章)。所以先找到顯示發表時間 (<data:post.timestamp/>) 的區段,插入紅色的那個程式:

<span class='post-timestamp'>
  <b:if cond='data:top.showTimestamp'>
    <data:top.timestampLabel/>
    <b:if cond='data:post.url'>
      <a class='timestamp-link' expr:href='data:post.url' title='permanent link'><data:post.timestamp/></a>
      <!-- Fixed for display post update time -->
      <b:if cond='data:blog.pageType == &quot;item&quot;'>
        <script expr:src='&quot;/feeds/posts/default/&quot; + data:post.id + &quot;?alt=json-in-script&amp;callback=showPostUpdateTime&quot;' type='text/javascript'/>
      </b:if>
    </b:if>
  </b:if>
</span>

那個 if 的判斷句就是檢查是不是「顯示文章全文」的狀態,如果到處都想看到「更新時間」,那麼把該 if 判斷拿掉就行了。

會想加這項資訊,主要也是想標示文章最後的更新時間,自己在整理筆記時,才知道上次更新的時間,閱讀時也能知道這篇是不是 Po 完就沒動過的舊文章,對於值得一看再看或會修改的文章,這項資訊很有參考價值,對於愛 Po 流水帳、或是 Po 完連自己都不一定會再看的 Blog 來說,這項功能就完全用不到囉~

回應: 22

 

2009-03-12

LinkStation 的升級 Part2: 支援 SATA 硬碟

沒想到從 Part1 到 Part2 的發文中間隔了快兩年...XD~從前一篇 Part1 文章可以知道拆開 LinkStation 的詳細步驟,透過這些動作可以直接把原先 LinkStation 裡的「IDE」硬碟換成大容量的新硬碟,不過從市場趨勢來看,原來 LinkStation 裡使用的 IDE 介面硬碟漸漸消失,新出的大容量硬碟都是 SATA 介面的(就是從針腳的介面變成像金手指的介面),而 IDE 市面上買得到最大也只到 500GB,SATA 卻已經來到其四倍的 2TB (2000GB) 啦!為了 LinkStation 的未來,讓 LinkStation 能支援到 SATA 硬碟就非常重要了。不過這個動作不像軟體改機那麼簡單,這需要一個 SATA -> IDE 介面轉換的硬體轉接板,熟悉零組件的人應該知道這類轉板到處都有賣,不過那大多是給電腦用的,對寸土寸金的 LinkStation 小機殼來講,這類轉板就算能用,但也塞不進機殼裡啊!所幸和 LinkStation 同門師兄弟的 Kurobox 有推出其專用的 SATA/IDE 轉板,經測試回報在 LinkStation 上也能用,雖然台灣買不到,但最後還是透過「代購」的辦法請「神蹟兄」幫忙,這才入手這張玄人志向Kuro-SATA

買回來後苦無硬碟測試(其實是懶惰)、加上大容量硬碟價格居高不下,所以這張轉板擺在家裏生灰塵了一段時間,直到最近購入 1TB 的 SATA 硬碟,這才動手安裝使用。拆開 LinkStation 的步驟仍請參考 Part1 的文章,等硬碟安裝好再上轉接板、復原接線就大功告成啦!這個轉板的好處是不用掛啥驅動程式,裝上去硬體重頭到尾還是以為它只是個「IDE」硬碟(所以 Device ID 仍是 hda,不會變成 sda),除了拆機上轉板外,使用上和一般 IDE 硬碟無異,所以其他軟體改機步驟都不會受到影響。

之前也有人問到,到底其他 IDE 轉 SATA 的轉板到底在 LinkStation 上能不能用,除了有勇者回報他買了 Uptech 最後宣告失敗的經驗,好像大多人沒有概念有什麼困難。我以坊間看到應該是最小了的轉接卡做例子,下面用是 Uptech UTN620 轉接板將 SATA 硬碟接上 IDE 排線的樣子(原圖引用自 Roch's Blog 的這篇文章:IDE轉 SATA,Uptech UTN620/630 介面轉換器介紹):

關鍵點在那個 IDE 插座是往後的,LinkStation 上了硬碟的空間很小,小到連那個插座都快塞不下,更別說要把排線和電源接上去了,所以光看這張圖應該想像得到,一般這類介面卡除非特別設計,不然一定是不行的。反觀玄人志向的 Kuro-SATA,介面卡長這樣:

IDE 插座是往上的,電源插座還特別突出來往後!這樣就可以解決問題了嗎?請看實際安裝的樣子:

左圖是上轉接板前,右圖是上轉接板後

從左圖看來,硬碟在接排線前,機殼的空間就小到只塞得下一小片電路板,別說排線了,電容電阻大顆一點都可能卡到。而經過「客制化」的 Kuro-SATA 有特別調整過,專門給 Kurobox 或 LinkStation 使用,因此也應該只有這款「專用」的轉接板,才能應付讓 LinkStation 能支援 SATA 介面的硬碟。所以有這等考量、還想 Try 其他轉板的人,不要掙扎了,趕緊想辦法去找人代購 Kuro-SATA 吧,哪天轉板停賣、又找不到合用的 IDE 硬碟時,才不會欲哭無淚、讓 LinkStation 「巧婦難為無米之炊」啊~(我不是業代、也沒有幫忙代購啦,只是這篇和 LinkStation Hack 有關,想說網路上也沒有類似的中文文章,所以特別記錄下來,有興趣的自己去找神蹟大、或是其他日本代購的賣家~)

回應: 12

 

2009-03-08

起死回生的 LinkStation (via JTAG)

話說之前買了個 1TB 的 WD 硬碟,加上請人代購的 SATA 套件,目的就是為了讓我的 NAS - LinkStation 能夠上更大的容量,經過幾次測試發現沒問題後,打算重灌、讓我新的 1TB 硬碟走馬上任,無奈手賤,看到網路上有提到一個超棒神奇的 ROM:U-boot(LinkStation 的 Firmware 是放在硬碟上,而 ROM 裡面有基本的 Boot Loader,即便硬碟壞了也可以透過 ROM 開機來修復重灌,這個 U-boot 的作用就是提昇原廠 ROM 的功能),可以塞到原廠 ROM 的前面當 Boot Loader、讓使用者能靠按電源鍵來決定哪個開機區(不用再手動 swaphd),也可以在重刷的過程一併將原廠的 ROM 換成有 Telnet 功能的方便維修。抱著戒慎恐懼的心態想來試刷看看,沒想到才跑第一個步驟,馬上出現我看不懂的錯誤訊息,關機重開後,機器就送給我最害怕的 Diag 燈連閃五下:Flash memory error (不同閃燈數量代表的意義可以參考這篇文章)!死了!ROM 刷壞哩(明明就連第一個步驟都還沒開始哩,它告訴我空間不足啊),這個可不是我能解決的狀況啊!一失足成千古恨,難道我服役兩年半 NAS 從此就變成磚塊 (Brick,這個字現在已經也可以做「動詞」了),之前買來升級的套件和硬碟都用不著了嗎?

訪查網路的文章,據說這個情況發生,除了送回原廠(但早就過保固啦),唯一的手段就是上 JTAG (Joint Test Action Group)。透過在電路板上焊幾隻針腳做一個連接埠,用這個連接埠與電腦連線,藉由和晶片的直接溝通 (Daisy Chain),就可以進行電路除錯、訊號資料傳送和維修的動作。以上都是從維基百科上查來的,我只是個小文組,電工的知識一點都沒有,這輩子也沒用過電烙鐵,就算以上動作再簡單,對我來說都是難如登天(更何況,並沒有那麼簡單),還好在網路上找到有維修 LinkStation 的賣家(翔工坊),不只是單純幫忙改機,連搞 JTAG 都有經驗,我二話不說就快遞機器給他處理了!

根據賣家告知的流程,基本上就是先在板子上焊一組 2x8 的針腳頭,當作 JTAG Port,然後做一張 JTAG 的 Cable(用來把針腳轉 Printer Port,裡面還有塊電路板),透過這條線連接機板和電腦,以及 JTAG Software,就可以下命令送資料進 ROM 裡重刷資料(用講的比較簡單)!以下整理搞 JTAG 的步驟以及相關的資料,如果有錯可以糾正我,但有細節問題要問我就沒法回答啦(因為沒親手做過):

步驟一:先焊上 JTAG Port (照片是我被焊過的機板,正面和反面)

請參考這兩篇:Install a JTAG Port, Add Jtag Port,主要是交待每個針腳的意義。

步驟二:自己做一塊 JTAG,像下面這樣的東西:

參考這一篇文章:Building a JTAG Interface ,或是參考上面那篇,去買一條現成的 Cable,像這樣:

步驟三:連接電腦和機板(電腦還要有 Printer Port,或透過轉接),透過 JTAG Software (Openwince),準備對應的 u-boot.bin (如果要上 U-boot 的話)和 Firmimg.bin(Linux Initrds, 原廠 ROM 含 Telent 的,3 MB),以及相關命令,開始刷(據說要很久)!
參考這一篇文章:Building and using Openwince's JTAG Tools

步驟四:刷完重開測試。如果有裝 U-boot,可以用 Net Cat 監看開機過程。
參考文章:NetCat-A UBoot-Friendly Network Utility

幫我維修的賣家直接幫我先上 U-boot,然後再刷上原廠內含 Telnet 的 ROM (firmimg.bin),哇!這就是原先我手賤想要「升級」的狀態啊!東西塞進 ROM 後,除非硬體故障、或哪天又手賤去動 ROM(我不敢了),基本上這樣的 LinkStation 就所向無敵啦!想要從那個分割區開機,只要搭配 Power 鍵按幾下就行,如果想用新硬碟、或是不小心硬碟掛了,隨時都可以進到 EM (Emergency Mode) ,看是要重灌原廠韌體(從新分割區做起)、還是要 Telnet 進 EM 模式檢查和維修,這樣再也不用擔心要拆機器或搞壞啦!(希望自己和大家都不需要用到這篇筆記的動作....)

回應: 28

 

2009-03-05

增加文章留言回應的編號 (Show Comment Index)

習慣透過 Blog 和「讀者」溝通交流的人,應該會發現 Blogger 的留言回應少了一個很重要的參考,那就是留言的「順序編號」。雖說這個編號是流水號,但這個有順序的編號對某些人氣很高的 Blog 來說,代表了讀者留言的前後關係,有的粉絲會盯著作者發表或更新文章,透過搶第一個留言的方式來表達熱情,什麼搶「頭香」「沙發」之類的,雖然這種行為沒啥意義,但還是一堆人樂此不疲。當留言少、一眼整頁就能看完的時候,其實編號的意義並不大,但留言一多,其中還有鄉民在發問(偏偏一堆人不愛看其他人的留言或回應),如果要針對特定一篇留言討論(「五樓」?!),或告知答案在的第幾篇回應中,沒有這個編號就很麻煩了(雖然編號會因為中間留言刪除而改變,但雖不中亦不遠矣)。又不少鄉民愛用「幾樓」來指定特定的第幾篇留言,如果不在留言上打上「樓層編號」,留言在管理和討論上實在也很不方便,難不成要讀者一篇篇用手數嗎?

當然這個問題不少人也有發現(追根究底是 Blogger 的樣板語言裡,有迴圈語法卻沒有顯示迴圈 Index 的變數),既然如此,那只好手動塞 Javascript 程式在該迴圈外和迴圈內,單純做個計數器就能夠搞定,不過坊間的改法看起來比較不友善,因此這裡用比較簡單的方式來處理這個問題(鄉民們也比較容易剪貼來用)。

首先定義這個回應編號計數器的宣告和計算。登入管理介面,切到版面配置、修改 HTML 樣板原始碼(要展開小程式範本),在程式碼 <head> 區段內(</b:skin> 標籤後、</head> 標籤前),塞入以下 Javascript 程式:

<script type='text/javascript'>
//<![CDATA[
<!-- Function used for generating the index number for each post: ShowCommentIndex() -->
var CommentIndex = 0, CommentPostID = '';
function ShowCommentIndex(PostID) {
  if (CommentPostID != PostID) {
    CommentIndex = 0;
    CommentPostID = PostID;
  }
  document.write(++CommentIndex);
}
//]]>    
</script>

接下來決定在留言內,要顯示回應編號的位置。基本上只要放在產生所有留言的迴圈「後面」就行了,那一行是:

<b:loop values='data:post.comments' var='comment'>

舉例,我把留言編號放在該篇留言的最後面 (comment-footer 區段裡、留言的時間後面,如同上面的例圖一樣),顯示編號的程式碼放的位置和內容如下:

<dd class='comment-footer'>
   <span class='comment-timestamp'>
     @ <a expr:href='data:comment.url' title='comment permalink'>
       <data:comment.timestamp/>
     </a>
     <b:include data='comment' name='commentDeleteIcon'/>
   </span>
   <!-- Fixed for display comment index -->
   | <data:commentLabel/> #
   <script type='text/javascript'>
     ShowCommentIndex(&#39;<data:post.id/>&#39;);
   </script>
</dd>

其實新加的關鍵是上面的倒數第六行到倒數第二行,如果編號想顯示在別的地方,請自行變更那五行的位置就行了(想改字型大小、顏色或靠哪一邊,請自己定義那一段的 CSS 樣式)。

和別人不一樣的是,程式碼裡我多加了 Post ID 的判斷,因為那個計數器變數 (CommentIndex) 是全域變數,如果有其他模組「同時」要用這個函式,只要不要交叉呼叫,基本上同一個頁面不同的文章也可以產生正確的留言編號。對像我一樣用一堆 Hack 的人來說,算是多做一點檢查和判斷,以避免重複呼叫產生編號錯亂的情況~

回應: 29