Hikiのmod_ruby化
Hikiの0.8.0 preview1がリリースされた。mod_rubyに正式対応したそうなので、 早速試してみようかと。が、rubyが1.8以降になってしまってる。 woodyのlibapache-mod-rubyは1.6.7だ。仕方ないのでソースから入れてあった apache2で試すことに。apache2にはmod_rubyが無いので、まずこれから。
$ tar zxvf mod_ruby-1.2.0.tar.gz $ cd mod_ruby-1.2.0/ $ ./configure.rb --with-apxs=/usr/local/apache2/bin/apxs
/usr/local/apache2/bin/apxsの先頭に
#!/usr/local/bin/perl -w
と書いてあってエラーになるので(今まで使ったこと無かったのか?)、
# ln -s /usr/bin/perl /usr/local/bin/
としてから作業継続。
$ make # make install
httpd.confに以下を追加。
LoadModule ruby_module modules/mod_ruby.so
続いてHiki本体。hikifarmにしたいのでmisc/hikifarm/READMEに従ってインストール。
Hiki本体 → /usr/local/hiki-0.8.0 CGI → /home/httpd/hiki08 データ → /home/hiki08-data
httpd.confに以下を追加。
Alias /hiki "/home/httpd/hiki08"
<Directory "/home/httpd/hiki08">
AllowOverride None
Options +ExecCGI +FollowSymLinks
#AddHandler cgi-script .cgi
RubyRequire apache/ruby-run
<Files *.cgi>
SetHandler ruby-object
RubyHandler Apache::RubyRun.instance
</Files>
DirectoryIndex index.cgi
Allow from all
</Directory>これで完了。0.6.5のhiki-data/をそのままコピーするとinternal errorになるので、 まずメニューからWikiサイトを作ってデータだけコピーする。
Wikiサイト名/hiki.conf
のフォーマットが違うのがいけないらしい。しかもその場合は、
http://server/hiki/Wikiサイト名/
は問題無く動くのに、
http://server/hiki/
がinternal errorなので、非常にわかりにくい。 あと、管理メニューで更新すると落ちる。これもhiki.confのフォーマットか? 落ちるとhiki.confが無くなってしまうようなので、あんまり試してない。
最大の関門は自作のプラグイン。 0.6.5のプラグイン→0.8.0に移行に関しては、
$変数 → @conf.変数
でいけるはずなのだが、mod_ruby化の方が厄介らしい。 attach.rbのform_procでInsecure Operationが出てしまう。 add_form_procで登録しているattach_show_page_files_checkbox()から 呼ばれているattach_file_info() (これはtDiaryから移植した自作関数)の 中で添付画像のサイズを調べているところが問題らしい。 File.open(attach_file)する前に
attach_file.untaint
とすることで解決。
また、今までimage.rbとして別プラグインにしていたcat_image()、image_external()を attach.rbに統合。
--- attach.rb.org Thu May 26 00:28:57 2005
+++ attach.rb Thu May 26 19:49:15 2005
@@ -11,6 +11,79 @@
</ul></div>'
end
+# 猫専用
+def cat_image( dir, file, width, height, place = "right", lnk = 0, target = "_blank" )
+ ext = '.jpg'
+ if (file =~ /SANY/)
+ ext = '.JPG'
+ end
+ if (lnk == 1)
+ begin_a = %Q[<a href="http://www.asahi-net.or.jp/~ad6h-ootk/cat/#{dir}/#{file}.html" target="#{target}">]
+ end_a = %Q[</a>]
+ else
+ begin_a = ''
+ end_a = ''
+ end
+ %Q[#{begin_a}<img class="#{place}" src="http://www.asahi-net.or.jp/~ad6h-ootk/cat/#{dir}/#{file}#{ext}" border="0" width="#{width}" height="#{height}" alt="#{file}"</img>#{end_a}]
+end
+#
+def image_external( url, alt, width, height, place = "right", lnk = 0, target = "_blank" )
+ if (lnk == 1)
+ begin_a = %Q[<a href="#{url}" target="#{target}">]
+ end_a = %Q[</a>]
+ else
+ begin_a = ''
+ end_a = ''
+ end
+ %Q[#{begin_a}<img class="#{place}" src="#{url}" border="0" width="#{width}" height="#{height}" alt="#{alt}"</img>#{end_a}]
+end
+#
+# service methods below. (from tDiary image.rb plugin)
+#
+
+def attach_file_info(fname)
+ image_type = nil
+ image_height = nil
+ image_width = nil
+ attach_file = "#{@cache_path}/attach/#{@page.escape}/#{fname.escape}"
+ attach_file.untaint
+ f = File.open(attach_file)
+
+ sig = f.read( 24 )
+ if /\A\x89PNG\x0D\x0A\x1A\x0A(....)IHDR(........)/on =~ sig
+ image_type = 'png'
+ image_height, image_width = $2.unpack( 'NN' )
+
+ elsif /\AGIF8[79]a(....)/on =~ sig
+ image_type = 'gif'
+ image_height, image_width = $1.unpack( 'vv' )
+
+ elsif /\A\xFF\xD8/on =~ sig
+ image_type = 'jpg'
+ data = $'
+ until data.empty?
+ break if data[0] != 0xFF
+ break if data[1] == 0xD9
+
+ data_size = data[2,2].unpack( 'n' ).first + 2
+ if data[1] == 0xC0
+ image_width, image_height = data[5,4].unpack('nn')
+ break
+ else
+ if data.size < data_size
+ f.seek(data_size - data.size, IO::SEEK_CUR)
+ data = ''
+ else
+ data = data[data_size .. -1]
+ end
+ data << f.read( 128 ) if data.size < 4
+ end
+ end
+ end
+
+ return image_type, image_height, image_width, FileTest.size(f)
+end
+
def attach_form(s = '')
command = @command == 'create' ? 'edit' : @command
<<EOS
@@ -61,8 +134,13 @@
s << %Q!#{file_name.escapeHTML}</a>!
end
-def attach_image_anchor(file_name, page=@page)
- s = %Q!<img alt="#{file_name.escapeHTML}" src="!
+def attach_image_anchor(file_name, page=@page, width=nil, height=nil, place=nil)
+ if (width && height)
+ imgsize = %Q!width="#{width}" height="#{height}"!
+ else
+ imgsize = ''
+ end
+ s = %Q!<img class="#{place}" alt="#{file_name.escapeHTML}" #{imgsize} src="!
s << %Q!#{@conf.cgi_name}#{cmdstr('plugin', "plugin=attach_download;p=#{page.escape};file_name=#{file_name.escape}")}">!
end
@@ -143,11 +221,11 @@
end
end
-def attach_view(file_name, page=@page)
+def attach_view(file_name, width=nil, height=nil, place=nil, page=@page)
if file_name =~ /\.(txt|rd|rb|c|pl|py|sh|java|html|htm|css|xml|xsl)\z/i
attach_src(file_name, page)
elsif file_name =~ /\.(jpeg|jpg|png|gif|bmp)\z/i
- attach_image_anchor(file_name, page)
+ attach_image_anchor(file_name, page, width, height, place)
end
end
@@ -194,14 +272,38 @@
s
end
+
def attach_show_page_files_checkbox
- s = ''
+ s = %Q[
+ <script type="text/javascript">
+ <!--
+ var elem=null
+ function ins(val){
+ // alert(val)
+ elem.value+=val
+ }
+ window.onload=function(){
+ for(var i=0;i<document.forms.length;i++){
+ for(var j=0;j<document.forms[i].elements.length;j++){
+ var e=document.forms[i].elements[j]
+ if(e.type&&e.type=="textarea"){
+ if(elem==null){
+ elem=e
+ }
+ e.onfocus=new Function("elem=this")
+ }
+ }
+ }
+ }
+ //-->
+ </script>
+ ]
if (files = attach_page_files).size > 0
- s << %Q!<form method="post" enctype="multipart/form-data" action="attach.cgi">
- <input type="hidden" name="p" value="#{@page.escapeHTML}">
- <input type="hidden" name="command" value="#{@command == 'create' ? 'edit' : @command}">
- <p>#{attach_files_label}:
+ s << %Q!<p>#{attach_files_label}:
!
+ s1 = ''
+ s2 = ''
+ s3 = ''
files.each do |file_name|
f = file_name.unescape
case @conf.charset
@@ -210,13 +312,51 @@
when 'Shift_JIS'
f = file_name.unescape.to_sjis
end
- s << %Q! [<input type="checkbox" name="file_#{file_name}">#{attach_anchor(f)}] \n!
- end
- s << %Q!<input type="submit" name="detach" value="#{detach_upload_label}">\n</p>\n</form>\n!
+ img_info = attach_file_info(f)
+# img_info = ['jpg',100,100,500]
+ img_w = img_info[1]
+ img_h = img_info[2]
+ while (img_w > 200)
+ img_w = img_w / 2
+ img_h = img_h / 2
+ end
+ #s1 << %Q! <td><input type="button" onclick="window.status='xxx'" value="本文に追加"> </td>\n!
+ s1 << %Q! <td><input type="button" onclick="ins('{{attach_view("#{f}",#{img_w},#{img_h}}}')" value="本文に追加"> </td>\n!
+ #s1 << %Q! <td><input type="button" onclick="window.status='xxx'; ins({{attach_view(#{f})}})" value="本文に追加"> </td>\n!
+ #s1 << %Q! <td>{{attach_view(#{f},#{img_w},#{img_h})}} </td>\n!
+ s2 << %Q! <td>#{attach_view(f,img_w,img_h)} </td>\n!
+ s3 << %Q! <td><input type="button" onclick="ins('{{attach_view("#{f}",#{img_w},#{img_h}}}')" value="本文に追加"><br>#{img_info[1]}x#{img_info[2]}(#{img_info[3]/1024}K)<br><input type="checkbox" name="file_#{file_name}" value="true">#{attach_anchor(f)} </td>\n!
+ end
+ #s << %Q!<br><table><tr>#{s1}</tr><tr>#{s2}</tr><tr>#{s3}</tr></table><br>!
+ s << %Q!<br><table>\n<tr>\n#{s2}</tr>\n<tr>\n#{s3}</tr>\n</table><br>!
+ s << %Q!<input type="submit" name="detach" value="#{detach_upload_label}">\n</p>!
end
s
end
+#def attach_show_page_files_checkbox
+# s = ''
+# if (files = attach_page_files).size > 0
+# s << %Q!<form method="post" enctype="multipart/form-data" action="attach.cgi">
+# <input type="hidden" name="p" value="#{@page.escapeHTML}">
+# <input type="hidden" name="command" value="#{@command == 'create' ? 'edit' : @command}">
+# <p>#{attach_files_label}:
+#!
+# files.each do |file_name|
+# f = file_name.unescape
+# case @conf.charset
+# when 'EUC-JP'
+# f = file_name.unescape.to_euc
+# when 'Shift_JIS'
+# f = file_name.unescape.to_sjis
+# end
+# s << %Q! [<input type="checkbox" name="file_#{file_name}">#{attach_anchor(f)}] \n!
+# end
+# s << %Q!<input type="submit" name="detach" value="#{detach_upload_label}">\n</p>\n</form>\n!
+# end
+# s
+#end
+
add_body_leave_proc {
begin
@@ -232,12 +372,12 @@
add_form_proc {
begin
- s = case @options['attach.form']
- when 'edit', 'both'
+ #s = case @options['attach.form']
+ #when 'edit', 'both'
attach_form(attach_show_page_files_checkbox)
- else
- ''
- end
+ #else
+ # ''
+ #end
rescue Exception
end
}
何はともあれ、それなりに動くようだ。てか、あからさまに速い。 下手したら倍くらいの感じ。でもかみさんは満足しないだろーなー...
