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.
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
- klass = ConfigClass.shift
183
- while k = ConfigClass.shift
184
+ base_klass = ConfigClass.shift
185
+ while klass = ConfigClass.shift
184
186
  Object.module_eval{
185
- remove_const(k.name)
187
+ remove_const(klass.name)
186
188
  }
187
189
  end
188
- ConfigClass.push(klass)
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
- ch_ = ch = @config.canonical_channel_name(rch)
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
- chs = @current_channels[ch] = ChannelState.new(rch)
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.2'
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| s = f.gets}
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
- begin
85
- if charset
86
- # ok
87
- elsif /charset=[\'\"]?([^;\'\">]+)/ni =~ body
88
- charset = $1
89
- end
90
- case charset
91
- when /shift_jis/i
92
- charset = "cp932"
93
- when /euc-jp/i # euc-jp, x-euc-jp
94
- charset = "eucjp-ms"
95
- end
96
- if /\Autf-8\z/i =~ charset
97
- # avoid #<ArgumentError: invalid byte sequence in UTF-8>
98
- # or Iconv::IllegalSequence
99
- body = NKF.nkf("-Wwm0x", body)
100
- elsif charset
101
- charset.sub!(/\Ax-?/i, '')
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
- else
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
- rescue Iconv::IllegalSequence => e
107
- info[:errors] << e
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
@@ -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
- def on_timer(t)
91
- @rt.friends_timeline.each do |status|
92
- id = status.id.to_i
93
- next unless @current_id < id
94
- @current_id = id
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
- rescue Errno::ETIMEDOUT, Timeout::Error, SocketError
102
- rescue Exception => err
103
- puts_error_message(err)
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
@@ -200,9 +200,11 @@ module RICE
200
200
  end
201
201
  sleep retry_wait
202
202
  retry
203
- ensure
203
+ rescue Exception
204
+ @main_th.kill
205
+ raise
206
+ else
204
207
  @main_th.join
205
- nil
206
208
  end
207
209
 
208
210
  end
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.2
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: 2012-06-29 00:00:00.000000000 Z
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