:::

DSpace擴增MediaFilter格式(安裝篇)

布丁布丁吃布丁

DSpace擴增MediaFilter格式(安裝篇)

DSpace擴增MediaFilter的目錄:

本篇介紹DSpace擴增MediaFilter格式的安裝篇,安裝完之後,還要做一次[dspace]/bin/filter-media才能有展示篇的功能。

需求環境

  • DSpace 1.5.0 release (1.4.2或之後的版本似乎也可以)
  • 作業系統:CentOS 5 Final
  • 必須要具備yum的功能
  • 必須安裝OpenOffice 2.0以上

用yum安裝轉檔軟體

如果你不是root的話,先切換到root權限

[dspace@dspace ~]# su root

修改/etc/yum.repos.d/CentOS-Base.repo

[root@dspace ~]# vim /etc/yum.repos.d/CentOS-Base.repo

你可以上鳥哥來看一下vim文字編輯器要怎麼使用。

在該檔案最後加入以下設定:

[dag]
name=Dag RPM Repository for Red Hat Enterprise Linux
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1

把金鑰加入RPM的資料庫

[root@dspace ~]# rpm --import http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt


如果你沒辦法下載RPM-GPG-KEY.dag.txt的話,可以下載我的備份檔案。(雖然沒什麼意義,他的伺服器掛點的話,之後yum也沒辦法安裝所需要的檔案啊。)

執行yum的安裝指令

[root@dspace ~]# yum -y install ffmpeg mencoder imagemagick python python-imaging

如果安裝都順利進行的話,那麼這個步驟就完成囉。

配置ZoomifyImage

ZoomifyImage的計畫網站中去下載最新版本,目前是1.4版,也可以下載我另外備份的檔案(24.06MB,有點大喔)。解壓縮之後,擺到/opt/當中 。

在Linux指令列之下,你可以用wget下載檔案,然後利用tar解壓縮,將之移至/opt/當中。指令如下:

[root@dspace ~]# wget http://nchc.dl.sourceforge.net/sourceforge/zoomifyimage/ZoomifyImage1_4.tar.gz
[root@dspace ~]# tar -zxvf ZoomifyImage1_4.tar.gz
[root@dspace ~]# mv ZoomifyImage /opt/

ZoomifyImage必須搭配Python才能執行,所以要記得一定要在之前yum安裝步驟中安裝Python喔。

配置JODconverter跟OpenOffice

請下載JODconverter的檔案,取出lib資料夾之中的所有jar檔(除了commons-cli-1.2.jar跟commons-io-1.4.jar之外),放到[dspace]/lib跟Java安裝目錄的擴增目錄(如果你跟我一樣安裝的是JDK 1.6.0.06,那麼路徑就是/usr/java/jdk1.6.0_06/jre/lib/ext/)之中。或是下載我另外備份的檔案:jodconverter-2.2.2-lib.zip

然後伺服器端必需要開啟OpenOffice的服務,用SSH開啟的話不知為何會失敗,請到本機端執行以下指令:

[root@dspace ~]# /usr/lib/openoffice.org2.0/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard

出現以下訊息的時候,表示正常開啟:

image

同樣的,也把這段指令加入開機執行的指令當中吧。

修改/etc/rc.local

[root@dspace ~]# vim /etc/rc.local

請把這段指令「/usr/lib/openoffice.org2.0/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard」加到最後去,這樣就大功告成了。

DSpace註冊Bitstream Format

image

開啟DSpace的管理介面,到「Bitstream Format Regisry(附加檔案(二進位檔案)格式登記)」當中,新增以下幾種檔案格式。支援等級皆選擇「已知」、取消「內部」的打勾。

MIME形式 名稱 完整描述 延伸檔名
video/x-msvideo AVI Audio Video Interleave avi
video/x-flv FLV Flash Video flv
video/x-ms-wmv WMV Windows Media Video wmv
application/vnd.rn-realmedia RM Real Media rm
application/vnd.rn-realmedia-vbr RMVB RealVideo Variable Bit Rate File rmvb
audio/3gpp audio/3gpp 3GPP Multimedia File 3gp
video/3gpp video/3gpp 3GPP Multimedia File 3gp
video/mp4v-es MP4 MPEG-4 Video File mp4
application/zip ZIP ZIP zip
audio/mpeg MP3 MPEG-1 Audio Layer 3 mp3
audio/mid MID Musical Instrument Digital Interface mid
audio/x-aac AAC Advanced Audio Coding aac
audio/flac FLAC Free Lossless Audio Codec flac
audio/ogg OGG Ogg ogg
audio/x-ms-wma WMA Windows Media Audio wma
audio/mp4a-latm M4A MPEG-4 Part 14 m4a
text/tab-separated-values TSV Tab-separated values tsv
text/csv CSV Comma-separated values csv

大部分的檔案格式在DSpace 1.5.0當中已經登錄了,特別是文件檔的類型,包括Microsoft Office跟OpenOffice系列,所以在此不特別敘述。目前我測試機上使用的Bitstream Format Registry資料表可以參考這個檔案,裡面有詳盡的設定,如果之後你發現有些格式沒有辦法正確辨識的話,再來比較這個檔案看看缺了哪些格式。

DSpace增加MediaFilter相關檔案

請將以下檔案下載,新增到指定的位置:

  • mediafilter-dspace-api.zip
    [dspace-source]/dspace-api/src/main/java/org/dspace/app/mediafilter/
  • BitstreamDisplay.zip
    [dspace-source]/dspace-jspui/dspace-jspui-api/src/main?java/org/dspace/app/webui/util/
  • RetrieveZIPServlet.zip
    [dspace-source]/dspace-jspui/dspace-jspui-api/src/main?java/org/dspace/app/webui/util/
  • extension-jspui.zip
    [dspace-source]/dspace-jspui/dspace-jspui-webapp/src/main/webapp/extension/
    ※預設是沒有extension這個資料夾的,請自行建立。

如果你的DSpace是預設的狀態,並且安裝過我之前介紹的XMLMetadata,那麼可以採用我的檔案:

如果你這些檔案已經做過更動,那麼取代的話會造成你設計的功能消失。因此接下來我介紹怎麼調整這些檔案。

DSpace調整display-item.jsp

位置在[dspace-source]/dspace-jspui/dspace-jspui-webapp/src/main/webapp/display-item.jsp

請在「<dspace:item-preview item="<%= item %>" />」程式碼之前,加入以下JavaScript跟CSS的引用語法,以便帶出jQuery UI等效果:

<script type="text/javascript" src="<%= request.getContextPath() %>/extension/jquery.js"></script> 
<script type="text/javascript" src="<%= request.getContextPath() %>/extension/bitstream-display/thickbox.js"></script> <script type="text/javascript" src="<%= request.getContextPath() %>/extension/bitstream-display/jquery-ui/js/jquery-ui-1.7.1.custom.min.js"></script> <script type="text/javascript" src="<%= request.getContextPath() %>/extension/bitstream-display/doDialog.js"></script> <link rel="stylesheet" href="<%= request.getContextPath() %>/extension/bitstream-display/thickbox.css" type="text/css" /> <link rel="stylesheet" href="<%= request.getContextPath() %>/extension/bitstream-display/jquery-ui/css/smoothness/jquery-ui-1.7.1.custom.css" type="text/css" />

 

DSpace調整web.xml

位置在[dspace-source]/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml

