argius note

プログラミング関連

ローカル用ブックマーク(今度はRubyで)

調子に乗って、Ruby版も作ってみました。やっぱりRubyのほうが楽に書ける半面、WEBrickとか使ったことなかったのでその辺で苦労してます。
起動は以下のような感じ。

./bukma.rb ポート [(プロキシを使う場合にURLを指定)]

今のところ、タイトルのところとか、ローカル環境と違う文字コードだとちゃんと取れません。

#!/usr/bin/env ruby

require 'webrick'
require 'open-uri'

port = ARGV.shift || 80
$proxy = ARGV.shift
INDEXFILE = "index.html"
TOOLNAME = "bukmaR"
HEADER = <<"EOD"
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<link rel="stylesheet" type="text/css" href="./bukma.css">
EOD

class EditServlet < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(req, res)
    title = "(unknown title)"
    url = req["Referer"]
    open(url, :proxy => $proxy) do |f|
      buffer, innerTitle = "", false
      f.each_line do |line|
        innerTitle = true if /<title/i =~ line
        if innerTitle
          buffer += line
          innerTitle = false if /<\/title>/i =~ line
          if /<title[^>]*>(.+)<\/title>/im =~ buffer
            title = $1.gsub(/[\t\r\n]/, "")
            break
          end
        end
      end
    end
    res["Content-Type"] = "text/html"
    res.body = <<"EOD"
<html><head>#{HEADER}</head><body><h1>#{TOOLNAME}</h1>
<form method="get" action="/register"><pre>
<input type="hidden" name="url" value="#{url}">
 comment <input type="text" name="comment" value="" size="60">
   title <input type="text" name="title" value="#{title}" size="60">
<input type="submit">
</pre></form></body></html>
EOD
  end
end

class RegisterServlet < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(req, res)
    now = Time.now
    id = now.strftime("%Y%m%d-%H%M%S")
    file = id + ".html"
    title = req.query["title"]
    comment = req.query["comment"]
    time = now.strftime("%Y/%m/%d %H:%M:%S")
    url = req.query["url"]
    raise "unexpected error : " + file if File.exist?(file)
    open(file, "w") do |out|
      open(url, :proxy => $proxy) do |f|
        f.each_line do |line|
          out.print line
        end
      end
    end
    lines = if test("e?", INDEXFILE) then IO.readlines(INDEXFILE) else [] end
    open(INDEXFILE, "w") do |out|
      out.puts "<html><head>#{HEADER}</head><body><h1>#{TOOLNAME}</h1>"
      out.puts <<"EOD" # do not insert new line
<h2><a href="#{file}">#{title}</a></h2><p class="comment">#{comment}</p><p><span class="time">#{time}</span> <span class="url"><a href="#{url}">#{url}</a></span></p>
EOD
      lines.each do |line|
        out.puts line if line[0..2] == "<h2"
      end
      out.puts "</body></html>"
    end
    res["Content-Type"] = "text/html"
    res.body = IO.readlines(INDEXFILE).join
  end
end

STDOUT.sync = true
puts <<"EOD"
This is #{TOOLNAME} server, version 0
EOD
server = WEBrick::HTTPServer.new(:Port => port)
server.mount("/edit", EditServlet)
server.mount("/register", RegisterServlet)
server.mount("/", WEBrick::HTTPServlet::FileHandler, "./")
trap("INT") do server.shutdown end
server.start