ちょっかん

微妙にもう手を入れる気にならないコードが存在していたがこれがtracのDBからnick一覧を引っ張ってくるというちょう便利なことやってたので記録しておく。
trac wiki には

== kejinan ==
 * keji
 * けじ

== pener ==
 * pener
 * うべ
 * べう

こゆう感じでnickと呼び名の対応が記録してある。

require 'date'
require 'sqlite3'

class Dengon < Chokan::PluginBase
  def initialize(config, chokan)
    super
    @trac_db = @config['trac_db']
    @trac_wiki_page = @config['trac_wiki_page']
    @channels = @config['channels']
    @nicks = []
    @messages = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = [] } }
    load_nicks
  end

  def on_privmsg(prefix, channel, message)
    if @channels.include?(channel)
      case message
      when /.+\s*[>>]\s*(.+)/
        to = Regexp.last_match[1]
        @nicks.each do |nicks|
          if nicks.any? { |nick| to.include?(nick) }
            @messages[channel][to] << {
              :from    => prefix.nick,
              :message => message,
              :date    => DateTime.now,
            }
            notice channel, "でんごんあずかった: #{message}"
            return
          end
        end
      end
    end

    case message
    when 'dengon nicks reload'
      load_nicks
      notice(channel, @nicks.inspect)

    when 'dengon nicks'
      notice(channel, @nicks.inspect)

    #when 'dengon messages'
    #  notice(channel, @messages.inspect)
    end
  end

  def on_join(prefix, channel)
    if @channels.include?(channel)
      @nicks.each do |nicks|
        if nicks.any? { |nick| prefix.nick.include?(nick) }
          nicks.each do |nick|
            until @messages[channel][nick].empty?
              msg = @messages[channel][nick].shift
              notice channel, "#{msg[:date].strftime('%m/%d %X')} #{msg[:from]} #{msg[:message]}"
            end
          end
          return
        end
      end
    end
  end

  def load_nicks
    db = SQLite3::Database.new(@trac_db)
    version = db.get_first_value("select max(version) from wiki where name='#@trac_wiki_page'")
    content = db.get_first_value("select text from wiki where name='#@trac_wiki_page' and version=#{version}")
    @nicks = content.inject([]) do |nicks,line|
      if line =~ /\s*\*\s*(.+)/
        nicks.last << Regexp.last_match[1].chomp
      else
        nicks << []
      end
      nicks
    end.reject { |n| n.empty? }
  end
end