nadoka 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/{ChangeLog.old → doc/ChangeLog.old} +0 -0
- data/lib/rss_check.rb +12 -0
- data/nadokarc +9 -0
- data/ndk/config.rb +7 -5
- data/ndk/logger.rb +1 -1
- data/ndk/server.rb +13 -1
- data/ndk/server_state.rb +1 -1
- data/ndk/version.rb +2 -2
- data/plugins/codesearchbot.nb +75 -0
- data/plugins/titlebot.nb +25 -23
- data/plugins/twitterbot.nb +50 -18
- data/rice/irc.rb +4 -2
- metadata +4 -3
|
File without changes
|
data/lib/rss_check.rb
CHANGED
|
@@ -148,20 +148,30 @@ class RSS_Check
|
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
def save
|
|
151
|
+
debug = $DEBUG
|
|
152
|
+
$DEBUG = false
|
|
151
153
|
@db.transaction{
|
|
152
154
|
@paths.each_with_index{|path, i|
|
|
153
155
|
@db[path] = @rss_files[i]
|
|
154
156
|
}
|
|
155
157
|
} if @db
|
|
158
|
+
ensure
|
|
159
|
+
$DEBUG = debug
|
|
156
160
|
end
|
|
157
161
|
|
|
158
162
|
def load_file file
|
|
163
|
+
debug = $DEBUG
|
|
164
|
+
$DEBUG = false
|
|
159
165
|
@db.transaction{
|
|
160
166
|
@db[file]
|
|
161
167
|
} if @db
|
|
168
|
+
ensure
|
|
169
|
+
$DEBUG = debug
|
|
162
170
|
end
|
|
163
171
|
|
|
164
172
|
def clear
|
|
173
|
+
debug = $DEBUG
|
|
174
|
+
$DEBUG = false
|
|
165
175
|
if @db
|
|
166
176
|
@db.transaction{
|
|
167
177
|
@db.keys.each{|k|
|
|
@@ -169,6 +179,8 @@ class RSS_Check
|
|
|
169
179
|
}
|
|
170
180
|
}
|
|
171
181
|
end
|
|
182
|
+
ensure
|
|
183
|
+
$DEBUG = debug
|
|
172
184
|
end
|
|
173
185
|
end
|
|
174
186
|
|
data/nadokarc
CHANGED
|
@@ -36,6 +36,8 @@ class NADOKA_Config < Nadoka::NDK_ConfigBase
|
|
|
36
36
|
Client_server_host = nil # You can specify binding host(interface)
|
|
37
37
|
Client_server_pass = 'NadokaPassWord'
|
|
38
38
|
Client_server_acl = nil
|
|
39
|
+
Client_server_ssl_cert_file = nil
|
|
40
|
+
Client_server_ssl_key_file = nil
|
|
39
41
|
|
|
40
42
|
# ACL(Access Control List) example:
|
|
41
43
|
# Client_server_acl = %q{
|
|
@@ -47,13 +49,20 @@ class NADOKA_Config < Nadoka::NDK_ConfigBase
|
|
|
47
49
|
# or you can set acl directly like follows:
|
|
48
50
|
#
|
|
49
51
|
# ACL_Object = ::ACL.new(...)
|
|
52
|
+
|
|
53
|
+
# Create a self-signed SSL certificate:
|
|
54
|
+
# $ openssl req -new -days 365 -x509 -nodes -out cert.pem -keyout key.pem
|
|
50
55
|
#
|
|
56
|
+
# And specify cert files:
|
|
57
|
+
# Client_server_ssl_cert_file = 'cert.pem'
|
|
58
|
+
# Client_server_ssl_key_file = 'key.pem'
|
|
51
59
|
|
|
52
60
|
|
|
53
61
|
###############################################
|
|
54
62
|
# server setting
|
|
55
63
|
|
|
56
64
|
# IRCnet servers in Japan
|
|
65
|
+
# see http://www.ircnet.ne.jp/servers.html
|
|
57
66
|
Servers = [
|
|
58
67
|
{ :host => 'irc.ircnet.ne.jp',
|
|
59
68
|
:port => 6667, # default: 6667
|
data/ndk/config.rb
CHANGED
|
@@ -34,6 +34,8 @@ module Nadoka
|
|
|
34
34
|
Client_server_host = nil
|
|
35
35
|
Client_server_pass = 'NadokaPassWord' # or nil
|
|
36
36
|
Client_server_acl = nil
|
|
37
|
+
Client_server_ssl_cert_file = nil
|
|
38
|
+
Client_server_ssl_key_file = nil
|
|
37
39
|
ACL_Object = nil
|
|
38
40
|
|
|
39
41
|
#
|
|
@@ -179,13 +181,13 @@ module Nadoka
|
|
|
179
181
|
|
|
180
182
|
def remove_previous_setting
|
|
181
183
|
# remove setting class
|
|
182
|
-
|
|
183
|
-
while
|
|
184
|
+
base_klass = ConfigClass.shift
|
|
185
|
+
while klass = ConfigClass.shift
|
|
184
186
|
Object.module_eval{
|
|
185
|
-
remove_const(
|
|
187
|
+
remove_const(klass.name)
|
|
186
188
|
}
|
|
187
189
|
end
|
|
188
|
-
ConfigClass.push(
|
|
190
|
+
ConfigClass.push(base_klass)
|
|
189
191
|
|
|
190
192
|
|
|
191
193
|
# clear required files
|
|
@@ -412,7 +414,7 @@ module Nadoka
|
|
|
412
414
|
end
|
|
413
415
|
|
|
414
416
|
def canonical_channel_name ch
|
|
415
|
-
ch = ch.sub(/^\!.{5}/, '!')
|
|
417
|
+
ch = ch.toeuc.sub(/^\!.{5}/, '!')
|
|
416
418
|
identical_channel_name ch
|
|
417
419
|
end
|
|
418
420
|
|
data/ndk/logger.rb
CHANGED
|
@@ -241,7 +241,7 @@ module Nadoka
|
|
|
241
241
|
def logging msg
|
|
242
242
|
user = @manager.nick_of(msg)
|
|
243
243
|
rch = msg.params[0]
|
|
244
|
-
|
|
244
|
+
ch = @config.canonical_channel_name(rch)
|
|
245
245
|
|
|
246
246
|
msgobj = make_msgobj(msg)
|
|
247
247
|
msgobj[:ch] = rch # should be raw
|
data/ndk/server.rb
CHANGED
|
@@ -15,6 +15,10 @@ require 'ndk/error'
|
|
|
15
15
|
require 'ndk/config'
|
|
16
16
|
require 'ndk/server_state'
|
|
17
17
|
require 'ndk/client'
|
|
18
|
+
begin
|
|
19
|
+
require 'openssl'
|
|
20
|
+
rescue LoadError
|
|
21
|
+
end
|
|
18
22
|
|
|
19
23
|
module Nadoka
|
|
20
24
|
Cmd = ::RICE::Command
|
|
@@ -163,8 +167,9 @@ module Nadoka
|
|
|
163
167
|
case q.command
|
|
164
168
|
when '001'
|
|
165
169
|
break
|
|
166
|
-
when '433'
|
|
170
|
+
when '433', '437'
|
|
167
171
|
# Nickname is already in use.
|
|
172
|
+
# 437 Nick/channel is temporarily unavailable
|
|
168
173
|
nick = @state.nick_succ(q.params[1])
|
|
169
174
|
@state.nick = nick
|
|
170
175
|
send_to_server Cmd.nick(nick)
|
|
@@ -343,6 +348,13 @@ module Nadoka
|
|
|
343
348
|
@config.client_server_port)
|
|
344
349
|
@logger.slog "Open Client Server Port: #{@cserver.addr.join(' ')}"
|
|
345
350
|
|
|
351
|
+
if @config.client_server_ssl_cert_file && @config.client_server_ssl_key_file
|
|
352
|
+
context = OpenSSL::SSL::SSLContext.new
|
|
353
|
+
context.cert = OpenSSL::X509::Certificate.new(File.read(@config.client_server_ssl_cert_file))
|
|
354
|
+
context.key = OpenSSL::PKey::RSA.new(File.read(@config.client_server_ssl_key_file))
|
|
355
|
+
@cserver = OpenSSL::SSL::SSLServer.new(@cserver, context)
|
|
356
|
+
end
|
|
357
|
+
|
|
346
358
|
while true
|
|
347
359
|
# wait for client connections
|
|
348
360
|
Thread.start(@cserver.accept){|cc|
|
data/ndk/server_state.rb
CHANGED
|
@@ -195,7 +195,7 @@ module Nadoka
|
|
|
195
195
|
def on_join user, rch
|
|
196
196
|
ch = canonical_channel_name(rch)
|
|
197
197
|
if user == nick
|
|
198
|
-
|
|
198
|
+
@current_channels[ch] = ChannelState.new(rch)
|
|
199
199
|
else
|
|
200
200
|
if @current_channels.has_key? ch
|
|
201
201
|
@current_channels[ch].on_join(user)
|
data/ndk/version.rb
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#
|
|
12
12
|
|
|
13
13
|
module Nadoka
|
|
14
|
-
VERSION = '0.8.
|
|
14
|
+
VERSION = '0.8.3'
|
|
15
15
|
NDK_Version = VERSION.dup
|
|
16
16
|
NDK_Created = Time.now
|
|
17
17
|
|
|
@@ -33,7 +33,7 @@ module Nadoka
|
|
|
33
33
|
$LOAD_PATH.each{|path|
|
|
34
34
|
path = path + '/ChangeLog'
|
|
35
35
|
if FileTest.exist?(path)
|
|
36
|
-
if /^\# ChangeLog of Nadoka\(\$Rev: (\d+) \$\)$/ =~ open(path){|f|
|
|
36
|
+
if /^\# ChangeLog of Nadoka\(\$Rev: (\d+) \$\)$/ =~ open(path){|f| f.gets}
|
|
37
37
|
rev = "rev: #{$1}"
|
|
38
38
|
break
|
|
39
39
|
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# -*-ruby; coding: utf-8 -*- vim:set ft=ruby:
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2012 Kazuhiro NISHIYAMA
|
|
4
|
+
#
|
|
5
|
+
# This program is free software with ABSOLUTELY NO WARRANTY.
|
|
6
|
+
# You can re-distribute and/or modify this program under
|
|
7
|
+
# the same terms of the Ruby's license.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'open-uri'
|
|
11
|
+
require 'uri'
|
|
12
|
+
require 'nkf'
|
|
13
|
+
|
|
14
|
+
module CodeSearch
|
|
15
|
+
ResultRegexp = /number of (regexp results: \d+)<br>\s*number of (source results: \d+)/
|
|
16
|
+
|
|
17
|
+
# https://code.google.com/p/codesearch/
|
|
18
|
+
EngineURI = {
|
|
19
|
+
'debian' => 'http://codesearch.debian.net/',
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
def codesearch_result engine, key
|
|
23
|
+
engine ||= 'debian'
|
|
24
|
+
key_uri = URI.encode(NKF.nkf('-w', key))
|
|
25
|
+
engine_uri = EngineURI[engine.downcase]
|
|
26
|
+
return "unknown engine: #{engine}" unless engine_uri
|
|
27
|
+
|
|
28
|
+
url = "#{engine_uri}search?q=#{key_uri}"
|
|
29
|
+
open(url){|f|
|
|
30
|
+
result = f.read
|
|
31
|
+
if ResultRegexp =~ result
|
|
32
|
+
"#{$~.captures.join(', ')} for #{key} - #{url}"
|
|
33
|
+
else
|
|
34
|
+
"#{key} - not found in #{engine} codesearch"
|
|
35
|
+
end
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if __FILE__ == $0
|
|
41
|
+
if ARGV.empty?
|
|
42
|
+
abort("usage: #{$0} keyword")
|
|
43
|
+
end
|
|
44
|
+
include CodeSearch
|
|
45
|
+
puts codesearch_result('debian', ARGV.join(' '))
|
|
46
|
+
exit
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class CodeSearchBot < Nadoka::NDK_Bot
|
|
50
|
+
include CodeSearch
|
|
51
|
+
|
|
52
|
+
def bot_initialize
|
|
53
|
+
if @bot_config.key?(:channels)
|
|
54
|
+
channels = '\A(?:' + @bot_config[:channels].collect{|ch|
|
|
55
|
+
Regexp.quote(ch)
|
|
56
|
+
}.join('|') + ')\z'
|
|
57
|
+
@available_channel = Regexp.compile(channels)
|
|
58
|
+
else
|
|
59
|
+
@available_channel = @bot_config[:ch] || //
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@bot_name = @bot_config[:bot_name] || 'CodeSearchBot'
|
|
63
|
+
@open_search = OpenSearch.new(@bot_config)
|
|
64
|
+
@ch_kcode = @bot_config[:ch_kcode]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def on_privmsg prefix, ch, msg
|
|
68
|
+
return unless /\Acodesearch(\:([a-z]+))?>\s*(.+)/ =~ msg
|
|
69
|
+
msg = "codesearch#$1 bot: #{codesearch_result($2, $3.toutf8)}"
|
|
70
|
+
if @ch_kcode == :jis
|
|
71
|
+
msg = msg.tojis
|
|
72
|
+
end
|
|
73
|
+
send_notice ch, msg
|
|
74
|
+
end
|
|
75
|
+
end
|
data/plugins/titlebot.nb
CHANGED
|
@@ -81,32 +81,34 @@ module URL2Title
|
|
|
81
81
|
|
|
82
82
|
|
|
83
83
|
# encoding
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
if charset
|
|
85
|
+
# ok
|
|
86
|
+
elsif /charset=[\'\"]?([^;\'\">]+)/ni =~ body
|
|
87
|
+
charset = $1
|
|
88
|
+
end
|
|
89
|
+
case charset
|
|
90
|
+
when /shift_jis/i
|
|
91
|
+
charset = "cp932"
|
|
92
|
+
when /euc-jp/i # euc-jp, x-euc-jp
|
|
93
|
+
charset = "eucjp-ms"
|
|
94
|
+
end
|
|
95
|
+
if /\Autf-8\z/i =~ charset
|
|
96
|
+
# avoid #<ArgumentError: invalid byte sequence in UTF-8>
|
|
97
|
+
# or Iconv::IllegalSequence
|
|
98
|
+
body = NKF.nkf("-Wwm0x", body)
|
|
99
|
+
elsif charset
|
|
100
|
+
charset.sub!(/\Ax-?/i, '')
|
|
101
|
+
begin
|
|
102
102
|
body = Iconv.conv("utf-8", charset, body)
|
|
103
|
-
|
|
103
|
+
rescue Iconv::IllegalSequence => e
|
|
104
|
+
info[:errors] << e
|
|
105
|
+
body = NKF.nkf("-wm0x", body)
|
|
106
|
+
rescue Iconv::InvalidEncoding => e
|
|
107
|
+
info[:errors] << e
|
|
104
108
|
body = NKF.nkf("-wm0x", body)
|
|
105
109
|
end
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
rescue Iconv::InvalidEncoding => e
|
|
109
|
-
info[:errors] << e
|
|
110
|
+
else
|
|
111
|
+
body = NKF.nkf("-wm0x", body)
|
|
110
112
|
end
|
|
111
113
|
|
|
112
114
|
title = nil
|
data/plugins/twitterbot.nb
CHANGED
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
#
|
|
45
45
|
require 'time'
|
|
46
46
|
require 'rubygems'
|
|
47
|
+
require 'user_stream'
|
|
47
48
|
require 'rubytter'
|
|
48
49
|
require 'json'
|
|
49
50
|
|
|
@@ -85,22 +86,56 @@ class TwitterBot < Nadoka::NDK_Bot
|
|
|
85
86
|
@bot_config.fetch(:access_token_secret, nil))
|
|
86
87
|
@rt = OAuthRubytter.new(access_token)
|
|
87
88
|
@current_id = -1
|
|
88
|
-
end
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
time = Time.parse(status.created_at)
|
|
96
|
-
next if time + 5 * 60 < Time.now
|
|
97
|
-
text = status.text.tr("\r\n", ' ')
|
|
98
|
-
text = NKF.nkf('--ic=UTF-8 --oc=' + @nkf_encoding, text) if @nkf_encoding
|
|
99
|
-
send_notice @ch, "#{time.strftime('%H:%M')} #{status.user.screen_name}: #{text}"
|
|
90
|
+
UserStream.configure do |config|
|
|
91
|
+
config.consumer_key = @bot_config.fetch(:consumer_key, nil)
|
|
92
|
+
config.consumer_secret = @bot_config.fetch(:consumer_secret, nil)
|
|
93
|
+
config.oauth_token = @bot_config.fetch(:access_token, nil)
|
|
94
|
+
config.oauth_token_secret = @bot_config.fetch(:access_token_secret, nil)
|
|
100
95
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
|
|
97
|
+
@streamer = Thread.new do
|
|
98
|
+
UserStream.client.user do |status|
|
|
99
|
+
case # https://dev.twitter.com/docs/streaming-apis/messages
|
|
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
|
|
114
|
+
begin
|
|
115
|
+
screen_name = status[:user][:screen_name]
|
|
116
|
+
if status[:retweeted_status]
|
|
117
|
+
status = status[:retweeted_status]
|
|
118
|
+
screen_name << ":"
|
|
119
|
+
screen_name << status[:user][:screen_name]
|
|
120
|
+
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
|
+
rescue => e
|
|
126
|
+
slog e.backtrace
|
|
127
|
+
slog e.inspect
|
|
128
|
+
slog status.inspect
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def bot_destruct
|
|
136
|
+
@streamer.kill
|
|
137
|
+
@streamer.join
|
|
138
|
+
rescue Timeout::Error
|
|
104
139
|
end
|
|
105
140
|
|
|
106
141
|
def on_client_privmsg(client, ch, message)
|
|
@@ -125,11 +160,8 @@ class TwitterBot < Nadoka::NDK_Bot
|
|
|
125
160
|
|
|
126
161
|
private
|
|
127
162
|
def puts_error_message(err)
|
|
128
|
-
if err.is_a?(Rubytter::APIError)
|
|
163
|
+
if err.is_a?(Rubytter::APIError) || err.is_a?(JSON::ParserError)
|
|
129
164
|
@logger.slog "%s: %s (%s) %s" % [err.backtrace[0], err.message, err.class, err.response]
|
|
130
|
-
elsif err.is_a?(JSON::ParserError)
|
|
131
|
-
sleep 180
|
|
132
|
-
return
|
|
133
165
|
else
|
|
134
166
|
@logger.slog "%s: %s (%s)" % [err.backtrace[0], err.message, err.class]
|
|
135
167
|
end
|
data/rice/irc.rb
CHANGED
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.3
|
|
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:
|
|
13
|
+
date: 2013-02-09 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.
|
|
@@ -23,11 +23,11 @@ extensions: []
|
|
|
23
23
|
extra_rdoc_files: []
|
|
24
24
|
files:
|
|
25
25
|
- .gitignore
|
|
26
|
-
- ChangeLog.old
|
|
27
26
|
- Gemfile
|
|
28
27
|
- README.md
|
|
29
28
|
- Rakefile
|
|
30
29
|
- bin/nadoka
|
|
30
|
+
- doc/ChangeLog.old
|
|
31
31
|
- lib/rss_check.rb
|
|
32
32
|
- lib/tagparts.rb
|
|
33
33
|
- nadoka.gemspec
|
|
@@ -46,6 +46,7 @@ files:
|
|
|
46
46
|
- plugins/autoop.nb
|
|
47
47
|
- plugins/backlogbot.nb
|
|
48
48
|
- plugins/checkbot.nb
|
|
49
|
+
- plugins/codesearchbot.nb
|
|
49
50
|
- plugins/cronbot.nb
|
|
50
51
|
- plugins/dictbot.nb
|
|
51
52
|
- plugins/drbcl.rb
|