| @技術/プログラミング

ポータルシットのコメント一覧ページで、マウスオーバーして全文を取得するやつをかっこよくした。

これまではjQueryでスクレイピングして、記事のパーマリンクからコメントを取得していた。しかしこれは無駄なクエリが発生する。記事本文を取得するクエリとコメントを取得するクエリだ。

これはださいと思っていたので、Rubyでコメントを取得してJSONで返すCGIを書いた。

#! /usr/bin/env ruby
#-*- coding: utf-8 -*-
start_time = Time.now

require "rubygems"
require "active_record"
require "mysql"
require "kconv"
require "cgi"

ActiveRecord::Base.establish_connection(
  :adapter  => "mysql",
  :database => "database_name",
  :host     => "mysql.host.name",
  :username => "mysql_username",
  :password => "mysql_password",
  :socket   => "/path/to/mysqld.sock",
  :encoding => "utf8"
)

class Comment < ActiveRecord::Base
  set_table_name 'p_forum'
  
  def self.some_comment(n)
    find(n)
  rescue ActiveRecord::RecordNotFound
    return false
  end
end

cgi = CGI.new
comment_id = cgi.params['id'][0]
@comment = Comment.some_comment(comment_id)
redirect_url = '/var/index.php?id=error404'
print cgi.header({ 'status' => 'REDIRECT', 'Location' => redirect_url }) unless @comment
cgi.out("application/json") {
  {:title => @comment.title, :user_name => @comment.user_name, :user_uri => @comment.user_uri, :date => @comment.date, :mod => @comment.mod, :comment => @comment.comment, :generation => Time.now - start_time}.to_json
}

ActiveRecordのおかげでさくっとできる。このCGIにjQueryで $.getJSON() してJSONをページ内に読み込む。各コメントはMarkdownに似た形式で記述されているので、Showdown.js を使って Markdown->HTML して表示している。参考までにコードはこんな感じ。

// load entire comment by JSON
$(document).ready(function() {
  $("#recent-comment-list a.taggedlink").one("mouseover", function() {
    var targetUrl = $(this).attr("href");
    targetUrl.match(/#c(d+)$/);
    var commentId = RegExp.$1;
    var commentLoadDiv = 'div#c' + commentId;
    var commentAuthorParagraph = 'div#c' + commentId + ' + p.auth';
    $.getJSON(
      'comments.cgi',
      { "id": commentId },
      function(data) {
        var converter = new Showdown.converter();
        var comment = converter.makeHtml(data.comment);
        $(commentAuthorParagraph).css("clear", "both");
        $(commentLoadDiv).html(comment).slideDown("slow");
        $(commentLoadDiv).wrap('<div class="comment-content"></div>');
      }
    );
  });
});

問い合わせのクエリはコメントを持ってる p_forum というテーブルへの一回だけになったが、RubyをCGIとして動かすと遅い。パフォーマンスは逆に落ちてるかも知れないけど、所詮自己満足なので問題なし。

追記: なんか脆弱性ありそうな気がしてきた…