nadoka 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/ndk/server.rb +2 -0
- data/ndk/version.rb +1 -1
- data/plugins/githubissuesbot.nb +141 -0
- data/plugins/googlebot.nb +10 -1
- data/plugins/tenkibot.nb +48 -51
- data/plugins/titlebot.nb +42 -10
- data/plugins/twitterbot.nb +36 -25
- data/rice/irc.rb +2 -2
- metadata +3 -2
data/.gitignore
CHANGED
data/ndk/server.rb
CHANGED
@@ -353,11 +353,13 @@ module Nadoka
|
|
353
353
|
context.cert = OpenSSL::X509::Certificate.new(File.read(@config.client_server_ssl_cert_file))
|
354
354
|
context.key = OpenSSL::PKey::RSA.new(File.read(@config.client_server_ssl_key_file))
|
355
355
|
@cserver = OpenSSL::SSL::SSLServer.new(@cserver, context)
|
356
|
+
@cserver.start_immediately = false
|
356
357
|
end
|
357
358
|
|
358
359
|
while true
|
359
360
|
# wait for client connections
|
360
361
|
Thread.start(@cserver.accept){|cc|
|
362
|
+
cc.accept if OpenSSL::SSL::SSLSocket === cc rescue NameError
|
361
363
|
client = nil
|
362
364
|
begin
|
363
365
|
if !@config.acl_object || @config.acl_object.allow_socket?(cc)
|
data/ndk/version.rb
CHANGED
@@ -0,0 +1,141 @@
|
|
1
|
+
# -*-ruby; coding: utf-8 -*- vim:set ft=ruby:
|
2
|
+
# Copyright (C) 2013 Kazuhiro NISHIYAMA
|
3
|
+
#
|
4
|
+
# This program is free software with ABSOLUTELY NO WARRANTY.
|
5
|
+
# You can re-distribute and/or modify this program under
|
6
|
+
# the same terms of the Ruby's license.
|
7
|
+
#
|
8
|
+
|
9
|
+
=begin
|
10
|
+
|
11
|
+
== Configuration:
|
12
|
+
|
13
|
+
BotConfig << {
|
14
|
+
:name => :GithubIssuesBot,
|
15
|
+
:bot_name => 'gh',
|
16
|
+
:ch => '#nadoka_check',
|
17
|
+
:tm => 30, # min
|
18
|
+
#:nkf => "--oc=CP50221 --ic=UTF-8 --fb-xml",
|
19
|
+
:owner => "nadoka",
|
20
|
+
:repo => "nadoka",
|
21
|
+
}
|
22
|
+
|
23
|
+
=end
|
24
|
+
require 'open-uri'
|
25
|
+
require 'time'
|
26
|
+
begin
|
27
|
+
require 'json'
|
28
|
+
rescue LoadError
|
29
|
+
require 'rubygems'
|
30
|
+
require 'json'
|
31
|
+
end
|
32
|
+
|
33
|
+
module GithubIssues
|
34
|
+
module_function
|
35
|
+
|
36
|
+
def issues(owner, repo, since=nil, state='open')
|
37
|
+
since = since.utc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
38
|
+
uri = URI("https://api.github.com/repos/#{owner}/#{repo}/issues?since=#{since}&state=#{state}")
|
39
|
+
issues = JSON.parse(uri.read)
|
40
|
+
issues.each do |issue|
|
41
|
+
comments_uri = URI("#{issue['comments_url']}?since=#{since}")
|
42
|
+
comments = JSON.parse(comments_uri.read)
|
43
|
+
if comments.empty?
|
44
|
+
yield [:issue, issue, issue_to_s(issue)]
|
45
|
+
else
|
46
|
+
comments.each do |comment|
|
47
|
+
yield [:comment, comment, comment_to_s(comment, issue)]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def user_to_s(user)
|
54
|
+
return unless user
|
55
|
+
"@#{user['login']} "
|
56
|
+
end
|
57
|
+
|
58
|
+
def time_to_s(time)
|
59
|
+
return unless time
|
60
|
+
time = Time.parse(time)
|
61
|
+
time.localtime.strftime("%H:%M ")
|
62
|
+
end
|
63
|
+
|
64
|
+
def issue_to_s(issue)
|
65
|
+
return unless issue
|
66
|
+
"#{issue['html_url']} [#{issue['state']}] #{time_to_s(issue['updated_at'])}#{user_to_s(issue['user'])}#{issue['title']}"
|
67
|
+
end
|
68
|
+
|
69
|
+
def comment_to_s(comment, issue=nil)
|
70
|
+
return unless comment
|
71
|
+
if issue
|
72
|
+
info = "[#{issue['state']}] "
|
73
|
+
else
|
74
|
+
end
|
75
|
+
"#{comment['html_url']} #{info}#{time_to_s(comment['updated_at'])}#{user_to_s(comment['user'])}#{comment['body']}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
if __FILE__ == $0
|
80
|
+
owner = "rubima"
|
81
|
+
repo = "rubima"
|
82
|
+
since = Time.now - 60*60*3
|
83
|
+
GithubIssues.issues(owner, repo, since) do |_, _, s|
|
84
|
+
puts s.gsub(/\s+/, ' ')
|
85
|
+
end
|
86
|
+
GithubIssues.issues(owner, repo, since, 'close') do |_, _, s|
|
87
|
+
puts s.gsub(/\s+/, ' ')
|
88
|
+
end
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
|
92
|
+
require 'nkf'
|
93
|
+
|
94
|
+
class GithubIssuesBot < Nadoka::NDK_Bot
|
95
|
+
def bot_initialize
|
96
|
+
@ch = @bot_config.fetch(:ch, '#nadoka_check')
|
97
|
+
@tm = @bot_config.fetch(:tm, 30) # min
|
98
|
+
@prevtm = Time.now
|
99
|
+
@nkf_options = @bot_config.fetch(:nkf, "--oc=CP50221 --ic=UTF-8 --fb-xml")
|
100
|
+
@owner = @bot_config.fetch(:owner, "nadoka")
|
101
|
+
@repo = @bot_config.fetch(:repo, "nadoka")
|
102
|
+
end
|
103
|
+
|
104
|
+
def bot_state
|
105
|
+
nt = Time.at(@prevtm.to_i + @tm * 60)
|
106
|
+
"<#{self.class}: next check at #{nt.asctime}@#{@ch}>"
|
107
|
+
end
|
108
|
+
|
109
|
+
def send_notice(ch, msg)
|
110
|
+
msg = msg.gsub(/\s+/, ' ')
|
111
|
+
if @nkf_options
|
112
|
+
msg = NKF.nkf(@nkf_options, msg)
|
113
|
+
end
|
114
|
+
super(ch, msg)
|
115
|
+
end
|
116
|
+
|
117
|
+
def on_timer tm
|
118
|
+
check
|
119
|
+
end
|
120
|
+
|
121
|
+
def check
|
122
|
+
tm = Time.now
|
123
|
+
if tm.to_i - @tm * 60 > @prevtm.to_i
|
124
|
+
make_notice tm
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def make_notice tm
|
129
|
+
since = @prevtm
|
130
|
+
@prevtm = tm
|
131
|
+
GithubIssues.issues(@owner, @repo, since) do |_, _, s|
|
132
|
+
send_notice @ch, s
|
133
|
+
end
|
134
|
+
GithubIssues.issues(@owner, @repo, since, 'close') do |_, _, s|
|
135
|
+
send_notice @ch, s
|
136
|
+
end
|
137
|
+
rescue Exception => e
|
138
|
+
send_notice(@ch, "rss bot error: #{e}")
|
139
|
+
@manager.ndk_error e
|
140
|
+
end
|
141
|
+
end
|
data/plugins/googlebot.nb
CHANGED
@@ -182,7 +182,16 @@ class GoogleBot < Nadoka::NDK_Bot
|
|
182
182
|
result.gsub!(/<sup>(.+?)<\/sup>/u) { "^(#{$1})" }
|
183
183
|
result.gsub!(/<.+?>/u, '')
|
184
184
|
result.gsub!(/&\#215;/u, "\303\227")
|
185
|
-
result
|
185
|
+
return result
|
186
|
+
elsif /<[^<>]+ id="cwos"[^<>]*>([^<>]+)</u =~ html
|
187
|
+
result = $1
|
188
|
+
if /<[^<>]+ id="cwles"[^<>]*>([^<>]+)</u =~ html
|
189
|
+
result = "#{$1}#{result}"
|
190
|
+
end
|
191
|
+
#@logger.slog("google_calc>#{result.dump}")
|
192
|
+
result.gsub!(/ /u, " ")
|
193
|
+
result.gsub!(/\s+/, " ")
|
194
|
+
return result
|
186
195
|
else
|
187
196
|
"response error"
|
188
197
|
end
|
data/plugins/tenkibot.nb
CHANGED
@@ -13,18 +13,15 @@
|
|
13
13
|
|
14
14
|
Answer weather information using "Livedoor Weather Web Service / LWWS".
|
15
15
|
|
16
|
-
LWWS: http://weather.livedoor.com/weather_hacks/webservice
|
16
|
+
LWWS: http://weather.livedoor.com/weather_hacks/webservice
|
17
17
|
|
18
18
|
|
19
19
|
== Usage
|
20
20
|
|
21
21
|
tenki> [CITY]
|
22
|
-
tenki:[today|tomorrow|dayaftertomorrow]> [CITY]
|
23
22
|
|
24
23
|
[CITY] should be city name in Kanji listed on following table.
|
25
|
-
http://weather.livedoor.com/forecast/rss/
|
26
|
-
|
27
|
-
If timing is not specified, show today's information.
|
24
|
+
http://weather.livedoor.com/forecast/rss/primary_area.xml
|
28
25
|
|
29
26
|
|
30
27
|
== Configuration
|
@@ -32,7 +29,7 @@ LWWS: http://weather.livedoor.com/weather_hacks/webservice.html
|
|
32
29
|
BotConfig = [
|
33
30
|
{
|
34
31
|
:name => :TenkiBot,
|
35
|
-
:ch => /nadoka/, # default:
|
32
|
+
:ch => /nadoka/, # default: //
|
36
33
|
}
|
37
34
|
]
|
38
35
|
|
@@ -42,62 +39,65 @@ BotConfig = [
|
|
42
39
|
require 'open-uri'
|
43
40
|
require 'pp'
|
44
41
|
require 'kconv'
|
45
|
-
require 'rexml/document'
|
46
42
|
require 'date'
|
43
|
+
begin
|
44
|
+
require 'json'
|
45
|
+
rescue LoadError
|
46
|
+
require 'rubygems'
|
47
|
+
require 'json'
|
48
|
+
end
|
47
49
|
|
48
50
|
module Tenki
|
49
51
|
CityIDs = {}
|
50
52
|
|
51
53
|
def init_tenki
|
52
|
-
open('http://weather.livedoor.com/forecast/rss/
|
53
|
-
f.
|
54
|
+
open('http://weather.livedoor.com/forecast/rss/primary_area.xml') do |f|
|
55
|
+
f.each_line do |line|
|
54
56
|
if /city title="(.+?)" id="(\d+)"/ =~ line
|
55
|
-
CityIDs[$1.toutf8] = $2
|
57
|
+
CityIDs[$1.toutf8] = $2
|
56
58
|
end
|
57
|
-
|
58
|
-
|
59
|
+
end
|
60
|
+
end
|
59
61
|
end
|
60
62
|
|
61
|
-
def tenki
|
62
|
-
|
63
|
-
"http://weather.livedoor.com/forecast/
|
64
|
-
"city=#{CityIDs.fetch(city)}&day=#{timing}"){|f|
|
65
|
-
REXML::Document.new f.read
|
66
|
-
}
|
67
|
-
|
68
|
-
title = doc.elements['/lwws/title/'].text.toutf8
|
69
|
-
telop = doc.elements['/lwws/telop/'].text.toutf8
|
70
|
-
link = doc.elements['/lwws/link/'].text.toutf8
|
71
|
-
desc = doc.elements['/lwws/description/'].text.toutf8
|
72
|
-
max = doc.elements['/lwws/temperature/max/celsius/'].text
|
73
|
-
min = doc.elements['/lwws/temperature/min/celsius/'].text
|
74
|
-
date = Date.parse(doc.elements['/lwws/forecastdate/'].text)
|
75
|
-
datestr = date.strftime('%m/%d')
|
76
|
-
|
77
|
-
desc.sub!(/\.\.\..*/m, '...')
|
78
|
-
|
79
|
-
celsius = []
|
80
|
-
celsius << "max: #{max}" if max
|
81
|
-
celsius << "min: #{min}" if min
|
82
|
-
unless celsius.empty?
|
83
|
-
celsius = "(#{celsius.join(', ')}) "
|
63
|
+
def tenki(city)
|
64
|
+
unless city_id = CityIDs[city]
|
65
|
+
return "Unknown city. Check city title on http://weather.livedoor.com/forecast/rss/primary_area.xml"
|
84
66
|
end
|
85
|
-
|
67
|
+
json = open("http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city_id}") do |f|
|
68
|
+
JSON.parse f.read
|
69
|
+
end
|
70
|
+
|
71
|
+
tenki = "#{json['title']}: "
|
72
|
+
tenki << json['forecasts'].map do |forecast|
|
73
|
+
max = forecast['temperature']['max']
|
74
|
+
min = forecast['temperature']['min']
|
75
|
+
celsius = []
|
76
|
+
celsius << "min:#{min['celsius']}" if min
|
77
|
+
celsius << "max:#{max['celsius']}" if max
|
78
|
+
unless celsius.empty?
|
79
|
+
temperature = "(#{celsius.join(',')})"
|
80
|
+
end
|
81
|
+
"#{forecast['dateLabel']}:#{forecast['telop']}#{temperature}"
|
82
|
+
end.join(', ')
|
83
|
+
desc = json['description']
|
84
|
+
text, = desc['text'].split(/\n\n/, 2)
|
85
|
+
text.gsub!(/\n/, '')
|
86
|
+
tenki << " - #{text}(#{desc['publicTime']})"
|
87
|
+
tenki << " - #{json['link']}"
|
88
|
+
|
89
|
+
tenki
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
89
93
|
if __FILE__ == $0
|
90
94
|
include Tenki
|
91
|
-
|
92
|
-
|
93
|
-
if city.nil?
|
94
|
-
puts "#$0 city [today|tomorrow|dayaftertomorrow]"
|
95
|
+
if ARGV.empty?
|
96
|
+
puts "#$0 city"
|
95
97
|
else
|
96
98
|
init_tenki
|
97
|
-
|
98
|
-
puts tenki(city
|
99
|
-
rescue IndexError
|
100
|
-
puts "Unknown city. Check city title on http://weather.livedoor.com/forecast/rss/forecastmap.xml"
|
99
|
+
ARGV.each do |city|
|
100
|
+
puts tenki(city)
|
101
101
|
end
|
102
102
|
end
|
103
103
|
exit
|
@@ -116,17 +116,14 @@ class TenkiBot < Nadoka::NDK_Bot
|
|
116
116
|
return unless @available_channel === ch
|
117
117
|
return if same_bot?(ch)
|
118
118
|
msg = NKF.nkf('-w', msg)
|
119
|
-
if /\Atenki
|
120
|
-
city = $
|
121
|
-
timing = ($2 || 'today').strip
|
119
|
+
if /\Atenki>/ =~ msg
|
120
|
+
city = $'.strip.toutf8
|
122
121
|
begin
|
123
|
-
result = tenki(city
|
124
|
-
rescue IndexError
|
125
|
-
result = "Unknown city. Check city title on http://weather.livedoor.com/forecast/rss/forecastmap.xml"
|
122
|
+
result = tenki(city)
|
126
123
|
rescue => e
|
127
124
|
result = "#{e}"
|
128
125
|
end
|
129
|
-
send_notice ch, NKF.nkf(@nkf, "tenki bot: #{result}")
|
126
|
+
send_notice ch, NKF.nkf(@nkf, "tenki bot: #{result}".gsub(/\s+/, ' '))
|
130
127
|
end
|
131
128
|
end
|
132
129
|
end
|
data/plugins/titlebot.nb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# -*-ruby-*-
|
1
|
+
# -*-ruby; coding: utf-8 -*-
|
2
2
|
# vim:set ft=ruby:
|
3
3
|
#
|
4
4
|
# Copyright (c) 2009, 2011, 2012 Kazuhiro NISHIYAMA
|
@@ -33,6 +33,12 @@ require 'open-uri'
|
|
33
33
|
require 'timeout'
|
34
34
|
require 'tmpdir'
|
35
35
|
|
36
|
+
begin
|
37
|
+
require 'cgi/util'
|
38
|
+
rescue LoadError
|
39
|
+
require 'cgi'
|
40
|
+
end
|
41
|
+
|
36
42
|
begin
|
37
43
|
require 'rubygems'
|
38
44
|
require 'nokogiri'
|
@@ -92,10 +98,10 @@ module URL2Title
|
|
92
98
|
when /euc-jp/i # euc-jp, x-euc-jp
|
93
99
|
charset = "eucjp-ms"
|
94
100
|
end
|
95
|
-
if /\
|
101
|
+
if /\A(?:utf-8|eucjp-ms)\z/i =~ charset
|
96
102
|
# avoid #<ArgumentError: invalid byte sequence in UTF-8>
|
97
103
|
# or Iconv::IllegalSequence
|
98
|
-
body = NKF.nkf("-
|
104
|
+
body = NKF.nkf("-wm0x --ic=#{charset}", body)
|
99
105
|
elsif charset
|
100
106
|
charset.sub!(/\Ax-?/i, '')
|
101
107
|
begin
|
@@ -127,20 +133,33 @@ module URL2Title
|
|
127
133
|
title = tweet unless tweet.empty?
|
128
134
|
end
|
129
135
|
end
|
130
|
-
|
136
|
+
else
|
131
137
|
if %r"<title\b(?>[^<>]*)>(.*?)</title(?>[^<>]*)>"miu =~ body
|
132
138
|
title = $1
|
133
139
|
end
|
134
|
-
if
|
140
|
+
if defined?(::Nokogiri)
|
141
|
+
doc ||= Nokogiri::HTML(body, uri.to_s, 'utf-8')
|
142
|
+
og_title = doc.xpath("//meta[@property='og:title'][1]/@content")
|
143
|
+
unless og_title.empty?
|
144
|
+
# title is escaped string when get by regexp
|
145
|
+
title = CGI.escapeHTML(og_title.text)
|
146
|
+
end
|
147
|
+
elsif /<meta property="og:title" content="(.+?)">/ =~ body
|
135
148
|
title = $1
|
136
149
|
end
|
137
|
-
|
138
|
-
|
150
|
+
if defined?(::Nokogiri)
|
151
|
+
doc ||= Nokogiri::HTML(body, uri.to_s, 'utf-8')
|
152
|
+
og_title = doc.xpath("//meta[@property='og:title']/@content")
|
153
|
+
unless og_title.empty?
|
154
|
+
# title is escaped string when get by regexp
|
155
|
+
title = CGI.escapeHTML(og_title.text)
|
156
|
+
end
|
157
|
+
elsif /<meta property="og:title" content="(.+?)">/ =~ body
|
139
158
|
title = $1
|
140
159
|
end
|
141
160
|
if uri.fragment && defined?(::Nokogiri)
|
142
161
|
begin
|
143
|
-
doc
|
162
|
+
doc ||= Nokogiri::HTML(body, uri.to_s, 'utf-8')
|
144
163
|
xpath = "//*[@id='#{uri.fragment}' or @name='#{uri.fragment}']"
|
145
164
|
fragment_element = doc.xpath(xpath)
|
146
165
|
# tDiary style
|
@@ -153,6 +172,19 @@ module URL2Title
|
|
153
172
|
end
|
154
173
|
end
|
155
174
|
end
|
175
|
+
if defined?(::Nokogiri)
|
176
|
+
doc ||= Nokogiri::HTML(body, uri.to_s, 'utf-8')
|
177
|
+
canonical_uri = doc.xpath("//link[@rel='canonical'][1]/@href")
|
178
|
+
unless canonical_uri.empty?
|
179
|
+
info[:uri] = URI(canonical_uri.text)
|
180
|
+
end
|
181
|
+
elsif /<link rel="canonical" href="(.+?)"/i =~ body
|
182
|
+
info[:uri] = URI(CGI.unescapeHTML($1))
|
183
|
+
end
|
184
|
+
if title
|
185
|
+
title = CGI.unescapeHTML(title)
|
186
|
+
title.gsub!(/\xE3\x80\x9C/u, "\xEF\xBD\x9E") # WAVE DASH -> FULLWIDTH TILDE
|
187
|
+
end
|
156
188
|
info[:title] = title || body
|
157
189
|
return info
|
158
190
|
when /\Aimage\//
|
@@ -211,7 +243,7 @@ if __FILE__ == $0
|
|
211
243
|
ARGV.each do |url|
|
212
244
|
info = u2t(url)
|
213
245
|
p info
|
214
|
-
puts
|
246
|
+
puts info[:uri]
|
215
247
|
puts info[:title]
|
216
248
|
end
|
217
249
|
end
|
@@ -232,7 +264,7 @@ class TitleBot < Nadoka::NDK_Bot
|
|
232
264
|
end
|
233
265
|
|
234
266
|
@same_bot = @bot_config.fetch(:same_bot, /(?!)/)
|
235
|
-
@nkf_options = @bot_config.fetch(:nkf, "--oc=CP50221 --ic=UTF-8 --
|
267
|
+
@nkf_options = @bot_config.fetch(:nkf, "--oc=CP50221 --ic=UTF-8 --fb-xml")
|
236
268
|
@timeout = @bot_config.fetch(:timeout, 10)
|
237
269
|
@fragment_size_range = @bot_config.fetch(:fragment_size_range, 5..100)
|
238
270
|
@headers = @bot_config.fetch(:headers, {})
|
data/plugins/twitterbot.nb
CHANGED
@@ -95,39 +95,50 @@ class TwitterBot < Nadoka::NDK_Bot
|
|
95
95
|
end
|
96
96
|
|
97
97
|
@streamer = Thread.new do
|
98
|
-
|
99
|
-
|
100
|
-
when status[:delete]
|
101
|
-
when status[:scrub_geo]
|
102
|
-
when status[:limit]
|
103
|
-
when status[:status_withheld]
|
104
|
-
when status[:user_withheld]
|
105
|
-
when status[:friends]
|
106
|
-
when status[:event]
|
107
|
-
when status[:for_user]
|
108
|
-
when status[:control]
|
109
|
-
when status[:warning]
|
110
|
-
screen_name = status[:code]
|
111
|
-
time = Time.parse(status[:created_at])
|
112
|
-
send_notice @ch, "#{time.strftime('%H:%M')} #{screen_name}: #{status.text}"
|
113
|
-
else
|
98
|
+
loop do
|
99
|
+
UserStream.client.user do |status|
|
114
100
|
begin
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
101
|
+
case # https://dev.twitter.com/docs/streaming-apis/messages
|
102
|
+
#when status[:delete]
|
103
|
+
#when status[:scrub_geo]
|
104
|
+
when status[:limit]
|
105
|
+
when status[:status_withheld]
|
106
|
+
when status[:user_withheld]
|
107
|
+
when status[:friends]
|
108
|
+
when status[:event]
|
109
|
+
when status[:for_user]
|
110
|
+
when status[:control]
|
111
|
+
when status[:warning]
|
112
|
+
screen_name = status[:code]
|
113
|
+
time = Time.parse(status[:created_at])
|
114
|
+
send_notice @ch, "#{time.strftime('%H:%M')} #{screen_name}: #{status.text}"
|
115
|
+
when status[:user]
|
116
|
+
screen_name = status[:user][:screen_name]
|
117
|
+
if status[:retweeted_status]
|
118
|
+
status = status[:retweeted_status]
|
119
|
+
screen_name << ":"
|
120
|
+
screen_name << status[:user][:screen_name]
|
121
|
+
end
|
122
|
+
time = Time.parse(status[:created_at])
|
123
|
+
text = status.text
|
124
|
+
text.tr!("\r\n", ' ')
|
125
|
+
text.gsub!(/</, '<')
|
126
|
+
text.gsub!(/>/, '>')
|
127
|
+
text.gsub!(/"/, '"')
|
128
|
+
text = NKF.nkf('--numchar-input --ic=UTF-8 --oc=' + @nkf_encoding, text) if @nkf_encoding
|
129
|
+
text.gsub!(/&/, '&')
|
130
|
+
send_notice @ch, "#{time.strftime('%H:%M')} #{screen_name}: #{text}"
|
131
|
+
else
|
132
|
+
send_notice @ch, status.inspect
|
120
133
|
end
|
121
|
-
time = Time.parse(status[:created_at])
|
122
|
-
text = status.text.tr("\r\n", ' ')
|
123
|
-
text = NKF.nkf('--ic=UTF-8 --oc=' + @nkf_encoding, text) if @nkf_encoding
|
124
|
-
send_notice @ch, "#{time.strftime('%H:%M')} #{screen_name}: #{text}"
|
125
134
|
rescue => e
|
135
|
+
@logger.slog e.inspect
|
126
136
|
slog e.backtrace
|
127
137
|
slog e.inspect
|
128
138
|
slog status.inspect
|
129
139
|
end
|
130
140
|
end
|
141
|
+
@logger.slog "user stream finished...and restart"
|
131
142
|
end
|
132
143
|
end
|
133
144
|
end
|
data/rice/irc.rb
CHANGED
@@ -300,7 +300,7 @@ module RICE
|
|
300
300
|
|
301
301
|
rescue Closed
|
302
302
|
begin
|
303
|
-
@main_th.run if
|
303
|
+
@main_th.run if alive?
|
304
304
|
rescue Closed
|
305
305
|
end
|
306
306
|
retry
|
@@ -317,7 +317,7 @@ module RICE
|
|
317
317
|
def close(restart = false)
|
318
318
|
begin
|
319
319
|
unless restart
|
320
|
-
@main_th.exit if
|
320
|
+
@main_th.exit if alive?
|
321
321
|
@read_th.exit if @read_th.alive?
|
322
322
|
end
|
323
323
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nadoka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-04-29 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: Nadoka is a tool for monitoring and logging IRC conversations and responding
|
16
16
|
to specially formatted requests. You define and customize these responses in Ruby.
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- plugins/drbcl.rb
|
53
53
|
- plugins/drbot.nb
|
54
54
|
- plugins/evalbot.nb
|
55
|
+
- plugins/githubissuesbot.nb
|
55
56
|
- plugins/gonzuibot.nb
|
56
57
|
- plugins/googlebot.nb
|
57
58
|
- plugins/identifynickserv.nb
|