:::

我記憶中的景色,逐漸消失

布丁布丁吃布丁

我記憶中的景色,逐漸消失

由於高中就讀台中一中的緣故,我當時的活動範圍以一中商圈、臺中公園到臺中電子街為主。因此這些地方,散佈著我高中三年中點點滴滴的回憶。

今天由於國中圖博碩士論文獎助授獎簽約的緣故,在活動結束、同學們各自回家之後,我打算到這些地方看看。老實說,以前每次都是晚上才回來,看不太到什麼。而且聽說最近一中又有大變動,因此更讓我想回來看看。

2009-03-14-565

辱德入德之門,還在。

2009-03-14-542

莊敬樓川堂還在,但是怎麼背後景色怪怪的。

2009-03-14-543

空了,原本圖書館的位置,已經變成一片廣場。而且後面原本應該是慎思樓的老舊教室,變成了七層樓的新建築物。

2009-03-14-544

是的,這棟樓還是叫做「慎思樓」,但是這次已經不能爬牆了!

2009-03-14-546

位於一二樓的玻璃牆的地方是閱覽室,很多學生在裡面讀書。而慎思樓與旁邊的敬業樓連結處有遮雨棚,方便學生往來。

2009-03-14-570

敬、敬業樓居然有了電梯,雖然說五層樓高度有電梯算是合情合理,但是那電梯粉紅的顏色難免讓人聯想到該不會是想模仿敬業樓的磚紅色卻退色的慘狀。

2009-03-14-547

很久以前這個位置有著家政教室,但是現在已經不見了。

2009-03-14-549

圖書館在這裡。

 2009-03-14-571

但是空空如也,看不太出來像是有在運作的感覺。

 2009-03-14-550

慎思樓還有地下室。

 2009-03-14-568

剛剛看到的閱覽室其實有三層,其中一層在地下室。地下室還擺有一些書架,不過沒有擺書上去。

 2009-03-14-553

假日仍如此用功的學生,真是偉大!

2009-03-14-555

繞道慎思樓背後看看,司令台也變了,這種塑膠色調的感覺我不是很喜歡。

2009-03-14-554

排球場上的藍色是不是後來才塗上的?

 2009-03-14-560

景賢樓取代原有的人文館,現在變成二年級的上課教室。而原本是社團活動中心的人文館,則自從遷移到體育大樓之後,就再也沒有回來的樣子。

2009-03-14-561

原本這後面還有一個老舊廁所,記得好像是跟著人文館一起拆掉了。

 2009-03-14-563

學完檔案學之後回來看校史館特別有感覺。

 2009-03-14-564

具有歷史價值的建築啊……


關於其他的地方……

2009-03-14-566

原本的阿姨素食店,招牌已經剝落,位置也淪為停車位,阿姨們已經不在這邊販賣便宜的素食了嗎?

 2009-03-14-573

電子街的忠一商店,原本是許多男同學的回憶,現在變成了金碟科技。話說回來,電子街賣光碟的店家變多了,賣光碟有比較好賺嗎?

 2009-03-14-574

忠一的招牌,掛到哈日GAME館旁邊,但是狹小的店面前卻停滿了摩托車,而週六假日晚上,似乎沒有任何營業的跡象。


台中一中變好多,中央圖書館拆掉,慎思樓舊三層樓變成七層大型建築物。跟我畢業時候比起來,已經一半建築物不在了。不僅如此,校門對面的阿姨素食店、電子街的忠一都消失了。

今天去玩具便利屋的時候看到有人在挑Aquarian Age水瓶世紀的單卡,一邊跟新手介紹各顏色的特色,忽然覺得好懷念。那張かごめかごめ,那是一張很好用的Project Card啊! 

話說回來,如果有人問我台中哪個地方最美,我可能只說得出一中街、電子街、大里、霧峰——因為那些是充滿我的回憶的地方,熟悉的景色對我來說最安心,也是最美的地方。

然而,隨著離開這裡越久,越來越多景色逐漸消逝,只屬於我的美景,也一個一個消失中。台中到底哪裡美,我也快說不上來了……

(more...)

MicroSD迷你讀卡機,美觀,但不堪用

布丁布丁吃布丁

MicroSD迷你讀卡機,美觀,但不堪用

image image

Jiner Micro SD金屬質感真皮手機吊飾讀卡機,純正金屬質感迷你讀卡機,PChome販售199元,有黑色跟紅色兩款。

image

平心而論,在大小只有一般USB插槽的一半高度的MicroSD迷你型讀卡機中,JINER這款算是看起來最好的。但是,他的USB連接頭並不是常見的四片金屬,而是一種複雜的晶片型的接頭。

