とりあえずPOSTする箇所とかは除いて、コアの部分だけ。
質問はコメントにください。

#!/home/ikemo/local/bin/ruby -Ku

# -*- encoding: utf-8 -*-

require 'net/http'
require 'rexml/document'
require 'timeout'
require 'time'
require 'dbm'
require 'uri'

include REXML

$yoruho = URI.encode("よるほ")
$yoruho_pittari = URI.encode("さんよるほーピッタリ賞です。おめでとうございます。")

user = 'yoruho'
pass = 'password'

def get_yoruho_buzztter(max_id)
  rss = ""
  begin
    res = nil
    now = Time::now
    yoru = Time::local(now.year, now.month, now.day, 0, 0, 0)

    timeout(60, IOError) {
      http = Net::HTTP.new("buzztter.com")
      if max_id then
        res = http.get("/ja/rss/#{$yoruho}?since=#{yoru.to_i}&max_id=#{max_id}",
                      {'User-Agent' => "Ruby/#{RUBY_VERSION}"})
      else
        res = http.get("/ja/rss/#{$yoruho}?since=#{yoru.to_i}",
                      {'User-Agent' => "Ruby/#{RUBY_VERSION}"})
      end
      rss = res.body
    }

    raise IOError if res.code != "200"
  end

  id = nil
  success = []
  doc = Document.new(rss)
  doc.elements.each("/rss/channel/item") {|item|
    title = item.elements["title"].text
    title_regexp = %r|([^:]+): .*|
    title_regexp.match(title)
    name = $1
    time = Time::parse(item.elements["pubDate"].text).localtime
    link = item.elements["link"].text
    link_regexp = %r|http://twitter.com/[^/]+/statuses/(.*)|
    link_regexp.match(link)
    id = $1
    if time.day == Time::now.day && time.hour == 0 && time.min == 0 && time.sec == 0 then
      success.push(name)
    elsif time.day != Time::now.day then
      return success, true, id
    end
  }

  return success, false, id
end

def get_yoruho_official(i)
  rss = ""
  begin
    res = nil

    timeout(60, IOError) {
      http = Net::HTTP.new("search.twitter.com")
      res = http.get("/search.atom?q=#{$yoruho}&page=#{i}&rpp=50",
                    {'User-Agent' => "Ruby/#{RUBY_VERSION}"})
      rss = res.body
    }

    raise IOError if res.code != "200"
  end

  success = []
  doc = Document.new(rss)
  doc.elements.each("//feed/entry") {|entry|
    url = entry.elements["author/uri"].text
    name_regexp = %r|^http://twitter.com/(.*)$|
    name_regexp.match(url)
    name = $1
    time = Time::parse(entry.elements["updated"].text).localtime
    if time.day == Time::now.day && time.hour == 0 && time.min == 0 && time.sec == 0 then
      success.push(name)
    elsif time.day != Time::now.day then
      return success, true
    end
  }

  return success, false
end

def get_yoruho(i)
  rss = ""
  begin
    res = nil

    timeout(60, IOError) {
      http = Net::HTTP.new("pcod.no-ip.org")
      res = http.get("/yats/search?query=#{$yoruho}&page=#{i}&rss",
                    {'User-Agent' => "Ruby/#{RUBY_VERSION}"})
      rss = res.body
    }

    raise IOError if res.code != "200"
  end

  success = []
  doc = Document.new(rss)
  doc.elements.each("//feed/entry") {|entry|
    name = entry.elements["author/name"].text
    time = Time::parse(entry.elements["updated"].text).localtime
    if time.day == Time::now.day && time.hour == 0 && time.min == 0 && time.sec == 0 then
      success.push(name)
    elsif time.day != Time::now.day then
      return success, true
    end
  }

  return success, false
end

def get_yoruho_timeline(max_id)
  xml = ""
  begin
    res = nil

    timeout(60, IOError) {
      path = if max_id != nil then
               "/statuses/friends_timeline.xml?count=200&max_id=#{max_id}"
             else
               "/statuses/friends_timeline.xml?count=200"
             end
      req = Net::HTTP::Get.new(path)
      req.basic_auth "yoruho", "password"

      Net::HTTP.start("twitter.com", 80) {|http|
        res = http.request(req)

        xml = res.body
      }
    }

    raise IOError if res.code != "200"
  end

  success = []
  id = nil
  doc = Document.new(xml)
  doc.elements.each("/statuses/status") {|status|
    screen_name = status.elements["user/screen_name"].text
    time = Time::parse(status.elements["created_at"].text).localtime
    text = status.elements["text"].text
    id = status.elements["id"].text

    if text.include?("よるほ") && time.day == Time::now.day && time.hour == 0 && time.min == 0 && time.sec == 0 then
      success.push(screen_name)
    elsif time.day != Time::now.day then
      return success, true, id
    end
  }

  return success, false, id
end

def post(name, status)
  # ここでTwitterにPOSTする
end

#
# kokokara
#
success_list_timeline = []
max_id = nil
(1..50).each {|i|
  count = 0

  begin
    (success, end_flag, max_id) = get_yoruho_timeline(max_id)
    success_list_timeline += success
    if end_flag == true then
      break
    end
  rescue
    count += 1
    retry if count <= 0
  end
}

success_list_buzztter = []
max_id = nil
[1].each {|i|
  count = 0

  begin
    (success, end_flag, max_id) = get_yoruho_buzztter(max_id)
    success_list_buzztter += success
    if end_flag == true then
      break
    end
  rescue
    count += 1
    retry if count <= 0
  end
}

success_list_pcod = []
(1..0).each {|i|
  count = 0

  begin
    (success, end_flag) = get_yoruho(i)
    success_list_pcod += success
    if end_flag == true then
      break
    end
  rescue
    count += 1
    retry if count <= 0
  end
}

success_list_official = []
(1..50).each {|i|
  count = 0

  begin
    (success, end_flag) = get_yoruho_official(i)
    success_list_official += success
    if end_flag == true then
      break
    end
  rescue
    count += 1
    retry if count <= 0
  end
}

success_list = success_list_timeline | success_list_pcod | success_list_official | success_list_buzztter

db = DBM::open("yoruho")
success_list.each {|name|
  if db[name] == nil then
    db[name] = "1"
  else
    db[name] = (db[name].to_i + 1).to_s
  end
}

success_list.each {|name|
  status = 'status=@' + name + "%20" + $yoruho_pittari + "%20" + db[name] + "%E5%9B%9E%E7%9B%AE%E3%80%82"
  post(name, status)

  # ここで段級の判定

  post(name, words)
}

# ここで人数を出力

One Comment

  1. よるほーbot作りました « From NeXT To Mac says:

    [...] ソースは今度整理して掲載する予定です。→整理してないけど公開しました。 [...]

Leave a Reply