nadoka 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|