2009-03-13-538 2009-03-14-575
JINER的USB接頭 傳統的四片USB接頭

我暫時找不到JINER這種接頭是怎麼回事,但可以確定的是,在年代有點久的電腦上插上這種USB接頭,好一點是讀不到,壞的話就是讓整台電腦短路斷電。因此建議不要買JINER的MicroSD讀卡機!


2009-03-14-576

題外話,上面比較圖當中白色這款是我現在在用的ZENITRON(增你強,名字俗夠有力)的MicroSD讀卡機,價格也是200元,但是增你強的網站上完全找不到這隻產品,網路上也很少看到過,實在是很神秘。

缺點是白色容易髒、上面的字容易被磨掉、塑膠質感便宜貨、更糟糕的是MicroSD的插口處會隨著你拔掉讀卡機的時候一起鬆脫(orz)。優點是意外的內部有綠色LED燈,會在讀取的時候發光,是很好的設計。

總而言之,我還蠻喜歡這種迷你型的MicroSD讀卡機,還可以替換裡面的MicroSD卡來當隨身碟使用,真是方便又實用呢。

(more...)

布丁式Blogger自動摘要功能(jQuery版)

布丁布丁吃布丁

布丁式Blogger自動摘要功能(jQuery版)

image

感謝jQuery這個強大的JavaScript程式庫,現在在Blogger上面裝外掛已經不用去版面配置跟HTML的範本(template)奮鬥了(如下圖)。

image

你也知道,程式往往因為少改那幾行而出錯,每次要檢查錯誤都蠻麻煩的。

這次我改寫了之前的布丁式自動摘要功能,並以jQuery的方法來實做他,讓各位Blogger套用在自己Blog的時候能更加地簡單、直接,而且更迅速!


快速安裝

  1. 到Blogger管理介面裡面的「版面配置」中的「網頁元素」,再最下方點選「新增小工具」。(請不要在意為何我的版面配置如此之怪,因為我不小心又把導覽列卡錯位置了orz)
    image
  2. 選擇新增一個「HTML/JavaScript」小工具吧。
    image
  3. 看到設定畫面,標題可以留空,在內容的部份請插入以下程式碼:
    <script src="http://puddingchen.35.googlepages.com/jquery.js" type="text/javascript"></script>
    <script type="text/javascript">
    jQuery.getScript("http://sites.google.com/site/puddingchen35/Home/digest/puliBloggerDigest.js", function() {
    pBD = puliBloggerDigest();
    pBD.delayTime = 0; //執行延遲時間,單位是「毫秒」(1000毫秒=1秒)
    pBD.wordMin = 100; //自動摘要最少字數
    pBD.wordMax = 200; //自動摘要最多字數
    pBD.langBlogURL = "文章網頁"; //連結按鈕
    pBD.langReadAll = "閱讀全文"; //連結按鈕
    pBD.langContiReadAll = "繼續閱讀全文"; //連結按鈕
    pBD.langShowDigest = "僅顯示摘要"; //連結按鈕
    pBD.doDegiest();
    });
    </script>
    最後結果應該會如下圖:
    image
  4. 按「儲存」,完成安裝。

回到首頁的時候,應該就能看到你的文章順利被縮成100字到200字之間的摘要了。


進階設定:自訂你的自動摘要功能

你可以在程式碼當中修改參數,以自訂你的動摘要功能。參數在前面小節安裝程式碼的時候即可設定,例如「pBD.wordMin = 100; //自動摘要最少字數」即是。以下一一說明各個參數的意義:

  • delayTime 延遲處理時間:預設值為「0」毫秒(1000毫秒=1秒)。當你覺得在做自動摘要的時候會讓你網頁讀起來緩慢,你可以增加延遲時間,讓程式分批去處理。
  • wordMin 自動摘要最短字數:預設值為「100」字,此字數並不包含標籤內的文字,而是真的顯示的字數。當超過此字數之後,程式會尋找HTML標籤完結處當中自動摘要的切斷點。
  • wordMax 自動摘要最長字數:預設值為「200」字,此字數並不包含標籤內的文字,而是真的顯示的字數。當程式找尋自動摘要的切斷點超過此字數之後,程式會強迫設定此字數為切斷點,並且自動增加結尾標籤進來,以維持HTML的完整性。
  • 後面的則是各種按鈕的訊息,你可以自訂成其他訊息:
    • langBlogURL:顯示按鈕「文章網頁」;
    • langReadAll:顯示按鈕「閱讀全文」;
    • langContiReadAll:顯示按鈕「繼續閱讀全文」;
    • langShowDigest:顯示按鈕「僅顯示摘要」。

