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 }
何はともあれ、それなりに動くようだ。てか、あからさまに速い。 下手したら倍くらいの感じ。でもかみさんは満足しないだろーなー...