加入以下設定,讓DSpace擁有直接讀取zip檔案的功能:

  <servlet>
    <servlet-name>retrieve-zip</servlet-name>
    <servlet-class>org.dspace.app.webui.servlet.RetrieveZIPServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>retrieve-zip</servlet-name>
    <url-pattern>/retrieve-zip/*</url-pattern>
  </servlet-mapping>

 

DSpace調整ItemTag.java

位置在[dspace-source]/dspace-jspui/dspace-jspui-api/src/main/java/org/dspace/app/webui/util/ItemTag.java

主要是使用BitstreamDisplay.java來分析、製作要顯示的連結。BitstreamDisplay.java詳細的用法我會另開一篇教,現在先簡介一下加入BitstreamDisplay功能的作法。

先在開頭引用BitstreamDisplay

import org.dspace.app.webui.util.BitstreamDisplay;

然後找到私有方法listBitstreams(),修改顯示連結的部份。請找到以下部份的程式碼:

                                // Work out what the bitstream link should be
                                // (persistent
                                // ID if item has Handle)
                                String bsLink = "<a target=\"_blank\" href=\""
                                        + request.getContextPath();

                                if ((handle != null)
                                        && (bitstreams[k].getSequenceID() > 0))
                                {
                                    bsLink = bsLink + "/bitstream/"
                                            + item.getHandle() + "/"
                                            + bitstreams[k].getSequenceID() + "/";
                                }
                                else
                                {
                                    bsLink = bsLink + "/retrieve/"
                                            + bitstreams[k].getID() + "/";
                                }

                                bsLink = bsLink
                                        + UIUtil.encodeBitstreamName(bitstreams[k]
                                            .getName(),
                                            Constants.DEFAULT_ENCODING) + "\">";

            					out
                                    .print("<tr><td headers=\"t1\" class=\"standard\">");
                                out.print(bsLink);
            					out.print(bitstreams[k].getName());
                                out.print("</a>");
                                

            					if (multiFile)
            					{
            						out
                                        .print("</td><td headers=\"t2\" class=\"standard\">");

            						String desc = bitstreams[k].getDescription();
            						out.print((desc != null) ? desc : "");
            					}

            					out
                                    .print("</td><td headers=\"t3\" class=\"standard\">");
                                out.print(UIUtil.formatFileSize(bitstreams[k].getSize()));
            					out
                                .print("</td><td headers=\"t4\" class=\"standard\">");
            					out.print(bitstreams[k].getFormatDescription());
            					out
                                    .print("</td><td class=\"standard\" align=\"center\">");

            					// is there a thumbnail bundle?
            					if ((thumbs.length > 0) && showThumbs)
            					{
            						String tName = bitstreams[k].getName() + ".jpg";
                                    String tAltText = LocaleSupport.getLocalizedMessage(pageContext, "org.dspace.app.webui.jsptag.ItemTag.thumbnail");
            						Bitstream tb = thumbs[0]
                                        .	getBitstreamByName(tName);

            						if (tb != null)
            						{
            							String myPath = request.getContextPath()
                                            	+ "/retrieve/"
                                            	+ tb.getID()
                                            	+ "/"
                                            	+ UIUtil.encodeBitstreamName(tb
                                            			.getName(),
                                            			Constants.DEFAULT_ENCODING);

            							out.print(bsLink);
            							out.print("<img src=\"" + myPath + "\" ");
            							out.print("alt=\"" + tAltText
            									+ "\" /></a><br />");
            						}
            					}

            					out
                                    .print(bsLink
                                            + LocaleSupport
                                                    .getLocalizedMessage(
                                                            pageContext,
                                                            "org.dspace.app.webui.jsptag.ItemTag.view")
                                            + "</a></td></tr>");

然後修改成以下程式碼,注意標註For Bitstream Display的部份:

                                // Work out what the bitstream link should be
                                // (persistent
                                // ID if item has Handle)
                                String bsLink = "<a target=\"_blank\" href=\""
                                        + request.getContextPath();
                                //For Bitstream Display
								String bdLink = request.getContextPath();
								
                                if ((handle != null)
                                        && (bitstreams[k].getSequenceID() > 0))
                                {
                                    bsLink = bsLink + "/bitstream/"
                                            + item.getHandle() + "/"
                                            + bitstreams[k].getSequenceID() + "/";
                                    //For Bitstream Display
                                    bdLink = bdLink + "/bitstream/"
                                            + item.getHandle() + "/"
                                            + bitstreams[k].getSequenceID() + "/";
                                }
                                else
                                {
                                    bsLink = bsLink + "/retrieve/"
                                            + bitstreams[k].getID() + "/";
                                    //For Bitstream Display
                                    bdLink = bdLink + "/retrieve/"
                                            + bitstreams[k].getID() + "/";
                                }

                                bsLink = bsLink
                                        + UIUtil.encodeBitstreamName(bitstreams[k]
                                            .getName(),
                                            Constants.DEFAULT_ENCODING) + "\">";
                                //For Bitstream Display
								bdLink = bdLink + UIUtil.encodeBitstreamName(bitstreams[k]
                                            .getName(),
                                            Constants.DEFAULT_ENCODING);
            					out.print("<tr><td headers=\"t1\" class=\"standard\">");
                                //out.print(bsLink);
            					//out.print(bitstreams[k].getName());
                                //out.print("</a>");
                                
                                //For Bitstream Display
                                BitstreamDisplay db = new BitstreamDisplay(item, bdLink);
                                out.print(db.doDialog(bitstreams[k].getName()));

            					if (multiFile)
            					{
            						out
                                        .print("</td><td headers=\"t2\" class=\"standard\">");

            						String desc = bitstreams[k].getDescription();
            						out.print((desc != null) ? desc : "");
            					}

            					out
                                    .print("</td><td headers=\"t3\" class=\"standard\">");
                                out.print(UIUtil.formatFileSize(bitstreams[k].getSize()));
            					out
                                .print("</td><td headers=\"t4\" class=\"standard\">");
            					out.print(bitstreams[k].getFormatDescription());
            					out.print("</td><td class=\"standard\" align=\"center\">");

            					// is there a thumbnail bundle?
            					if ((thumbs.length > 0) && showThumbs)
            					{
            						String tName = bitstreams[k].getName() + ".jpg";
                                    String tAltText = LocaleSupport.getLocalizedMessage(pageContext, "org.dspace.app.webui.jsptag.ItemTag.thumbnail");
            						Bitstream tb = thumbs[0]
                                        .	getBitstreamByName(tName);

            						if (tb != null)
            						{
            							String myPath = request.getContextPath()
                                            	+ "/retrieve/"
                                            	+ tb.getID()
                                            	+ "/"
                                            	+ UIUtil.encodeBitstreamName(tb
                                            			.getName(),
                                            			Constants.DEFAULT_ENCODING);

            							//out.print(bsLink);
            							//out.print("<img src=\"" + myPath + "\" ");
            							//out.print("alt=\"" + tAltText
            							//		+ "\" /></a>");
            							
            							//For Bitstream Display
            							String thumbnailImg = "<img src=\"" + myPath + "\" alt=\"" + tAltText
            									+ "\" />";
            							out.print(db.doDialog(thumbnailImg));
            							out.print("<br />");
            						}
            					}

            					//out.print(bsLink
            					//	+ LocaleSupport.getLocalizedMessage(pageContext,"org.dspace.app.webui.jsptag.ItemTag.view")
            					//	+ "</a>");
                                
                                //For Bitstream Display
                                out.print(db.doDialog(LocaleSupport.getLocalizedMessage( pageContext, "org.dspace.app.webui.jsptag.ItemTag.view")));
                                out.print("</td></tr>");

 

DSpace調整style.css.jsp

位置在[dspace-source]/dspace-jspui/dspace-jspui-webapp/src/main/webapp/style.css.jsp

請新增一段程式碼,以讓Bitstream的列表置中:

table.miscTable, table.attentionTable {
	margin: auto;
}

效果圖片如下:

image

DSpace修改dspace.cfg設定

位置在[dspace]/config/dspace.cfg

最後,要加入設定,Media Filter才能生效。預設的Media Filter部份設定如下:

#### Media Filter / Format Filter plugins (through PluginManager) ####
# Media/Format Filters help to full-text index content or
# perform automated format conversions

#Names of the enabled MediaFilter or FormatFilter plugins
filter.plugins = PDF Text Extractor, HTML Text Extractor, \
				 Word Text Extractor, JPEG Thumbnail
# [To enable Branded Preview]: remove last line above, and uncomment 2 lines below
#   			 Word Text Extractor, JPEG Thumbnail, \
#   			 Branded Preview JPEG

#Assign 'human-understandable' names to each filter
plugin.named.org.dspace.app.mediafilter.FormatFilter = \
  org.dspace.app.mediafilter.PDFFilter = PDF Text Extractor, \
  org.dspace.app.mediafilter.HTMLFilter = HTML Text Extractor, \
  org.dspace.app.mediafilter.WordFilter = Word Text Extractor, \
  org.dspace.app.mediafilter.JPEGFilter = JPEG Thumbnail, \
  org.dspace.app.mediafilter.BrandedPreviewJPEGFilter = Branded Preview JPEG

#Configure each filter's input format(s)
filter.org.dspace.app.mediafilter.PDFFilter.inputFormats = Adobe PDF
filter.org.dspace.app.mediafilter.HTMLFilter.inputFormats = HTML, Text
filter.org.dspace.app.mediafilter.WordFilter.inputFormats = Microsoft Word
filter.org.dspace.app.mediafilter.JPEGFilter.inputFormats = BMP, GIF, JPEG, image/png
filter.org.dspace.app.mediafilter.BrandedPreviewJPEGFilter.inputFormats = BMP, GIF, JPEG, image/png

請修改成以下設定:

#### Media Filter / Format Filter plugins (through PluginManager) ####
# Media/Format Filters help to full-text index content or
# perform automated format conversions

#Names of the enabled MediaFilter or FormatFilter plugins
filter.plugins = PDF Text Extractor, HTML Text Extractor, \
				 Word Text Extractor, JPEG Thumbnail, \
FFmpeg Image Capturer, MEncoder Image Capturer, \
FFmpeg Video Converter, MEncoder Video Converter, \
Zoomify Image Converter, FFmpeg Audio Converter, \
ImageMagick Converter, OOg Text Converter, OOg PPT Converter, OOg PDF Converter

# [To enable Branded Preview]: remove last line above, and uncomment 2 lines below
#   			 Word Text Extractor, JPEG Thumbnail, \
#   			 Branded Preview JPEG

#Assign 'human-understandable' names to each filter
plugin.named.org.dspace.app.mediafilter.FormatFilter = \
  org.dspace.app.mediafilter.FFmpegVideoFilter = FFmpeg Video Converter, \
  org.dspace.app.mediafilter.FFmpegImgFilter = FFmpeg Image Capturer, \
  org.dspace.app.mediafilter.MEncoderFilter = MEncoder Video Converter, \
  org.dspace.app.mediafilter.MEncImgFilter = MEncoder Image Capturer, \
  org.dspace.app.mediafilter.ZoomifyFilter = Zoomify Image Converter, \
  org.dspace.app.mediafilter.FFmpegAudioFilter = FFmpeg Audio Converter, \
  org.dspace.app.mediafilter.PDFFilter = PDF Text Extractor, \
  org.dspace.app.mediafilter.HTMLFilter = HTML Text Extractor, \
  org.dspace.app.mediafilter.WordFilter = Word Text Extractor, \
  org.dspace.app.mediafilter.JPEGFilter = JPEG Thumbnail, \
  org.dspace.app.mediafilter.BrandedPreviewJPEGFilter = Branded Preview JPEG, \
  org.dspace.app.mediafilter.ImageMagickFilter = ImageMagick Converter, \
  org.dspace.app.mediafilter.OOgPDFFilter = OOg PDF Converter, \
  org.dspace.app.mediafilter.OOgTextFilter = OOg Text Converter, \
  org.dspace.app.mediafilter.OOgPPTFilter = OOg PPT Converter

#Configure each filter's input format(s)
filter.org.dspace.app.mediafilter.PDFFilter.inputFormats = Adobe PDF
filter.org.dspace.app.mediafilter.HTMLFilter.inputFormats = HTML, Text
filter.org.dspace.app.mediafilter.WordFilter.inputFormats = Microsoft Word
filter.org.dspace.app.mediafilter.JPEGFilter.inputFormats = BMP, GIF, JPEG, image/png
filter.org.dspace.app.mediafilter.BrandedPreviewJPEGFilter.inputFormats = BMP, GIF, JPEG, image/png
filter.org.dspace.app.mediafilter.FFmpegVideoFilter.inputFormats = MP4, MPEG, AVI, FLV, WMV
filter.org.dspace.app.mediafilter.FFmpegImgFilter.inputFormats = MP4, MPEG, AVI, FLV, WMV
filter.org.dspace.app.mediafilter.MEncoderFilter.inputFormats = RM, RMVB, video/3gpp, Video Quicktime
filter.org.dspace.app.mediafilter.MEncImgFilter.inputFormats = RM, RMVB, video/3gpp, Video Quicktime
filter.org.dspace.app.mediafilter.ZoomifyFilter.inputFormats = BMP, GIF, JPEG, image/png, TIFF
filter.org.dspace.app.mediafilter.FFmpegAudioFilter.inputFormats = MP3, AAC, FLAC, OGG, WMA, WAV, M4A
filter.org.dspace.app.mediafilter.ImageMagickFilter.inputFormats = TIFF
filter.org.dspace.app.mediafilter.OOgPDFFilter.inputFormats = Microsoft Powerpoint, OpenDocument Presentation, RTF, OpenDocument Spreadsheet, Calc 6.0 spreadsheets, CSV, TSV, Impress 6.0 presentations, Microsoft Word, OpenDocument Text, Writer 6.0 documents
filter.org.dspace.app.mediafilter.OOgTextFilter.inputFormats = Microsoft Powerpoint, OpenDocument Presentation, RTF, OpenDocument Spreadsheet, Calc 6.0 spreadsheets, CSV, TSV, Impress 6.0 presentations, OpenDocument Text, Writer 6.0 documents
filter.org.dspace.app.mediafilter.OOgPPTFilter.inputFormats = Microsoft Powerpoint, Impress 6.0 presentations, OpenDocument Presentation

# Where is Temp Directory?
filter.tempfile.config = /tmp/

# How to excute FFmpeg?
filter.exec.ffmpeg = ffmpeg
# FFmpeg Config
filter.FFmpegVideoFilter.config = -ar 22050 -ab 56 -f flv -y -s 320x240
filter.FFmpegImgFilter.config = -y -f image2 -ss 8 -t 0.001 -s 80x60
filter.FFmpegAudioFilter.config = -ar 22050 -y

# How to excute MEncoder?
filter.exec.mencoder = mencoder
# MEncoder Config
filter.MEncoderFilter.config = -vf scale=320:240 -ffourcc FLV1 -of lavf -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -ovc lavc -lavcopts vcodec=flv:vbitrate=200 -srate 22050 -oac lavc -lavcopts acodec=mp3:abitrate=56

# How to excute Python?
filter.exec.python = python
# Where is ZoomifyFileProcessor.py ?
filter.exec.zoomifyImage = /opt/ZoomifyImage/ZoomifyFileProcessor.py
# How to excute ImageMagick?
filter.exec.imagemagick = convert

簡單說明一下各設定檔的用處:

  • filter.plugins:要採用哪些filter,輸入他們的名稱。
  • plugin.named.org.dspace.app.mediafilter.FormatFilter:設定各個filter的名稱。
  • filter.org.dspace.app.mediafilter.*******.inputFormats:設定該filter處理的檔案類型,名稱是Bitstream Format當中的「名稱」,所以上面才要先設定Bitstream Format。
  • 以下都是各個filter的設定參數,可以做進一步的微調。如果你要在Windows環境底下執行的話,這些參數可能需要重新調整。

DSpace重新編譯

步驟如下,注意[tomcat]、[dspace-source]跟[dspace]要替換成你Tomcat的位置、原始碼跟安裝目的地的位置:

  1. cd [dspace-source]/dspace/
  2. mvn package
  3. cd [dspace-source]/dspace/target/dspace-1.5.0-build.dir/
  4. ant -Dconfig=[dspace]/config/dspace.cfg update
  5. \cp -rf [dspace]/webapps/* [tomcat]/webapps/
  6. [tomcat]/bin/shutdown.sh
  7. [tomcat]/bin/startup.sh

DSpace執行filter-media

請執行以下指令:

[root@dspace ~]# [dspace]/bin/filter-media -v

加入-v指令,程式就會顯示他處理的詳細過程,也可以看到剛剛新增的MediaFilter有沒有正確地被採用,如下圖:

image

如果有完成的話,就可以找一個有Bitstream的Item頁面看看這些功能有沒有出來囉。

image


因為MediaFilter結合了許多工具,儘管我已經盡量把安裝動作簡化了,但還是很繁雜,如果哪裡有出錯,請務必通知我。下一篇則是給進階者的BitstreamDisplay使用篇,讓你更進一步地去調整display-item或其他的版面。<-- Post Catalog -->

(more...)

DSpace擴增MediaFilter格式(展示篇)

布丁布丁吃布丁

DSpace擴增MediaFilter格式(展示篇)

DSpace擴增MediaFilter的目錄:

image

DSpace具備MediaFilter(多媒體過濾器,不過以下我還是會用MediaFilter來稱呼)的功能,負責處理DSpace中上傳到Item裡面的Bitstream,每一種Filter的功用各不相同,可以在[dspace]/config/dspace.cfg裡面調整。預設的DSpace提供了以下幾種功能的Filter:

  • JPEG、GIF、PNG跟BMP圖片製作索引縮圖(thumbnail)跟商標縮圖(brand)

    索引縮圖(thumbnail):預設為寬80px、80px以下大小。

    商標縮圖(brand):預設是寬600px、高600px以下大小。
  • HTML、PDF跟Word檔案內的文字抽取出來,以便搜尋引擎製作索引。
    image
    抽取出來的文字會存成txt檔案,但是有時候會抽出亂碼。

預設的功能僅有如此,但這對各種數位物件的應用來說已經不敷使用,因此我又撰寫了幾個MediaFilter來用,並寫了展示的功能,可以搭配display-item時使用。不過大部分功能都只針對Linux(特別是CentOS發行版)環境下使用,而且都是使用開放原始碼自由軟體。

這一篇主要是介紹我到底做出了什麼MediaFilter、怎麼展示,之後再介紹怎麼安裝。


內嵌視窗介面

image 

當安裝完所有功能之後,下面的Bitstream列表基本上跟原始的一樣,但是點下去開啟之後,就會打開jQuery UI的Dialog視窗,取代到原本就讓使用者直接下載的不方便。視窗畫面如下:

image

jQuery UI的Dialog提供了相當具有彈性的操作介面,搭配上面圖片的數字來看有四大功能:(1) 自定義的標題、滑鼠按著標題列則可拖曳視窗;(2) 關閉按鈕,可以隱藏視窗;(3) 下載按鈕,可以下載原始的Bitstream,當然,也可以設定為不開放下載按鈕;(4) 視窗大小調整。此外,使用者可以開啟很多個Dialog,然後隨心所欲地拖曳到使用者想要的地方,或是在不需要的時候關掉指定的Dialog。

必須要注意的是,如果沒有是先做過[dspace]/bin/filter-media的動作的話,以下支援的功能有些就會失效,而仍會連結到原始的Bitstream。

圖片支援

image

支援格式:JPEG、GIF、PNG、BMP、TIFF

播放器:Zoomify Express

搭配新版本的Zoomify播放器,提供大圖瀏覽的功能、無差段縮放(是以前在百年圖書館做Zoomify的進化版喔!)。此外,TIFF也支援索引縮圖的功能了!無損壓縮的TIFF檔案是許多數位典藏採用的共通格式,相信這個MediaFilter能夠接納TIFF,一定可以造福許多數位典藏網站。

影片支援

image 

支援格式:MPEG、AVI、FLV、WMV、MP4、RM、RMVB、3GP、MOV

播放器:FLV Player

就跟大部分影音分享網站(如YouTube)一樣,MediaFilter會把影片檔轉換成可以直接線上播放的FLV檔案。

此外,MediaFilter也會擷取影片第8秒的畫面作為縮圖。

聲音支援

image

支援格式:MP3、WMA、WAV、AAC、FLAC、OGG、M4V

播放器:XSPF Web Music Player

以上格式都會轉換成MP3檔案,再搭配播放器就能夠在網頁中直接播放,而不需要讓使用者再去開啟其他軟體才能聽到音樂。

文件支援

image

支援格式:Offcie系列的doc、ppt、xls;OpenOffice系列的odt、odp、ods、sxi、sxw、sxc;通用格式的rtf、csv、tsv;原本DSpace就支援的txt、html、pdf

播放器:使用使用者電腦內部的Adobe PDF Reader之類的軟體,我推薦採用XChange Viewer

以上格式都能夠轉換成PDF以供線上播放,並抽取出文字檔作為全文檢索的對象。此外,Power Pointer投影片系列,包括ppt、odp、sxi還可以擷取第一張投影片作為縮圖。

我有想過是否要轉換成圖片檔案來作為線上播放,但是考量到瀏覽介面需要另外設計、也不方便操作,故還是選擇採用最通用的PDF Reader。缺點是目前沒有加密PDF的功能,PDFBox不知為何不能生效。

多檔案網頁支援

image

你可以把檔案壓縮成zip檔案,只要包含index.html、index.htm、default.html、default.htm,系統就會自動把他當成網頁開啟。注意到上面圖片中的範例,這是一個包含多個檔案的jQuery UI範例檔,裡面包含了網頁、圖片、JavaScript、CSS檔案,現在只要壓縮成zip之後上傳到DSpace,就能夠直接在DSpace上直接開啟了!


好,以上是給使用者看得部份。接下來後面幾篇,就是給系統建置者看得安裝跟使用的部份囉!

(more...)

延畢確定

布丁布丁吃布丁

延畢確定

 

剛入學的時候,迎新茶會上老師們聲稱我們最快可以兩年畢業,這是政大圖檔所的特色。

在跟陳志銘老師meeting的時候,也常常聽到老師勉勵著學生兩年畢業。

不只是陳老師,我也不時聽到其他老師極力地推著學生完成論文、無不希望學生早點畢業的消息。

學生們也都用兩年畢業來勉勵自己。在碩一下決定題目,花半年完成計劃書,然後再用碩二下半年來把論文完成,順利畢業,找到工作。

高等教育評鑑裡面,本所的就業率非常地高,而且大部分畢業的學長姊找到的工作都是與圖書館、檔案館相關 (並不是去賣雞排,雖然這比較賺)。


現在是碩二下,我進來圖檔所已經兩年。

我的同學當中,不乏有已經被圖書館挑上,預備一畢業就進去辦公室坐的預備館員;也有翻著圖書館徵人公告,問我這邊到底好不好的人。

儘管同學們一邊抱怨著論文難寫、指導教授囉唆、問卷收不回來,但還是確實地朝著完成畢業論文的方向前進。

「我們一定要兩年畢業喔。」這句打氣的話,不知道在同學之間已經說過多少次。

一開始,我也相信這是可能的,因為我們都是同學,我們都在百年樓上課,我們都是在優秀的老師指導,我們都一樣努力,所以理所當然的,我們會一起畢業。

逐漸地,我終於發現,原來看似一樣的我們,走的是截然不同的道路。

你們為了「畢業」而努力。

我則是背對與「畢業」南轅北轍,日夜不息地狂奔中。

同學們會順利畢業,而我註定延畢。(除了跑去美國留學的跟晚了半年進來的那幾位,我們就一起留下來吧XD)


當我發現的時候,那些諷刺研究生生活的種種笑話,我已經視之習以為常。

要找新穎議題的資料,首先會想到要找電子資料庫當中的英文paper,而且習以為常地閱讀英文paper。對了,我也是計畫書口試的時候才被口委老師點出,原來我的中文參考文獻居然這麼少。

幫老師做事理所當然,因為老師很辛苦、事務繁雜,想像一下如果你自己是老師的話,就能夠稍微體會到老師到底有多累了。所以在自己的能力範圍內,盡可能地幫老師的忙吧。

寫論文、做工作就要專心地做。能夠心無旁鶩地整天待在實驗室進行研究,然後抱著期待的心情等待成果「蹦」出來的那一瞬間,不是很令人興奮嗎?電影、電動?有比我花了好幾天努力建置的成果還要有趣嗎?

對我來說,研究所中最重要的工作不是畢業,是論文。論文是自己第一本著作、意義非凡,而且可以不用理會商業價值、可以做出基於前人研究的更進一步發展,這是證明自己所學所得的具體呈現,「用自己的雙手去發掘這世界裡面你尚未發現的真相」的開始,怎能不叫人興奮、不想要好好地完成論文呢?

也因此,自己才深深地感覺到知識的無止盡。短短的研究所兩年的時間,用半年的時間就要把論文做完,我怎樣都覺得好像哪裡不夠。所以想要攻讀博士班,繼續這種頹廢生活,倒也是不錯的人生選項之一。

雖然同學一窩風在找工作、找打工,但我仍抱持著「趁老爸老媽還可以養我的時候趕快享受學生生活」的頹廢想法,利用所上跟老師提供的資源,日以繼夜地學習、學習、再學習。


很奇怪嗎?很像違心之論嗎?我倒是覺得還蠻正常的,也不過就是日常生活的大小事而已。

只是有時候會覺得有點悶。

悶在當同學興高采烈地嚷嚷著「畢業才是真的」、其他人一起附和的時候,我這個覺得那其實還好、重要的是其他的事情。

悶在老是聽到「你好辛苦」、「你好厲害」、「我都做不來」但卻沒有手來幫我一個忙之後,聽到他們有說有聊地討論晚餐吃完要去看哪部電影,而自己像事傻瓜一樣留著繼續做別人不願意做的工作。

悶在老師堅持自己上課要弄出來的系統、研討會要佈置的完善、計畫要做得出成果,卻不會想到學生為了老師其實沒什麼時間寫論文,然後還要承受「什麼?看你不是每天都在所上晃來晃去很閒嗎?怎麼沒時間寫論文?還會延畢?」的罪名。

悶在人情債進化成人情討債公司的時候,來討債的人只會給我無奈的表情,告訴我他也沒辦法。

悶在急著想要寫論文,可是卻有一堆雜事纏身。(教授,我好想寫論文啊!)


後來我終於發現了,其實這麼悶,也只是我自己的問題。

是的,我何必去煩惱自己怎麼過得跟其他同學不太一樣,因為我們本來就走在不同的道路上,擁有不同的價值觀、做著不同的事情。這社會有著多元的價值觀,除了尊重對方的想法,也不必強求自己一定要這樣做。

我要把論文寫好,完整地建構系統、費心地安排實驗、仔細地收集數據、謹慎地寫下結論!

在這之前,我要把教育部計畫做好,讓研究已久的DSpace系統作到一種能讓自己抬頭挺胸說:「這是我的心血成果」的程度!

在這之前,我要把我不會的東西都學好,善用大學豐沛的藏書、實驗室購書的經費、還有優秀的老師們,好好地把不懂地方的搞懂!

在這之前,我會延畢。

因為我喜歡這種生活,所以我得要抬頭挺胸地說出這種頹廢生活的好處,這樣就行了!

2009-05-16-701

p.s. 對了,在問我為什麼圖資人要看「物件導向程式設計」、「UML」或是「極致軟體製程」之前,可以先問你一下,你覺得學生的工作是來學東西的呢?還是來跟別人說「這個我不會」的呢?

(more...)

DSpace改用Proxool增加連線效率

布丁布丁吃布丁

DSpace改用Proxool增加連線效率

image

Proxool 是一個開放原始碼的連線池(Connection Pool)管理套件,引用一下「Proxool - 快速入門」來介紹一下什麼連線池:

在資料庫應用程式中,資料庫連線的取得是一個耗費時間的動作,為了避免花費時間在連線的取得與關閉上,我們會將連線資源放置在一個池中,有需要連線時就從池中取得,不需要連線時就將之放回池中,以求重複利用連線,連線池也擔任連線數量、連線時間的控制等等動作。

連線池的設置可以讓資料庫連線比較不容易當機(當然,你要惡意地一直對伺服器發出請求,伺服器還是會當的)。DSpace的資料庫連也有設置連線池,但是連線數量一多的時候,系統卻不會踢掉已經發呆太久的連線,而導致發生「PSQLException: This statement has been closed (這個statement已經被關閉)」的例外錯誤。

Proxool在JDBC的連線池當中似乎是頗富盛名的套件,我們試著以Proxool取代DSpace預設的連線池,也大幅度地改善了DSpace的資料庫連線容易當機的問題!此外我順便撰寫了一個可直接使用SQL語法查詢的類別,可直接輸入SQL語法而回傳ResultSet物件,而不需要另外去學習DSpace的DatabaseManager怎麼使用。

以下教學都是基於我之前撰寫的DSpace 1.5.1安裝法,如果你也是照著這方法安裝,那麼以下的路徑設定幾乎不需要更動。如果不是的話,那麼請你務必注意到路徑的地方必需要改成你的環境!

DSpace的路徑我們通常會用[dspace-source]表示DSpace原始的程式檔,在本文中則是「/opt/dspace-1.5.1-src-release」,而[dspace]則是表示DSpace的安裝檔,本文中是「/dspace」,請依照你實際的情況來調整。

安裝步驟

Step 1. 在伺服器上安裝Proxool到Java的函式庫中

請到下載網頁下載Proxool的編譯打包檔,檔案類型為jar。

請取出壓縮檔裡面的proxool-0.9.1.zip/proxool-0.9.1/jarjar/jarjar-0.6.jar

接下來安裝到Java的函式庫當中,請把jarjar-0.6.jar擺到JAVA_HOME/jre/lib/ext/[dspace]/lib/當中。JAVA_HOME是你Java環境路徑檔,以我以前的DSpace安裝法來說,jarjar-0.6.jar的位置應該在/usr/java/jdk1.6.0_12/jre/lib/ext/jarjar-0.6.jar以及/dspace/lib/jarjar-0.6.jar

Step 2. 修改DatabaseManager.java

請修改你的[dsapce-source]/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java,也就是請修改/opt/dspace-1.5.1-src-release2/dspace-api/src/main/java/org/dspace/storage/rdbms/DatabaseManager.java

請找到getConnection()的方法:

    public static Connection getConnection() throws SQLException
    {
        initialize();

        return DriverManager
                .getConnection("jdbc:apache:commons:dbcp:" + poolName);
    }

請修改成以下程式碼:

    public static Connection getConnection() throws SQLException //, ClassNotFoundException
    {
        boolean useProxool = ConfigurationManager.getBooleanProperty("db.proxool",true);
		if (useProxool != true)
		{
			initialize();

        	return DriverManager
                .getConnection("jdbc:apache:commons:dbcp:" + poolName);
		}
		else
		{
			Connection conn = null;
			try {
				Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
				conn = DriverManager.getConnection("proxool."+ConfigurationManager.getProperty("db.poolname")+":org.postgresql.Driver:"+ConfigurationManager.getProperty("db.url") 
					, ConfigurationManager.getProperty("db.username")
					, ConfigurationManager.getProperty("db.password"));
			}
			catch (ClassNotFoundException e) {e.printStackTrace();}
			return conn;
		}
    }

如果你的DatabaseManager.java之前並沒有修改過,那麼你也可以用我已經改好的DatabaseManager.java檔案 (http://0rz.tw/a4Vat)。

Step.3 加入SQLQuery.java

請新增[dspace-source]/dspace-api/src/main/java/org/dspace/storage/rdbms/SQLQuery.java。或是用我已經寫好的SQLQuery檔案 (http://0rz.tw/a4Vat)。

SQLQuery是直接用SQL語法直接查詢資料庫的類別,內容也很簡單(版權宣告反而比內容還要長),後面章節會教讀者如何使用,程式碼如下:

package org.dspace.storage.rdbms;

import org.dspace.core.Context;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

public class SQLQuery
{
	private Context context = null;
	private Statement statement = null;
	
	public SQLQuery(Context c)
	{
		context = c;
	}
	
	public ResultSet query(String query) throws SQLException   
    {
		try{
			if (statement != null)
			{
				statement.close();
			}
			statement = context.getDBConnection().createStatement();
			ResultSet rs = statement.executeQuery(query);
			return rs;
		}
		catch (SQLException sqle)
        {
            throw sqle;
        }
		
    }
}
Step.4 修改web.xml

請修改

[dspace-source]/dspace-jspui/dspace-jspui-webapp/src/main/webapp/WEB-INF/web.xml,一樣地你也可以選擇用我已經寫好的web.xml檔案 (http://0rz.tw/a4Vat)。

修改的過程如下:

先找到「</web-app>」,這應該在web.xml的最後一行。

然後在</web-app>之前,加入以下xml設定:

<!-- proxool setting -->
<servlet>
  <servlet-name>ServletConfigurator</servlet-name>
  <servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
  <init-param>
    <param-name>propertyFile</param-name>
    <param-value>${dspace.dir}/config/dspace.cfg</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

<!-- Proxool Admin -->
<!-- If you want to check database connection detail, just remove comment marks. -->
<!--
<servlet>
  <servlet-name>proxool</servlet-name>
  <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>proxool</servlet-name>
  <url-pattern>/proxool</url-pattern>
</servlet-mapping>


<display-name>proxool</display-name>
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
-->

 

注意到後面的註解標籤「<!—」跟「-->」,裡面的內容是Proxool的管理介面,可以看到你資料庫的連線狀態。稍後我會介紹怎麼開啟Proxool的管理介面,預設我們就把他關起來吧。

Step.5 修改dspace.cfg,增加Proxool.properties

請修改[dspace-source]/dspace/config/dspace.cfg,這個設定檔在安裝DSpace的時候一定會修改到,所以我不提供寫好的檔案,請依照以下步驟修改:

首先先找個地方插入設定,其實插入到哪裡都可以,但我想擺在一個跟資料庫靠近的地方還是比較好。請找到「##### Email settings #####」,通常會位於db.poolname的設定之後,原始的dspace.cfg那部份的程式碼如下:

# Specify a name for the connection pool (useful if you have multiple applications sharing Tomcat's dbcp)
# If not specified, defaults to 'dspacepool'
# db.poolname = dspacepool

##### Email settings ######

# SMTP mail server
mail.server=smtp.myu.edu

請先把db.poolname的註解拿掉,變成如下:(如果你有多個DSpace系統,那麼最好用不同的名稱)

db.poolname = dspacepool

請增加以下程式碼:

##### Proxool settings #####

# Use Proxool, you have to install Proxool's jar file (jarjar-0.6.jar) to JAVA_HOME/jre/lib/ext/
db.proxool = true

# Proxool Properties
jdbc-0.proxool.alias = ${db.poolname}
jdbc-0.proxool.driver-class = ${db.driver}
jdbc-0.proxool.driver-url = ${db.url}
jdbc-0.user = ${db.username}
jdbc-0.password = ${db.password}
jdbc-0.proxool.house-keeping-sleep-time = 3000
jdbc-0.proxool.simultaneous-build-throttle = 5
jdbc-0.proxool.prototype-count = 4
jdbc-0.proxool.maximun-connection-lifetime = 60000
jdbc-0.proxool.maximum-connection-count = 500
jdbc-0.proxool.minimum-connection-count = 3
jdbc-0.proxool.statistics = 1m,15m,1d
jdbc-0.proxool.overload-without-refusal-lifetime = 10000
jdbc-0.proxool.maximum-active-time = 60000
jdbc-0.proxool.statistics-log-level=ERROR

如果你想要使用DSpace預設的連線池,那麼可以把db.proxool設為false。

Proxool可以設定的參數還有很多,以上的設定是我們在測試的過程中決定的連線參數,這讓伺服器在短時間內容易到達連線上限,但又很快可以恢復。有興趣可以到Proxool的網站去查查看Properties的意思,或是參考proxool 连接池配置属性说明

稍後我會介紹之後調整參數的方法,預設值就設成這樣吧!

Step.6 DSpace編譯、配置

由於我們修改了dspace.cfg,所以我們必須使用ant的另一個參數來更新DSpace安裝檔。以下照著這個步驟確實地作吧:

移動到[dspace-source]/dspace

[dspace@dspace ~]# cd /opt/dspace-1.5.1-src-release/dspace

執行「mvn package」。

[dspace@dspace dspace]# mvn package

如果最後看到「[INFO] BUILD SUCCESSFUL」訊息,表示編譯成功。如果失敗了,那麼可能是DatabaseManager.java或是SQLQuery.java這兩個檔案出錯了,請檢查編碼或是錯字等問題,然後再來執行mvn package。

請移動到[dspace-source]/dspace/target/dspace-{verion}-build.dir/

[dspace@dspace dspace]# cd /opt/dspace-1.5.1-src-release/dspace/target/dspace-1.5.1-build.dir/

接下來要用ant配置。如果你是第一次安裝DSpace,那麼請執行以下指令:

[dspace@dspace dspace-1.5.1-build.dir]# ant fresh-install

如果你已經安裝了DSpace,那麼請執行以下指令。請務必注意到dspace.cfg必須要指定你的DSpace安裝位置(dspace.dir),我們通常會用[dspace]來表示!

[dspace@dspace dspace-1.5.1-build.dir]# ant -Dconfig=/dspace/config/dspace.cfg init_configs
[dspace@dspace dspace-1.5.1-build.dir]# ant -Dconfig=/dspace/config/dspace.cfg update_webapps

然後把[dspace]/webapps/jspui複製到你的Tomcat的webapps資料夾當中,請注意到要設置成你的Tomcat的安裝位置

[dspace@dspace ~]# 
\cp -rf /dspace/webapps/jspui /opt/apache-tomcat-6.0.13/webapps/

最後重新啟動Tomcat。

[dspace@dspace ~]# /opt/apache-tomcat-6.0.13/bin/shutdown.sh
[dspace@dspace ~]# /opt/apache-tomcat-6.0.13/bin/startup.sh

大功告成了!

接下來你可以打開你的DSpace,移動到display-item的頁面,然後用連點程式狂按「重新整理」或「F5鍵」,看看你的DSpace哪時候會掛點吧!

附帶一題,我是用連點程式每秒按2下「F5」來搞壞我的DSpace的,歡迎大家分享更有「創意」的搞壞方法。(誤)


進階調整

有些預設安裝沒有開啟的功能,或是之後要調整的參數設定,在這邊我一口氣介紹吧!由於DSpace在經過ant配置完之後,需要修改的位置都不大相同。你當然可以用上面的步驟整個慢慢地修改、mvn package、ant,但也可以用以下的偷吃步來修改!

快速修改Proxool參數

請直接修改[dspace]/config/dspace.cfg,修改完畢之後重新啟動Tomcat即可生效。

請注意!如果你的參數設置錯誤的話,Proxool會使用預設值來連線。預設最大連線數(maximum-connection-count)只有15,連線量一多很快就會當掉了。

你會發現[dspace]/config/dspace.cfg中Proxool有些參數跟上面不一樣,這是因為他經過ant配置,把一些變數替換掉的結果。那些都是資料庫連線的必要參數,請不要變更。

如果你發現更好的參數配置,請務必告訴我喔!

開啟Proxool Admin介面

請修改Tomcat中webapps/jspui/WEB-INF/web.xml (/opt/apache-tomcat-6.0.13/webapps/jspui/WEB-INF/web.xml),把Proxool Admin的註解拿掉。然後重新啟動Tomcat,就用網址http://你的主機:8080/jspui/proxool來開啟Proxool Admin。

image

Proxool Admin的畫面如上,當中可以看到Proxool的各個參數跟現在資料庫的連線狀態。如果你發現參數跟你設置的不一樣,例如最大連線數(maximum-connection-count)只有預設值的15,而不是我們設定的500,那麼就可能是你的Proxool設定檔有問題囉。

當不使用的時候,建議是把Proxool Admin介面關掉比較好喔。

使用SQLQuery

還記得我們剛剛新增了一個「SQLQuery.java」嗎?現在我就來介紹一下他要怎麼在DSpace裡面使用。

首先要先引用SQLQuery。

<%@ page import="org.dspace.storage.rdbms.SQLQuery" %>

然後你必需找到context物件。如果你的程式之中沒有預先宣告的話,那麼你可以用以下方法來建立一個context物件:

<%
Context context = new Context();
%>

然後建立一個SQLQuery物件:

<%
SQLQuery sq = new SQLQuery(context);
%>

接著你就可以使用query方法來取得ResultSet囉!

<%
ResultSet rs = sq.query("SELECT count(*) FROM item");
%>

至於ResultSet要怎麼用嘛……就請你參考PostgreSQL 文檔 發出查詢和處理結果囉。


後記

DSpace儘管擁有相當完整的系統架構,但是資料庫連線這個問題卻是困擾我們已久,連DSpace的說明文件都說叫我們手動去砍掉那些死掉的連線(文件裡面把這些連線稱為「殭屍(zombie)」)。

今天總算用Proxool來改進這個問題,Proxool可以動態地踢掉沒動作的連線,比起DSpace內建的連線池還來得聰明的多,真是讓人感動!

最後,請不要問我為什麼不寫論文,而一直在研究DSpace,我只能告訴你這是教育部全國通識計畫要用的系統而已……<-- Post Catalog -->

(more...)

Blogger最新文章與最新回應產生器(jQuery版)

布丁布丁吃布丁

Blogger最新文章與最新回應產生器(jQuery版)

  • 最新文章程式產生器
    Blogger網址http://.blogspot.com 必填!舊版的Blogger無效喔。
    顯示篇數要顯示最新文章數目
    標題長度限制如果是空白,表示不限制
    顯示方式%title%(標題)、%Y%(西元年份)、%M%(月份)、%D%(日期)、%authorname%(作者名稱),可視需要改變排列或是刪掉參數,或加入HTML語法
    標籤可限制只顯示特定標籤的最新文章,空白表示顯示所有標籤的最新文章。
    聯播程式碼: (程式碼擺設的位置)
  • 最新回應程式產生器
    Blogger網址http://.blogspot.com 必填!舊版的Blogger無效喔。
    顯示篇數要顯示最新回應數目
    留言長度限制如果是空白,表示不限制
    顯示方式%comment%(留言)、%Y%(西元年份)、%M%(月份)、%D%(日期)、%authorname%(作者名稱),可視需要改變排列或是刪掉參數,或加入HTML語法
    網站提供 (Feeds Type) 要搭配自己部落格的設定(位置圖),預設是Full(完整)。
    聯播程式碼: (程式碼擺設的位置)

這篇是改進以前我寫的「Blogger專用最新文章與最新回應產生器」,以物件的方式重寫了一遍,並且改進了留言時常因為HTML標籤而爆掉的錯誤。

這次程式碼很簡短,因為大部分的程式碼我都改用引用的方式,可以確保不會因為意外事故讓人裝不上去。此外這次的程式碼也很好懂,應該直接看就知道要做什麼了,如果使用者以後要修改的話就不用回來這邊重新產生,只要修改參數設定就好了。

原始的寫法是參考從堯@部落格來的,各別是Blogger聯播程式產生器(PartII)Blogger最新回應程式產生器(5/27更新),請也支持一下原作者吧。

  • 2011/4/1: 補充,您的Blogger讀取權限必須設定為「任何人」才能使用此功能。
  • 2012/12/21: 修正文章連結會抓到RSS網址的錯誤。因為程式檔案改位置了,所以請重新產生程式碼再安裝一次,這樣才會有效果喔。
(more...)

全文搜尋引擎Lucene簡介投影片

全文搜尋引擎Lucene簡介投影片

image

Lucene是一個全文搜尋引擎的套件,他可以為各種文件製作倒置索引檔(Inverted File),並透過簡單的API來檢索。DSpace的搜尋功能也是透過Lucene來實做,一時興起就去研究看看到底是怎麼回事了。

(Google Docs新開視窗SkyDrive投影片下載)

原本是抱著會對論文有幫助的心態去研究,不過實際上好像用不太到。我還是乖乖地來學習物件導向程式設計還比較實在就是。

參考資源

以下是一些可供參考的網站:

image實際上我是閱讀書本「征服Ajax+Lucene建構搜尋引擎」:

  • 征服Ajax+Lucene建構搜尋引擎(附光碟)
  • 作者:李剛、宋傳、邱哲
  • 出版社:松崗
  • 出版日期:2006年11月07日
  • 語言:繁體中文
  • ISBN:9861258566
  • 定價:490元

之前是在光華大享書局以特價書150元的價格買下來,好像覺得很值得。內文介紹其實不是說寫得很好,他也只是把中國大陸簡體字翻譯成繁體字之後出版而已,很多地方都是把他當作簡體字來看待比較好。

(more...)

Blogger側邊欄開關小工具

布丁布丁吃布丁

Blogger側邊欄開關小工具

image

看來的確有人注意到我的Blogger右上角有個「Sidebar」控制的功能,這可以控制右邊側邊欄的大小,搭配jQuery的動畫效果,呈現的效果其實還蠻有趣的。(只是在IE6中動畫效果並不明顯)

由於網友Gooda的詢問,我特別把這功能獨立出來並改寫成較容易操作的方式,分享給各位Blogger的玩家使用。

程式碼下載

下面的快速安裝當中是使用了我架在Google Page Creator的程式,如果你需要的話,歡迎大家自行下載、修改並使用。


安裝方法

Step.1 進入Blogger管理介面的「版面配置」,點選下方的「新增小工具」

image 

Step.2 新增「HTML/JavaScript」

image

按下右上角的「+」就可以進入編輯畫面。

Step.3 在內容新增程式碼

image

程式碼的內文如下:

<script src="http://puddingchen.35.googlepages.com/jquery.js" type="text/javascript"> </script>
<script type="text/javascript">
jQuery.getScript("http://puddingchen.35.googlepages.com/puliBloggerSidebarControl.js", function () {
	pBS = puliBloggerSidebar();
	pBS.styleController = "cursor:default;float:right;font-size: 10pt;font-weight:normal;margin-right:1em;margin-top:15px;";	//定義控制按鈕的格式
	pBS.styleA = "font-weight:blog;";	//定義左右按鈕的格式
	pBS.textLeft = " &lt; Side";	//定義左文字的內容
	pBS.textCenter = "";	//定義中間文字的內容
	pBS.textRight = "bar &gt; ";	//定義右文字的內容
	pBS.setup();
});
</script>

如果你之前已經引用了jQuery,那麼你可以省略掉第一行的「<script src="http://puddingchen.35.googlepages.com/jquery.js" type="text/javascript"> </script> 」部份。

注意到裡面有些屬性設定,包括CSS與內文的部份。如果你對於呈現出來的導覽列控制按鈕的樣式不太滿意,稍後你可以回來修改這邊屬性的內容。

標題留空無所謂,完成之後按下右下角的「儲存」。

Step.4 看看你的網誌,「< Sidebar >」應該已經出來囉!

image

點點看能不能順利運作吧!

(more...)

製作DSpace的鏡像伺服器(Mirror Server)

布丁布丁吃布丁

製作DSpace的鏡像伺服器(Mirror Server)

當一台伺服器出問題掛點的時候,為了避免服務中斷,我們總是會準備另一台鏡像的伺服器來接手,好讓網路服務能夠持續不斷地進行。

儘管DSpace這種機構典藏系統通常不會需要這麼完全不中斷的高等級服務,不過對於我們這種全國性的教育部計畫來說,總是想要越做越好。因此終於把DSpace的鏡像伺服器功能完成了!

鏡像伺服器說明

鏡像的目的在於建立出另一台一模一樣的伺服器環境、一模一樣的資料,但是卻是獨立運作的個別伺服器。我把主要提供服務的伺服器稱為「Master Server」,而備用作為鏡像的伺服器稱為「Slave Server」。以下不論是在圖解說明還是在程式設定裡面,提到Master(或簡稱M)、Slave(或簡稱S)都是在指這兩種伺服器。

Master Server與Slave Server所提供的服務基本上必須相同,也就是同樣的DSpace系統。但他們之間有兩個差別:

  • 網路設定不一樣:例如Master Server的IP可能是192.168.1.21,而Slave Server則可能是192.168.1.22。當然,現在的網路環境中不可能有兩個同時一樣的IP,但是他們都必需要有固定的IP位置才能進行檔案資料的傳送。
  • 排程功能不一樣:Master Server負責程式的備份,Slave Server則負責把資料從Master Server抓過來,然後利用備份的資料來作還原成Master Server的資料環境。

值得一提的是,因為執行鏡像同步之後,原本被同步的伺服器資料將會消失。例如將Master Server的資料鏡像同步到Slave Server的時候,Slave Server原有的DSpace系統、PostgreSQL資料庫中的資料將會被覆蓋。因此Slave Server將會是很好的測試環境!

鏡像功能說明

鏡像功能當中有7支程式(下載http://0rz.tw/swNWn),其中最後5支是控制鏡像動作的各個功能。程式功能概述如下:

  • config.php:設定檔,主要需要設定Master Server跟Slave Server的網路設定。
  • function.php:執行函式庫,大部分的動作都在這個函式庫當中執行。
  • initiate-slave.php:建置Slave Server的環境。
  • rsync-slave2master.php:檔案鏡像同步,從slave到master。
  • rsync-master2slave.php:檔案鏡像同步,從master到slave。
  • network-master2slave.php:修改網路設定,從master到slave。
  • network-slave2master.php:修改網路設定,從slave到master。

後面五支程式可以用「php rsync-master2slave.php」這樣的指令來執行。接下來我們一邊建置鏡像伺服器的環境,一邊說明這些程式的功用吧。

Step1. 設定config.php

請先把DSpace鏡像程式下載到本機端,然後修改設定檔config.php,以便之後的步驟中可以上傳到伺服器裡。

設定檔內容很多,大部分我都有撰寫註解以說明。最重要的是要設定Master Server與Slave Server的網路設定,而這些參數就在檔案開頭,如下:

//鏡像主要伺服器與備份伺服器
$rsyncConfig["serverMaster"]="192.168.1.21";	//Master Server的IP
$rsyncConfig["serverMasterDN"]=$rsyncConfig["serverMaster"];	//Master Server的Domain Name
$rsyncConfig["serverSlave"]="192.168.1.22";	//Slave Server的IP
$rsyncConfig["serverSlaveDN"]=$rsyncConfig["serverSlave"];	//Slave Server的Domain Name

請依照Master Server與Slave Server實際的網路位置去做設定吧。

Step2. 配置Master Server

在config.php預設設定裡面:

最後,把上述7支鏡像功能程式上傳到「/root/rsync」吧。

請完成以上工作之後,才能開始準備進行鏡像。如果你系統安裝位置與上述路徑不同,則請修改config.php檔案,程式內皆有註解說明,應該很好懂才是。

Step3. 安裝Slave Server

請安裝與Master Server同樣的作業系統,如果你跟著我之前寫的「DSpace 1.5.1安裝法」來作的話,那麼你需要注意以下幾點:

  • 作業系統是CentOS 5.2。
  • 需要額外安裝PostgreSQL跟Apache PHP環境。
  • 需要額外開啟8080 port。
  • 需要額外建立名為「dspace」的帳號。

安裝完成之後,一樣把上述7支鏡像功能程式上傳到「/root/rsync」吧。接下來DSpace的伺服器環境、資料,都交由鏡像程式來幫你執行!

Step4. 配置Slave Server伺服器環境

image

概念如上圖,我們從Master取得伺服器環境所的軟體,並執行安裝。所使用的程式是「initiate-slave.php」。你需要在Slave Server中執行這支程式(為了避免網路放置過久斷線,強烈建議在Slave Server本機端執行):

[root@dspace2 ~]# php /root/rsync/initiate-slave.php

第一次執行,程式會提示你製作並安裝SSH公鑰與私鑰,你需要依照程式的提示到Master Server去安裝可以登入的公鑰(詳細可以參考鳥哥的說明)。只有安裝SSH公鑰與私鑰之後,Slave Server才能順利從Master Server取得資料,而不需要每次都詢問密碼。要注意的是,當Master Server要像Slave Server取得資料的時候,依然需要詢問密碼的,除非你手動新增了公鑰。

第二次執行,程式會開始安裝各個DSpace所需要的軟體,並且修改設定成為適合運作DSpace的環境,同時安裝自動鏡像的排程。如果順利安裝完成的話,接著就可以來作鏡像取得資料了。

Step5. 手動從Master Server取得資料到Slave Server

image

接著一樣在Slave Server本機端中執行這支程式:

[root@dspace2 ~]# php /root/rsync/rsync-master2slave.php

程式就會自動從Master Server取得資料,然後再將部份設定檔修改成Slave Server所在的網路設定,以讓他可以順利運作。

這隻程式在Step4的時候就被設定成為自動執行,預設是每週日早上5點進行鏡像,如需要調整請修改config.php。

Step6. Master Server與Slave Server網路身份交換

image

透過「network-master2slave.php」與「network-slave2master.php」,可以快速地將伺服器的網路狀態切換,同時修改設定檔。這在Master Server出問題而需要Slave Server馬上接替他的工作時派得上用場。

作法是先在Master Server上執行「network-master2slave.php」:

[root@dspace ~]# php /root/rsync/network-master2slave.php

然後在Master Server上執行「network-slave2master.php」:

[root@dspace2 ~]# php /root/rsync/network-slave2master.php

那麼他們的網路狀態就會交換過來,用原本Master Server的IP就可以連到運作正常的Slave Server上。

相反地執行以上功能,就可以讓兩者的網路設定恢復原樣。

Step7. 手動從Slave Server取得資料到Master Server

image

 

在Master Server上執行「rsync-slave2master.php」就可以把Slave Server上的資料抓過來:

[root@dspace ~]# php /root/rsync/rsync-slave2master.php

當Slave Server資料比Master Server還要新的時候,則可以執行這個指令。

結語

用PHP來控制Linux系統有很多好處,像是陣列控制自由、字串搜尋、寫入、取代等功能方便易懂,不用像Bash Shell Script寫起來寫到快吐血都還過不了,而PHP也是我比較熟悉的語言。

DSpace鏡像功能能夠給伺服器更完整的一個備份機制,但是相對的你也得付出一台相同伺服器、佔掉一個網路位置的成本,如何考量就看你們怎麼使用了。

希望DSpace蓬勃發展,大家加油吧。

(more...)

在工人舍SX安裝Windows 7 Beta

布丁布丁吃布丁

在工人舍SX安裝Windows 7 Beta

2009-03-29-619

機種:KJS工人舍 SX系列-黑色(XP GPS版) 產品代碼:K7873

安裝作業系統:Windows 7 7000.0.081212-1400_client_en-us_Ultimate-GB1CULFRE_EN_DVD (這是2008年12月20日微軟發給部份測試者的版本)

這個型號買來的時候是安裝Windows XP Home版本,本來就打算重新安裝成Windows XP Professional版,不過在這之前,聽說Windows 7對於觸控介面設計有獨到之處,一時興起就抓了Windows 7來安裝看看,結果讓我十分滿意,真要用觸控功能的話,比起Windows XP,我會更喜歡Windows 7。Windows 7具有較適合觸控的介面設計,比起Windows XP美觀的系統介面,更簡單也更好用的系統設定,

安裝完成之後畫面如下,雖然我這張是取自於Wikipedia,不過與實際畫面相去不遠:

image 


硬體規格

  • 工人舍 S47-SX3KX08GTW (黑) 詳細規格表
  • 作業系統: Windows XP Home
  • 處理器:Intel Atom Z520 1.33GHz
  • 晶片組:Intel US15W Chipset
  • 記憶體:1G DDR2 667(規格是DDR2 533)
  • 螢幕:Glare WIDE 8.9"(WXGA) 1280x768 TFT Color LCD with Touch Screen Panel
  • 硬碟:80GB(1.8吋)
  • 光碟機:Tray Type, 9.5 mm (DVD Super Multi燒錄器)
  • 多媒體網路攝影機:搭載前、後雙向攝影機(2 Way Camera)前35萬畫素後200萬畫素
  • Audio:Stereo Speakers-1 watt
  • Sound Chip:AC97,Realtek ALC262 VC2-G
  • I/O Ports外接介面~
    • VGA:Yes (外接螢幕可到1680*1050)
    • USB 2.0:2組
    • FIR:No
    • DC-In:Yes
    • Headphone:Yes(前置)
    • Microphone in:Yes(前置)
    • Built-In Microphone:Yes
    • RJ-45:Yes (右側附蓋)
    • Memory Card Reader: SDHC、MicroSDHC、MS(包括duo),個別獨立的讀卡機
    • Express Card Slot:Yes (特色!)
    • Power Button:Yes
    • Launch Buttons:Yes
    • Wireless On/Off (w/LED):Yes
    • Ethernet (10/100M):10/100
    • Wireless LAN:B/G
    • WLAN Antenna Ready:Yes
    • Input Device~Keyboard:TWN Keyboard
    • Pointing:Touch Pad with 2 pick buttons (左鍵加大是貼心設計)
    • Battery type:3-Cell
    • Battery life:2.5 hrs (跟大多數小筆電比起來略短)
    • AC Adaptor:19V/50W
    • Bluetooth:QCOM USB 2.0
    • 尺寸:227mm (W) x 170mm (D) x 25.4 ~ 33mm (H)
    • 重量:1.2kg(不含電池)
    • 保固:商品一律依其原廠或代理商之保固條約內容所履行。工人舍筆記型電腦行動電腦主體及內部組件保固一年、電池與AC變壓器

查看Windows 7的基本資訊如下:

工人舍SX Windows7基本資訊 


Windows體驗指數1.9分

工人舍SX Windows體驗指數

Windows體驗指數以1到7.9的分數範圍來評定電腦的等級,而這之中取最低的分數作為該電腦的基本分數。工人舍SX所獲得的分數如下表,基本分數取最低子分為1.9分。

元件 分級資料 子分數 備註
處理器 計算(每秒) 1.9 Intel Atom Z520 1.33GHz
記憶體(RAM) 每秒的記憶體運算 4.2 1G DDR2 667(規格是DDR2 533)
圖片 Windows Aero的桌面效能 2.9 Intel US15W Chipset
遊戲圖形: 3D商業和遊戲圖形效能 2.5
主要硬碟: 磁碟資料傳送速率 1.9 TOSHIBA MK8025GAL,80GB(1.8吋),平均傳輸速率為26.9MB/sec,隨機存取時間23.4ms

關於工人舍SX的效能報告,可以參考傳說中的挨踢部門: KOHJINSHA 工人舍 SX 台灣版 SX3KP08HTW --實測篇


工人舍SX的驅動程式皆可正常安裝

2009-03-29-620

工人舍大部分的驅動程式都可以順利安裝在這個版本的Windows 7,唯有顯示卡的驅動程式安裝的時候失敗,但在經過Windows Update之後就能夠順利運作。

2009-03-29-628 2009-03-29-626

這包括了各種的快捷鍵,像是右邊的上下快捷鍵(如上圖左,調整亮度)、鍵盤Fn搭配的功能鍵(如上圖右,調整照相機)、光碟機開關、無線網路開關(這應該只是牽涉到硬體層面)。另外GPS我沒有測試。


開機大約1分26秒

從出現工人舍畫面到進入Window 7的檔案總管,所需時間大約是1分26秒。中間要選擇Windows版本是因為之前安裝的Windows XP Home的緣故,稍微拖累了一些時間。


關機大約25秒

關機 從按下「關機」指令,看完Windows Logoff到畫面消失,時間大約是24秒。但是工人舍SX的電 源燈熄滅大約要40秒,我猜可能是之後工人舍SX要自己關掉一些硬體的關係,所以比起作業系統又稍微延後了一些時間。


Origami Experience 2.0可順利運作,但圖片投影片不太順暢

 

2009-03-29-621

畫面上看到的是微軟為UMPC或MID裝置所作的Origami Experience 2.0,相關資料可以看看以下網頁:

簡單地說,這功能讓具有觸控螢幕的電腦看起來像PMP一樣地可以用手指操作,包括按鈕加大,把影音播放、圖片播放等功能提到前面來用,加入RSS摘要功能,改善IE瀏覽器(其實也只有工具列跟移動網頁的方式不同而已)。功能並沒有很豐富,運作起來也不是很順暢,怎麼說也不會讓人覺得滿意。

接下來就看一下一些圖片吧:

2009-03-29-622

手寫便條紙這邊我還蠻喜歡的,十分方便。

2009-03-29-623

可以檢視照片。使用投影片模式播放照片又有許多有趣的類型,但播放起來並不順暢。

2009-03-29-624

像拍立得的形式,下面顯示檔案名稱。

2009-03-29-625

把螢幕切割成很多塊各別顯示圖片。


Open PCman Combo Nova亂碼

Windows 7 PCman亂碼

儘管已經安裝了繁體中文語言包,Open PCman Combo 9.2.2 (Novus)依然是亂碼。可憐的巴哈姆特身上盡是看不懂得外國語言。


其他新功能

有許多篇報導已經介紹過Windows 7的新功能,我也不特別去贅述,有興趣的話可以參考以下資料:

 

<-- Post Catalog -->

(more...)

zFTPServer Suite Build: 2008-06-18 12:11

布丁布丁吃布丁

0 Comments

zFTPServer Suite Build: 2008-06-18 12:11

image

許多人都發現到現在zFTPServer Suite最新的版本並不支援中文亂碼,所以我補一下不會造成亂碼的版本。

zFTPServer Suite Version Information

  • Administration Build: 2008-06-18 12:11
  • Server Build: 2008-06-18 12:11

SkyDrive空間:zFTPServer_Suite_Setup 2008-06-18 1211.exe

連線軟體使用的是FileZilla 3.2.1 Portable,不需要特別設定語系,即可正常讀取大多數中文檔名(細部還沒有特別去測試)。使用IE連FTP可以正常下載,但是上傳時會因為路徑中文變成亂碼而無法上傳。

(more...)