現在來舉一個設定與實際程式碼撰寫的例子:

  • 延遲時間為「500」毫秒,也就是0.5秒;
  • 最小字數為「50」字,最大字數為「100」字,這可以讓你的首頁看起來不會這麼長;
  • 訊息改為「Post Link」、「Read All」、「Read All」(其實跟前面的沒什麼差別嘛)、「Show Digest」,改成英文很有國際化的感覺。

那麼你的程式碼應該如此撰寫:

<script src="http://puddingchen.35.googlepages.com/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
jQuery.getScript("http://sites.google.com/site/puddingchen35/Home/digest/puliBloggerDigest.js", function() {
pBD = puliBloggerDigest();
pBD.delayTime = 500; //執行延遲時間,單位是「毫秒」(1000毫秒=1秒)
pBD.wordMin = 50; //自動摘要最少字數
pBD.wordMax = 100; //自動摘要最多字數
pBD.langBlogURL = "Post Link"; //連結按鈕
pBD.langReadAll = "Read All"; //連結按鈕
pBD.langContiReadAll = "Read All"; //連結按鈕
pBD.langShowDigest = "Show Digest"; //連結按鈕
pBD.doDegiest();
});
</script>

進階設定:手動插入摘要切斷點

如之前的布丁式自動摘要功能一樣,本功能支援你在撰寫文章時手動插入摘要切斷點。

切斷點分成三個種類,個別有特定的格式跟意含,如下說明:

手動摘要功能 需要插入的HTML程式碼
隱藏所有文章
  • <!--Hidden All-->
  • <!-- Hidden All -->
  • <span class="digest-mode hidden-all">&lt;-- HIDDEN ALL --&gt;<span>
顯示所有文章
  • <!--Show All-->
  • <!-- Show All -->
  • <span class="digest-mode show-all">&lt;-- SHOW ALL --&gt;<span>
此處之前設定為摘要
  • <!--Digest-->
  • <!-- Digest -->
  • <!--more-->
  • <span>DIGEST<span>

如果同時插入了這三種切斷點,則效果會由隱藏全部文章優先,其次是顯示所有文章,手動摘要則是最後才會生效的!


進階設定:儲存並修改你自己的自動摘要功能

布丁式自動摘要功能(jQuery版)是由Google Page Creator提供的空間。這空間有流量限制,速度也不快。如果你需要的話,可以自行下載下來並擺置到你的空間,然後修改安裝程式碼當中src的引用位置即可。

  • jquery.js:jQuery 1.2.6版本,也許你可以在jQuery的網站上找到更新的版本。
  • puliBloggerDigest.js:布丁式自動摘要功能(jQuery版),因為要搭配jQuery才能運作,所以安裝程式碼的時候一定要一起引用喔!

在我很久以前推出的布丁式自動摘要功能似乎大受好評,希望這次推出的改良版,能夠幫助更多Blogger來改善你們的Blog頁面。

不過還是要提醒一下,安裝太多JavaScript檔案會拖慢你的網站讀取速度,要在美觀與速度之間取得平衡喔!

(more...)

公用電腦安裝WinXP步驟

布丁布丁吃布丁

公用電腦安裝WinXP步驟

2009-03-11-537

最近這個週末都帶著學弟妹在灌電腦。儘管安裝Windows XP、安裝軟體等步驟我想大家應該都會,不過會不會考慮到使用者使用的感受,我想應該很少人會作到了。

以下列出我為公用電腦安裝的大略步驟,分上半部與下半部,還沒有細講為每個軟體調整的步驟。我想作完這些,才是一個「供人工作用的公用電腦」吧。


