#!/usr/local/bin/ruby require 'fileutils' require 'date' require 'net/http' Net::HTTP.version_1_2 # おまじない # 記事を作成するディレクトリ。ファイル名は .html $news_dir = './mnews/' # nmewsのトップページ $redirect = './mnews.html' # ロックファイル $lockfile = './lock/mnews.lock' $lockfile = '' # symlinkが使えない場合は空文字列 # 取得するURL $news_url = 'http://maplestory.nexon.co.jp/web_module/skins/MapleStory/board_list.asp?strboardid=maplestorynews' # 更新間隔 [秒] $interval = 60 * 60 # 新着情報の正規表現 $match_news = Regexp.new(<<'EOS'.gsub(/\n|\r/, '')) (\d+)\.(\d+)\.(\d+) ([^<]+)  EOS $lockflag = 0 # メイン処理 def main() printf "content-type: text/html\n" newsary = [] if not FileTest.exist?($redirect) or (Time.now - File.stat($redirect).mtime > $interval) # 新着情報を入手して上書きする body = get_body($news_url).gsub!(/\n|\r/, '') # 色々問題あるので改行消去 body.scan($match_news) { newsary.push $~[1..5] } lock() make_index(newsary) # トップページ作成 # 記事作成 未作成分と当日・前日分のみ newsary.each do |year, month, day, url, news| if /intidx=(\d+)/ =~ url intidx = $1 if Date.new(year.to_i, month.to_i, day.to_i) > Date.today - 2 or not FileTest.exist?($news_dir + intidx + '.html') make_article($news_url.gsub(/[^\/]+$/, '') + url, intidx, year, month, day, news) end end end unlock() end #printf "Location: %s\n", $redirect # index.cgiにすると redirectがうまく行かなかったので読み込む print "\n" print File.open($redirect).read end # 指定したURLの内容を取得 def get_body(url) if %r!^http://([^/]+)(.*)!i =~ url host, file = $1, $2 newsary = [] Net::HTTP.start(host, 80) do |http| response = http.get(file) return response.body end end end # 「おしらせ」の記事の詳細を作成 def make_article(url, intidx, year, month, day, news) # intidx: article number FileUtils.mkdir_p($news_dir) body = get_body(url) # 〜 を取得 if %r!(.*?)!im =~ body oh = File.open($news_dir + intidx + '.html', 'w') # ヘッダ出力 oh.print <<"EOS" #{ sprintf "%s/%s %s

", month, day, news }#{$1} EOS oh.close end end # mnewsのトップページの作成 def make_index(newsary) File.open($redirect, 'w') do |oh| # ヘッダ出力 oh.print <<"EOS"
MapleStory What's New
#{ newsary.map { |year, month, day, url, news| # インデックス作成 (/intidx=(\d+)/ =~ url)? sprintf("%s/%s %s
\n", month, day, $news_dir + $1 + '.html', news): "" }.join } EOS end end # エラー処理 def error(mes) unlock() if $lockflag == 1 printf "\n\n%s", mes exit end # ロック def lock() return if $lockfile.length == 0 # 古いロックを削除 unlock() if FileTest.exist?($lockfile) and Time.now - File.stat($redirect).mtime > 30 cnt = 5 # リトライカウンタ while (cnt -= 1) >= 0 do begin File.symlink(".", $lockfile) $lockflag = 1 break rescue error("ファイルロックに失敗しました。\nしばらくしてアクセスし直すか、こちらにどうぞ" % $redirect) if cnt == 0 sleep(1) end end end # アンロック def unlock() return if $lockfile.length == 0 File.unlink($lockfile) $lockflag = 0 end main()