PRagger用プラグインを作った

Rails 南蛮通事」システムでは海外のRails情報を PRagger を使って収集しようと考えています。
しかし、現在PRaggerで集めた情報をDBに書くプラグインはありません。 そこで作ってみました :-)

仕様

  • MySQL専用
  • 書き込むDB,table名はコンフィグで指定
  • カラム名RSSの情報名と同じカラムを用意する (CoC)
    • title, link, description, dc_date
  • 定数を挿入するカラムをコンフィグで指定できる
    • additional_data:
  • created_at カラムがあれば自動的にタイムスタンプを挿入

プラグインコード

require "mysql"

def mysql_insert(config, data)
  connect_db(config) do |db_info|
    data.each do |d|
      rss = Hash.new
      rss['title'] = d.title rescue d.to_s
      rss['link'] = d.link rescue ""
      rss['description'] = d.description rescue ""
      rss['dc_date'] = (d.date rescue Time.now.utc).localtime.strftime('%Y-%m-%d %H:%M:%S')

      insert_db(db_info, rss)
    end
    puts " insert #{data.size} records for #{config['additional_data']['source']}"
  end
end

def connect_db(config)
  db = Mysql.init()
  db.options(Mysql::SET_CHARSET_NAME, 'utf8')
  db.connect(config['server'] || 'localhost', config['username'], config['password'],
                     config['database'])
  db.autocommit(false)

  db_info = Struct.new("DbInfo", :db, :table, :columns, :additional_data).new
  db_info.db = db
  db_info.table = config['table']
  db_info.columns = get_columns(db, config['table'])
  db_info.additional_data = config['additional_data']
  yield db_info
  db.commit
rescue
  db.rollback
  raise
ensure
  db.close
end

def insert_db(db_info, rss)
  columns = []
  values = []
  # tableに在るカラムと一致する情報を挿入
  db_info.columns.each  do |name|
    if (rss[name])
      columns << name
      values << "'" + Mysql.quote(rss[name]) + "'"
    end
  end
  # additional_data があれば挿入
  db_info.additional_data.keys.each do |col|
    columns << col
    values << "'" + Mysql.quote(db_info.additional_data[col]) + "'"
  end
  # created_at があれば CURRENT_TIMESTAMP を挿入
  if (db_info.columns.include? 'created_at') 
    columns << 'created_at'
    values << 'CURRENT_TIMESTAMP'
  end
  sql = "insert into #{db_info.table}(#{columns.join(',')}) values(#{values.join(',')})";
  #puts "SQL: #{sql}" 
  db_info.db.query(sql);
end


def get_columns(db, table)
  db.list_fields(table).fetch_fields().map {|f| f.name}
end

コンフィグファイルの例

- module: RSS::load
  config:
    url: http://d.hatena.ne.jp/yuum3/rss/
- module: Filter::grep
  config:
    regex: "\[Award on Rails\]"
- module: mysql_insert
  config:
    database: test
    username: test
    password: 
    table: rss
    additional_data:
      source: yuumi3

PRaggerRSS ParserMySQL/Ruby の勉強になりました ^^)