1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
# -*-ruby; coding: utf-8 -*- vim:set ft=ruby:
# Copyright (C) 2013 Kazuhiro NISHIYAMA
#
# This program is free software with ABSOLUTELY NO WARRANTY.
# You can re-distribute and/or modify this program under
# the same terms of the Ruby's license.
#
=begin
== Configuration:
BotConfig << {
:name => :GithubIssuesBot,
:bot_name => 'gh',
:ch => '#nadoka_check',
:tm => 30, # min
#:nkf => "--oc=CP50221 --ic=UTF-8 --fb-xml",
:owner => "nadoka",
:repo => "nadoka",
}
=end
require 'open-uri'
require 'time'
begin
require 'json'
rescue LoadError
require 'rubygems'
require 'json'
end
module GithubIssues
module_function
DEFAULT_HEADER = {
'User-Agent' => "Nadoka-GithubIssuesBot/0.1",
}
def uri_read(uri, header)
debug = $GITHUB_ISSUES_DEBUG
p uri if debug
uri.open("r", header) do |f|
p f.meta if debug
return f.read
end
rescue OpenURI::HTTPError => e
p e.io.meta if debug
if e.io.meta["x-ratelimit-remaining"] == "0"
raise "#{e}: because x-ratelimit-remaining=0"
end
raise "#{e}: #{uri}"
end
def issues(owner, repo, since, state='open', header=DEFAULT_HEADER)
since = since.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
uri = URI("https://api.github.com/repos/#{owner}/#{repo}/issues?since=#{since}&state=#{state}")
json = uri_read(uri, header)
issues = JSON.parse(json)
issues.each do |issue|
comments_uri = URI("#{issue['comments_url']}?since=#{since}")
json = uri_read(comments_uri, header)
comments = JSON.parse(json)
if comments.empty?
yield [:issue, issue, issue_to_s(issue)]
else
comments.each do |comment|
yield [:comment, comment, comment_to_s(comment, issue)]
end
end
end
end
def user_to_s(user)
return unless user
"@#{user['login']} "
end
def time_to_s(time)
return unless time
time = Time.parse(time)
time.localtime.strftime("%H:%M ")
end
def issue_to_s(issue)
return unless issue
"#{issue['html_url']} [#{issue['state']}] #{time_to_s(issue['updated_at'])}#{user_to_s(issue['user'])}#{issue['title']}"
end
def comment_to_s(comment, issue=nil)
return unless comment
if issue
info = "[#{issue['state']}] "
else
end
"#{comment['html_url']} #{info}#{time_to_s(comment['updated_at'])}#{user_to_s(comment['user'])}#{comment['body']}"
end
end
if __FILE__ == $0
$GITHUB_ISSUES_DEBUG = $DEBUG
owner = "rubima"
repo = "rubima"
since = Time.now - 60*60*3*7
GithubIssues.issues(owner, repo, since) do |_, _, s|
puts s.gsub(/\s+/, ' ')
end
GithubIssues.issues(owner, repo, since, 'close') do |_, _, s|
puts s.gsub(/\s+/, ' ')
end
exit
end
require 'nkf'
class GithubIssuesBot < Nadoka::NDK_Bot
def bot_initialize
@ch = @bot_config.fetch(:ch, '#nadoka_check')
@tm = @bot_config.fetch(:tm, 30) # min
@prevtm = Time.now
@nkf_options = @bot_config.fetch(:nkf, "--oc=CP50221 --ic=UTF-8 --fb-xml")
@owner = @bot_config.fetch(:owner, "nadoka")
@repo = @bot_config.fetch(:repo, "nadoka")
end
def bot_state
nt = Time.at(@prevtm.to_i + @tm * 60)
"<#{self.class}: next check at #{nt.asctime}@#{@ch}>"
end
def send_notice(ch, msg)
msg = msg.gsub(/\s+/, ' ')
if @nkf_options
msg = NKF.nkf(@nkf_options, msg)
end
super(ch, msg)
end
def on_timer tm
check
end
def check
tm = Time.now
if tm.to_i - @tm * 60 > @prevtm.to_i
make_notice tm
end
end
def make_notice tm
since = @prevtm
@prevtm = tm
GithubIssues.issues(@owner, @repo, since) do |_, _, s|
send_notice @ch, s
end
GithubIssues.issues(@owner, @repo, since, 'close') do |_, _, s|
send_notice @ch, s
end
rescue Exception => e
send_notice(@ch, "github issues bot error for #{@owner}/#{@repo}: #{e}")
@manager.ndk_error e
end
end
|