開発版ふぁぼDB

まだ開発版ですよ
※この記事とコード部分は予告なく変更される可能性があります.

# -*- coding: utf-8 -*-
require 'sqlite3'

$dbfile = '../plugin/tweets.db'
existsFile = File.exists?($dbfile)
db = SQLite3::Database.new($dbfile)
existsTable = db.execute('select * from sqlite_master').size == 1

if !existsFile or !existsTable then
  db.execute('create table tweets (idname, tweetid, tweet, faved)')
end

db.close()

Plugin.create(:tweetdb) do

  onupdate do |service, messages|
    messages.each{ |m|
      if !m.system? then
        db = SQLite3::Database.new($dbfile)
        if db.execute("select * from tweets where tweetid = #{m.id.to_s}").size == 0 then
          sql = "insert into tweets values (\'#{m.idname}\',#{m.id.to_s},\'\',\'#{m.favorite?}\')"
          db.execute(sql)
        end
        db.close()
      end
    }
  end

  on_favorite do |service, by, to|
    db = SQLite3::Database.new($dbfile)
    db.execute("update tweets set faved = \'true\' where tweetid = #{to.id}")
    db.close()
  end

  onmention do |post, raw_messages|
    messages = Plugin.filtering(:show_filter, raw_messages.select{ |m| not(m[:retweet]) and m[:created] > DEFINED_TIME }).first
    username = Post.primary_service.user.to_s
    messages.each{ |m|
      if (/@#{username} favall [a-zA-Z0-9_]+ [0-9]+/ =~ m.to_s) != nil then
        arg = m.to_s['@#{username} favall '.size..-1]
        pos = / / =~ arg
        target = arg[0..pos-1]
        num = arg[pos+1..-1].to_i
        if num > 50 then
          num = 50
        end
        if target != username then
          favall(target, num)
        end
      end
    }
  end

  def self.createSystemMessage(message)
    Plugin.call(:update, nil, [Message.new(:message => "#{message}", :system => true)])
  end

  def self.count(idname, faved = false)
    Thread.new{
      db = SQLite3::Database.new($dbfile)
      list = db.execute("select count(tweetid) from tweets where idname = \'#{idname}\' and faved = \'#{faved}\'")
      db.close()
      if faved == false then
        createSystemMessage("favable count of @#{idname}: #{list[0][0]}")
      else
        createSystemMessage("unfavable count of @#{idname}: #{list[0][0]}")
      end
    }
  end

  def self.favsingle(tweetid)
    Post.primary_service.twitter.favorite(tweetid).code == '200'
  end
  
  def self.favall(idname, limit, unofficial = false, delay = 700)
    Thread.new{
      db = SQLite3::Database.new($dbfile)
      list = db.execute("select tweetid from tweets where idname = \'#{idname}\' and faved = \'false\' order by tweetid desc limit #{limit}")
      if unofficial == false then
        Post.primary_service.update(:message => "fav targets of @#{idname}: #{list.size}")
        list.each{ |t|
          if Post.primary_service.twitter.favorite(t[0]).code == '200' then
            db.execute("update tweets set faved = \'true\' where tweetid = #{t[0]}")
          end
          sleep((delay + rand(1500)) / 1000.0)
        }
        db.close()
      else
        Post.primary_service.update(:message => "unofficial fav targets of @#{idname}: #{list.size}")
        list.each{ |t|
          Post.primary_service.update(:message => "@#{idname}#{" " * (t[0] % 15)}")
        }
      end        
    }
  end

  def self.unfavall(idname, limit)
    Thread.new{
      db = SQLite3::Database.new($dbfile)
      list = db.execute("select tweetid from tweets where idname = \'#{idname}\' and faved = \'true\' order by tweetid desc limit #{limit}")
      Post.primary_service.update(:message => "unfav targets of @#{idname}: #{list.size}")
      list.each{ |t|
        if Post.primary_service.twitter.unfavorite(t[0]).code == '200' then
          db.execute("update tweets set faved = \'false\' where tweetid = #{t[0]}")
        end
      }
      db.close()
    }
  end

  def self.unfavfavall(idname, limit)
    Thread.new{
      unfavall(idname, limit)
      favall(idname, limit)
    }
  end

  def self.callSQL(state, function)
    Thread.new{
      db = SQLite3::Database.new($dbfile)
      result = db.execute(state)
      db.close
      createSystemMessage("#{state} => #{result}")
      if function != nil then
        result.each{ |res|
          function.call(res)
        }
      end
    }
  end

  def self.ranking(limit = 10)
    Thread.new{
      db = SQLite3::Database.new($dbfile)
      result = db.execute("select idname, count(tweetid) from tweets where faved = 'false' group by idname order by count(tweetid) desc limit #{limit}")
      db.close
      msg = "favable ranking top #{limit}"
      result.each{ |r|
        msg += "@#{r[0]}\t#{r[1]}\n"
      }
      createSystemMessage(msg)
    }
  end
   
   
  add_event_filter(:command){ |menu|
    menu[:favable_count] = {
      :slug => :favable_count,
      :name => 'ふぁぼって登録',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| count(Gtk::TimeLine.get_active_mumbles[0][:user].to_s, false) },
      :visible => true,
      :role => :message }
    [menu]
  }
  add_event_filter(:command){ |menu|
    menu[:favable_count] = {
      :slug => :favable_count,
      :name => 'いくつふぁぼれるか数える',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| count(Gtk::TimeLine.get_active_mumbles[0][:user].to_s, false) },
      :visible => true,
      :role => :message }
    [menu]
  }
  add_event_filter(:command){ |menu|
    menu[:unfavable_count] = {
      :slug => :unfavable_count,
      :name => 'いくつunfavできるか数える',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| count(Gtk::TimeLine.get_active_mumbles[0][:user].to_s, true) },
      :visible => true,
      :role => :message }
    [menu]
  }
  add_event_filter(:command){ |menu|
    menu[:favorite_all] = {
      :slug => :favorite_all,
      :name => '愛のふぁぼを贈る',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| favall(Gtk::TimeLine.get_active_mumbles[0][:user].to_s, 100) },
      :visible => true,
      :role => :message }
    [menu]
  }
  add_event_filter(:command){ |menu|
    menu[:unfavorite_all] = {
      :slug => :unfavorite_all,
      :name => '愛の鞭でふぁぼを取り消す',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| unfavall(Gtk::TimeLine.get_active_mumbles[0][:user].to_s, 100) },
      :visible => true,
      :role => :message }
    [menu]
  }
  add_event_filter(:command){ |menu|
    menu[:show_ranking] = {
      :slug => :show_ranking,
      :name => 'ふぁぼれるランキングを表示',
      :condition => lambda{ |m| m.message.repliable? },
      :exec => lambda{ |m| ranking(10) },
      :visible => true,
      :role => :message }
    [menu]
  }

end