上半部:資料備份、安裝Windows、防毒軟體,然後備份硬碟

  1. Double Driver備份驅動程式,並勾選全部的驅動程式(特別注意顯示卡、網路卡、音效卡,以及週邊裝置,如印表機、掃描機、Webcam等的驅動程式);
  2. 記錄該電腦的網路設定;
  3. 準備好Windows XP的安裝光碟,如果沒有的話要到學校校園授權軟體下載裡面下載並燒錄成光碟(最新的是Windows XP SP3版本);
  4. 拔掉網路線;
  5. 重新安裝Windows,硬碟分割為C:15GB,D:剩餘空間;
  6. 建立兩個帳號,個別是admin跟user,都設定為電腦管理者
  7. 以admin登入,並為admin設定密碼。再以user登入,以下作業以user進行。
  8. 在D磁碟建立Desktop(取消唯讀屬性)、My Document、My Document\Start Menu、Program Files等目錄;
  9. 以「我的文件」按右鍵來修改我的文件的位置;
  10. TweakUI修改「桌面」、「程式集」等位置,並把原本位置的檔案手動移動過去;
  11. 重新開機,確認可以順利登入user,而且路徑都沒錯之後,準備以Acronis True Image光碟開機;
  12. 以Acronis True Image光碟開機,建立「Acronis安全區」,切割D磁碟,設定大小為15GB,並開啟「Acronis® 啟動還原管理員」;詳細作法,可以參考如何使用Acronis True Image備份作業系統?的圖解說明;
  13. 待Acronis True Image處理完成之後,重新開機,正常進入Windows XP,以user登入
  14. 利用Double Driver還原驅動程式,並到「裝置管理員」去檢查未安裝的驅動程式;如果找不到驅動程式,可以利用EVEREST來調查主機板的型號,並到該主機板的網站去下載驅動程式;
  15. 安裝軟體時,必需要將安裝路徑開頭由「C」改成「D」,也就是裝到D的Program Files資料夾當中。注意不要自己指定資料夾到Program Files,有些軟體不會好心地幫你建立一個資料夾的;
  16. 接著是安裝軟體:
    1. 安裝防毒軟體(Kapsersky之類的),檔案防護設最高層級;掃描的四種類別都設最高層級(如果電腦等級不足,那麼層級可以考慮降低),而且動作改成「不提示動作」,下面兩項都打勾;服務裡面的「啟用訊息通知」,關閉全部音效,關閉「特徵碼過期」的提示;
    2. 安裝WowUSBProtector,設定開機自動啟動、填入白名單(名稱隨意)、掃毒顯示方式設為「無毒時略過」、新版本通知設定「關閉」
    3. 安裝USBcleaner (詭異的是,USBcleaner的官方網站被Kaspersky認為有毒,所以我改提供別人的網頁),打開USBmon監控程式的「常規監控」,設成開機自動啟動(而日期監控是多餘的);利用USBcleaner的工具及插件,「禁用系統自動播放功能」、「設置免疫資料夾」
  17. 到下面的工具列上面按右鍵/內容,「顯示快速啟動」;「隱藏非使用中的圖示」僅留下Kaspersky、聲量、安全地移除硬體,其他設為永遠隱藏,以後安裝的程式也要作這個步驟;
  18. 一樣在「工具列及 [開始] 功能表內容」當中的[開始] 功能表「自訂」:程式數目設為12 (螢幕解析度高度為768px的時候,如果解析度更高,可以設更大一點);顯示在[開始] 功能表,隱藏「電子郵件」;
  19. 承上,到「進階」當中:取消「將最近安裝的程式反白顯示」;「我的文件」、「我的電腦」、「控制台」設成「以功能表顯示」;「我的音樂」、「我的圖片」關閉;關閉「設定程式存取及預設值」
  20. 桌面上按右鍵/內容(等於「顯示 內容」),螢幕保護裝置當中,取消「繼續後,以密碼保護」或是「回到歡迎畫面」、取消「桌面自動清理精靈」、在桌面設置「我的電腦」;
  21. 開始/所有程式當中:刪除Windows Catalog、設定程式存取及預設值兩個捷徑;
  22. 重新開機,登入沒有問題之後,開始準備進入Acronis進行第一次的完整備份;
  23. 重新開機,按F11進入Acronis True Image;選擇「備份」,備份「我的電腦」,選擇「C磁碟機」,選擇備份在「Acronis安全區」,選擇「完整備份」,壓縮層級設最大,並勾選處理完畢之後檢查備份套件,最後加個註解,以方便之後回憶你現在這個備份是在做什麼的,然後進行備份。
  24. 完成之後,重新啟動。

下半部:軟體安裝、備份

  1. 插回網路線,設定網路連線
  2. 以user的身份,修改LOGO跟桌布、以及外觀/色彩配置為「銀色」;
    1. LOGO:安裝電腦用:LIAS-LOGO
    2. 桌布:安裝電腦用:政大圖檔所桌布
  3. 以user的身份,安裝其他Portable(可攜性軟體、綠色軟體)的軟體,如FileZilla(FTP軟體)、FirefoxGoogle瀏覽器Q-Dir,安裝路徑為D:\Program Files\當中,各自開一個資料夾;並開啟看看能不能順利執行;
    ※為什麼要安裝Portable版本?因為原本的版本會把資料留在C:\Documents and Settings當中,這些資料在作硬碟備份/還原或影子系統的時候就會被還原回去。為了避免這種情況,建議使用Portable版本
  4. 設定user要自動開啟的portable程式;
  5. 更新Kaspersky的病毒碼、更新WowUSBProtector病毒庫
  6. 安裝免費軟體,注意安裝時選擇D,並一一開啟;
    1. allSnap(設成開機啟動)、
    2. OrbitDownloader(關閉開機啟動、關閉監控瀏覽器及點擊、設定預設下載目錄為桌面、關閉自動更新)、
    3. PCman(所有使用者共用設定)、
    4. Pismo File Mount Audit Package
    5. Unlocker(只留下關聯右鍵,其他「助理」、「ebay」都取消)、
    6. Teracopy(取代原本傳輸功能)、
    7. Unicode補完計畫
    8. CodeStuff Starter (SkyDrive備份)、
    9. Spybot(更新、免疫)等軟體、
    10. 新酷音(關閉自動更新,然後以下是個人習慣:設定一排顯示3字,設定按住Shift輸出大寫、字體顯示大小為24)、
    11. Taskbar Shuffle(開機啟動)、
    12. WinSplit Revolution(開機啟動)、
    13. DM2(開機啟動)、
    14. FastStone Image Viewer(設定關聯)、
    15. K-Lite Codec Pack FULL
    16. QuickTime Player(安裝威力導演時需要用到)、
    17. KMPlayer(設定關聯)、
    18. Open Office
  7. 安裝校園授權軟體及所上購買軟體,注意安裝時選擇D,安裝之後記得要開啟並取消註冊動作或是完成輸入註冊碼的動作
    1. Microsoft Office(安裝完之後要再進行Windows Update)、
    2. Adobe Acrobat(關閉自動更新)、
    3. DreamweaverFlash(註冊碼需要開啟之後才能使用)、
    4. SPSS(注意授權人數)、
    5. PhotoImpact(記得開啟之後取消註冊)、
    6. Photoshop(記得開啟之後取消註冊)、
    7. Nero(包括Nero、Nero Vision Expression、樣板)、
    8. WinRAR(設定壓縮預設為zip(方便管理)、最大壓縮、背景壓縮、等待其他壓縮程式、右鍵關聯為群組式;為了完成安裝,要把註冊檔複製到安裝目錄下)、
    9. 威力導演(在這之前要安裝Quick Time,安裝完成之後開啟輸入註冊碼、關閉自動更新)、
    10. CorelDraw(只要第一片程式即可)、
    11. 政治大學行政資訊系統安裝程式 2005 版(設定Kaspersky的駭客防護讓update.exe跟update_new.exe更新程式全部允許,稍後記得設定影子系統允許此資料夾的更新)
    12. 其他字型(注意,字型安裝太多會讓校務系統列印時當機)
    13. 安裝Windows Live Messenger,取消開機自動啟動;
  8. 安裝其他Portable軟體
    1. TweakUI
    2. Double DriverTeam Viewer(電腦臨時遠端用)、Notepad++AutoLogon(設定以user自動登入)、EFixIME Tool(調整輸入法順序)、7-zip(設定右鍵選單)、EVERESTImgBurn(設成中文介面、關閉更新)、ip-toolsAudacity
  9. 安裝印表機驅動程式。大部分印表機都要連接印表機本體才能運作,如果你也跟我一樣把電腦拆回實驗室裝的話,最後記得要回頭確認印表機驅動程式裝了沒;
  10. 以admin身份登入,用TweakUI調整特殊資料夾的路徑,同user;關閉桌面螢幕保護程式的「繼續後回到歡迎畫面」、取消「桌面自動清理精靈」、在桌面設置「我的電腦」;調整特殊資料夾的路徑完成之後,重開機,再以admin進入,檢查路徑變更是否成功;
  11. 設定admin開始/所有程式當中:刪除Windows Catalog、設定程式存取及預設值兩個捷徑;整理開始/程式集,依名稱排序(整理方法後述);
  12. 回到admin身份,安裝影子系統Shadow Defender,並以AutoLogon自動以user登入(如果之前忘記做了話);
  13. 進行Windows Update
  14. 用user身份進入,利用Starter關閉不使用的程式跟服務;
  15. 整理程式集內的捷徑,把最常用的放在第一層,不常用的捷徑放到「Other Programs」當中;把一些Portable的軟體建立捷徑到程式集當中(利用TweakUI,可以取消建立捷徑時的「捷徑 - 」字眼);其他依名稱排序;這兩個帳號都要作;
  16. 清理桌面跟回收筒,兩個帳號都要作;
  17. 設定所有瀏覽器開啟預設的網頁為政大首頁(http://www.nccu.edu.tw/),改預設搜尋提供者為Google;主要是user帳號要做;
  18. 如果你有印表機共享,請在此時設定。如果沒辦法順利共享,通常是Kaspersky駭客防護的隱形模式打開了,請關掉;
  19. 將user設為「受限制的使用者」;
  20. 重開機到Acronis True Image,進行增量備份;
  21. 全部設定完成之後,開啟「即使重新啟動也開啟影子模式」,保護C磁碟機,重新啟動;
  22. 如果順利自動登入user,並且影子模式正確啟動;
  23. 測試影子模式:嘗試以你自己的帳號登入Windows Live Messenger,然後重新啟動之後再回到user,你的帳號應該不會被記錄到Windows Live Messenger當中;
  24. 如果成功之後,再以Acronis True Image增量備份。全部安裝手續大功告成。

回頭整理一下步驟,發現這真是繁雜到讓人頭痛的程度,而我好像每次都是在不知不覺的情況做完這些設定,實在是很麻煩。

不過經過這些設定跟保護,我想之後也不需要常常重灌了吧。

(more...)

讓VirtualBox的VRDP連線的滑鼠同步

布丁布丁吃布丁

讓VirtualBox的VRDP連線的滑鼠同步

image 

一般來說,要操作VirtualBox建立的虛擬機器時,必須先連到安裝VirtualBox的Host OS,再連到虛擬機器Guest OS。作法如上圖中左邊的流程,整個步驟要兩次。此作法最大的問題在於Host OS限制連線使用者端,連帶影響Guest OS的使用者人數。

VirtualBox提供了VRDP的方法,讓你簡單地能夠利用遠端桌面直接操作虛擬機器(Guest OS),而不需要透過Host OS主機(如上圖中,右邊的方法)。

image

開啟VRDP的功能也很簡單,只要在VirtualBox對每一台虛擬機器的設定值裡面,切到「遠端顯示」,「啟用VRDP伺服器」並設定「伺服器埠」便可以了。當然,別忘了打開Host OS的防火牆喔。


VirtualBox VRDP 2009-03-10_145626

雖然這是很簡單也很確實的解決方法,不過不知道為什麼似乎很少人提出來講。在這邊佔個版面,特地拿出來講一下。

(more...)

DSpace使用XMLMetadata的方法

布丁布丁吃布丁

DSpace使用XMLMetadata的方法

之前我為DSpace 1.5.1寫過一種新型態的input-type: XMLMetadata,那裡只有處理到遞交(submit)處理,這一篇則是教大家如何利用儲存在資料庫的XMLMetadata API。

我假設你已經懂得如何從DSpace裡面取出你指定的Metadata Value,如果不懂,請參考DSpace系統文件裡面的內容管理API的章節,或是參考我之前寫過如何從DSpace的API裡面取得Item的Metadata Value教學


安裝XMLMetadata API

請把該檔案上傳到[dspace-source]/dspace-api/src/main/java/org/dspace/app/util/當中。

然後進行DSpace的重新編譯,方法如下:

  1. 進入指令模式
  2. 移動到你的[dspace-source]/dspace/目錄
    > cd [dspace-source]/dspace/
  3. 執行ant編譯
    > mvn package
  4. 移動到你的[dspace-source]/dspace/target/dspace-[version].dir目錄
    > [dspace-source]/dspace/target/dspace-[version].dir
  5. 執行ant打包
    > ant -Dconfig=[dspace]/config/dspace.cfg update
  6. 停止你的Tomcat伺服器
    > cd [tomcat]/bin/
    > ./shutdown.sh
  7. 複製新的.war檔案到Tomcat的webpapps目錄:
    > \cp -rf [dspace]/webapps/* [tomcat]/webapps/
  8. 重新啟動Tomcat伺服器
    > cd [tomcat]/bin/
    > ./startup.sh

測試是否安裝成功

請把該檔案放到你的DSpace在Tomcat的執行位置,然後用網址開啟該檔案看看。

例如[tomcat]/webapps/jspui/裡面。你用http://localhost:8080/jspui/XMLMetadataExample.jsp開啟,如果出現錯誤訊息表示安裝失敗。


使用XMLMetadata API

示範檔案:XMLMetadataExample.jsp

  1. 先引用org.dspace.app.util.XMLMetadata。
    <%@ page import="org.dspace.app.util.XMLMetadata" %>
  2. 從資料庫或是利用DSpace的API取得XMLMetadata的值,存入字串型態的變數當中,假如是設為xmlText。(其中rs.getString()是從資料庫查詢結果取出資料的語法,實際使用的時候,請自行設計)。
    ※以下是JSP端的程式,請寫在<% %>之間。
    String xmlText = rs.getString();
    假設取得的XMLMetadata值如下:
    <div class=\"xml-root\"><DIV class=node>
    <DIV class=node-type>node</DIV>
    <DIV class=node-title>教師</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-node</DIV>
    <DIV class=node-content-temp>
    <DIV class=node>
    <DIV class=node-type>node</DIV>
    <DIV class=node-title>人名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-node</DIV>
    <DIV class=node-content-temp>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>true</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaasdsdsdf </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaasdsdsdf </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>2 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>node</DIV>
    <DIV class=node-title>人名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-node</DIV>
    <DIV class=node-content-temp>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓ewrwere</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa </DIV>
    <DIV class=input-required>true</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>2 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>node</DIV>
    <DIV class=node-title>人名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-node</DIV>
    <DIV class=node-content-temp>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaasdsdsdf </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>黃</DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>2 </DIV>
    <DIV class=input-values>2 </DIV>
    <DIV class=input-values>2 </DIV>
    <DIV class=input-values>2 </DIV></DIV></DIV>
    <DIV class=node-contents>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>姓</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>aaaaa2 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>aaaaa2 </DIV></DIV>
    <DIV class=node>
    <DIV class=node-type>input</DIV>
    <DIV class=node-title>名</DIV>
    <DIV class=node-repeatable>true</DIV>
    <DIV class=node-class>table-input</DIV>
    <DIV class=input-default-value>1 </DIV>
    <DIV class=input-required>false</DIV>
    <DIV class=input-type>onebox</DIV>
    <DIV class=input-values>1 </DIV>
    <DIV class=input-values>1 </DIV>
    <DIV class=input-values>1 </DIV></DIV></DIV></DIV></DIV></DIV>
    </div>
    ※你可能注意到了上面的XMLMetadata並不是正規的XML:他缺少了開頭的宣告,而屬性class的值也沒有正確的雙引號。這是使用IE瀏覽器在控制input-type的XMLMetadata時最後必然的結果。所以本XMLMetadata API在設計時已經考慮到這點,這些不正規的Metadata資料會被重新整理成正規的XML格式,最後再進行分析。
  3. 建立XMLMetadata物件,並且給予XMLMetadata的值。
    XMLMetadata xmlObj = new XMLMetadata();
    xmlObj.setXMLdoc(xmlText);
  4. 設定你要在XMLMetadata當中找尋的路徑。請以每個節點的node-title為路徑名稱,中間用「/」來隔開。例如你要找的是在「教師」、「人名」、「姓」當中的資料,那麼請如下設定你的路徑變數:
    String path = "教師/人名/姓";
    注意你的根節點他也需要一個node-title!可是偶爾還是會有忘記設定node-title的時候,當該層沒有node-title之時,可以考慮直接空下來,繼續寫下一層。例如你根節點的node-title原本應該寫「教師」但是卻忘記寫了,那麼你的路徑就要這樣設:
    String path = "/人名/姓";
  5. 接著你就可以用API的方法來取得你的資料了。以下一一介紹各種方法:
    1. 你可以取得查詢的資料,以陣列的字串或是陣列的整數來回傳:
      String[] valueAry = xmlObj.locate(path);
      int[] valueIntAry = xmlObj.locateInt(path);
    2. 你可以取得資料的數量,假如有很多位教師,可以查詢到底有幾筆教師的:
      int count = xmlObj.locateCountNode("教師");
    3. 如果你明確知道要哪一筆,那麼也可以設定偏移值,第一筆則設定0,第二筆則設定1。如果偏移直超過查詢結果的數量,則會回傳「null」:
      int offset = 1;	
      String valueSingle = xmlObj.locateSingle(path, offset);
      int valueIntSingle = xmlObj.locateIntSingle(path, offset);
    4. 你也可以用XPath上來找尋資料:
      String[] valueAry = xmlObj.locateXPath(XPath);

      善用XPath來作更進一步的查詢

      聰明的你也許發現到前面locate所用的路徑查詢語法並不是正確的XPath查詢語法,而是我為簡化查詢XMLMetadata而設計的方法。

      舉例來說,剛剛查詢「教師/人名/姓」的語法,利用XPath查詢XMLMetadata則會非常地複雜。你可以利用public String titlePathToXPath(String titlePath)來看一下XMLMetadata的路徑是怎麼轉換成完整的XPath:

      String path = "教師/人名/姓";
      String XPath = "/div[@class='xml-root']/DIV[@class='node'][DIV[@class='node-title']/text() ='教師']/DIV[@class='node-contents']/DIV[@class='node'][DIV[@class='node- title']/text()='人名']/DIV[@class='node-contents']/DIV[@class='node'][DIV [@class='node-title']/text()='名']/DIV[@class='input-values']/text()";
      out.print(xmlObj.titlePathToXPath(path));  //Show full XPath

      因為時間不多,XMLMetadata的查詢語法並不是很完整。如果你需要更完整的查詢功能,那麼你得需要自行撰寫XPath才行。

      詳細的XPath教學,可以參考w3schools.com的XPath教學


      光是為了寫這份文件就花了我一整天,好累……

      (more...)

      PostgreSQL連線設定與DSpace資料庫備份設定

      布丁布丁吃布丁

      PostgreSQL連線設定與DSpace資料庫備份設定

      安裝DSpace的時候要先把PostgreSQL的連線類型改成不需要密碼的「trust」,但是安裝完之後要改回「md5」(以md5加密的密碼)或「password」(必須詢問密碼),以提高PostgreSQL的安全性。

      但是本機端需要詢問密碼的情況下,會讓crontab自動排程無法自動備份(dump)PostgreSQL的資料庫。因此必須設定該帳號家目錄底下的.pgpass,讓該帳號不需要再次詢問密碼就能夠直接通過PostgreSQL的認證連線,以順利匯出資料庫。

      詳細步驟說明如下:

      安裝DSpace之前需要修改的PostgreSQL設定

      安裝DSpace的過程中,我建議先把PostgreSQL的連線設定(/var/lib/pgsql/data/pg_hba.conf,註1)裡每一個連線類型改成trust,範例如下:

      # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
      
      # "local" is for Unix domain socket connections only
      local   all         all                               trust #ident sameuser
      # IPv4 local connections:
      host    all         all         127.0.0.1/32          trust #ident sameuser
      # IPv6 local connections:
      host    all         all         ::1/128               trust #ident sameuser
      # for DSpace
      host    dspace      dspace      127.0.0.1             trust #255.255.255.
      • 註1^PostgreSQL在CentOS中預設安裝位置在/var/lib/pgsql/當中,故連線的設定檔將位於/var/lib/pgsql/data/pg_hba.conf,如果是手動安裝則可能會在其他地方。

      安裝完DSpace之後的PostgreSQL連線設定

      安裝完成DSpace之後,為了提高PostgreSQL的安全性,設定為本機端連線的時候也需要詢問密碼。

      一樣是修改連線設定檔/var/lib/pgsql/data/pg_hba.conf,將method改成md5(以MD5編碼加密)或password(需要詢問密碼),修改範例如下:

      # TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
      
      # "local" is for Unix domain socket connections only
      local   all         all                               md5 #ident sameuser
      # IPv4 local connections:
      host    all         all         127.0.0.1/32          md5 #ident sameuser
      # IPv6 local connections:
      host    all         all         ::1/128               md5 #ident sameuser
      host    dspace      dspace      127.0.0.1             password #255.255.255.255

      這樣修改主要是方便使用phpPgAdmin——一個用網頁介面管理PostgreSQL的工具(註2 )。

      下圖是phpPgAdmin的介面:

      image 

      如果連線設定依舊是trust的情況下,任何使用者只要連到該系統的phpPgAdmin工具、知道該帳號名稱,則使用任何密碼都可以登入PostgreSQL資料庫中。

      使用phpPgAdmin時,除了需要修改PostgreSQL的連線為「md5」或「password」之外,最好如phpMyAdmin一樣地還加上Apache利用.htaccess來實作的認證機制(註3)。

      PostgreSQL自動備份策略

      如果PostgreSQL的連線設定需要使用密碼,那麼在利用crontab排程自動執行備份指令時,也會遇到需要輸入密碼而無法自動執行的情況。

      PostgreSQL在8版之後(好像是,至少目前我們使用的都是8版)可以使用「.pgpass」來為使用者設定自動認證

      以下介紹詳細步驟

      1. 假如我們要連線的資料庫位置為「localhost」(表示本機端)、連接埠為「5432」(PostgreSQL預設連接埠)、資料庫名稱為「database」、資料庫帳號為「username」、密碼為「password」。注意,username不一定要跟你執行crontab的帳號相同。
      2. 切換到執行crontab的LINUX實體帳號,假如是「dspace」,則利用su指令切換:
      3. [root@dspace /]# su dspace 
      4. 在該帳號的家目錄新增檔案「.pgpass」
      5. [dspace@dspace /]# vim ~/.pgpass
      6. 利用vim編輯器輸入以下資料:
      7. localhost:5432:database:username:password 
        完成之後儲存離開。
      8. 修改.pgpass的權限為600
      9. [dspace@dspace /]# chmod 600 ~/.pgpass
      10. 測試看看,利用pg_dump匯出資料庫到「/var/lib/pgsql/backups/bkup.sql」
      11. [dspace@dspace /]# pg_dump -U username database > /var/lib/pgsql/backups/bkup.sql 
      12. 如果「/var/lib/pgsql/backups/bkup.sql」有檔案,並且內文為正確的sql檔,則表示認證成功。反之,如果系統要求你輸入密碼,那可能是哪個步驟做錯了,請回頭一一確認。

      當確認可以自動通過認證,以指令執行PostgreSQL匯出的之後,就可以把這些指令加入crontab排程中囉。

      資料庫一定要天天備份,祝大家伺服器都能運作順利


      延伸閱讀