nadoka 0.8.0
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/.gitignore +5 -0
- data/ChangeLog.old +1553 -0
- data/Gemfile +4 -0
- data/README.org +31 -0
- data/Rakefile +1 -0
- data/bin/nadoka +13 -0
- data/lib/rss_check.rb +206 -0
- data/lib/tagparts.rb +206 -0
- data/nadoka.gemspec +29 -0
- data/nadoka.rb +123 -0
- data/nadokarc +267 -0
- data/ndk/bot.rb +241 -0
- data/ndk/client.rb +288 -0
- data/ndk/config.rb +571 -0
- data/ndk/error.rb +61 -0
- data/ndk/logger.rb +311 -0
- data/ndk/server.rb +784 -0
- data/ndk/server_state.rb +324 -0
- data/ndk/version.rb +44 -0
- data/plugins/autoawaybot.nb +66 -0
- data/plugins/autodumpbot.nb +227 -0
- data/plugins/autoop.nb +56 -0
- data/plugins/backlogbot.nb +88 -0
- data/plugins/checkbot.nb +64 -0
- data/plugins/cronbot.nb +20 -0
- data/plugins/dictbot.nb +53 -0
- data/plugins/drbcl.rb +39 -0
- data/plugins/drbot.nb +93 -0
- data/plugins/evalbot.nb +49 -0
- data/plugins/gonzuibot.nb +41 -0
- data/plugins/googlebot.nb +345 -0
- data/plugins/identifynickserv.nb +43 -0
- data/plugins/mailcheckbot.nb +0 -0
- data/plugins/marldiabot.nb +99 -0
- data/plugins/messagebot.nb +96 -0
- data/plugins/modemanager.nb +150 -0
- data/plugins/opensearchbot.nb +156 -0
- data/plugins/opshop.nb +23 -0
- data/plugins/pastebot.nb +46 -0
- data/plugins/roulettebot.nb +33 -0
- data/plugins/rss_checkbot.nb +121 -0
- data/plugins/samplebot.nb +24 -0
- data/plugins/sendpingbot.nb +17 -0
- data/plugins/shellbot.nb +59 -0
- data/plugins/sixamobot.nb +77 -0
- data/plugins/tenkibot.nb +111 -0
- data/plugins/timestampbot.nb +62 -0
- data/plugins/titlebot.nb +226 -0
- data/plugins/translatebot.nb +301 -0
- data/plugins/twitterbot.nb +138 -0
- data/plugins/weba.nb +209 -0
- data/plugins/xibot.nb +113 -0
- data/rice/irc.rb +780 -0
- metadata +102 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
#
|
3
|
+
# Copyright (C) 2004 Kazuhiro NISHIYAMA
|
4
|
+
# All rights reserved.
|
5
|
+
# This is free software with ABSOLUTELY NO WARRANTY.
|
6
|
+
#
|
7
|
+
# You can redistribute it and/or modify it under the terms of
|
8
|
+
# the Ruby's licence.
|
9
|
+
#
|
10
|
+
=begin
|
11
|
+
BotConfig = [
|
12
|
+
{
|
13
|
+
:name => :MessageBot,
|
14
|
+
:message_file => 'message.yaml',
|
15
|
+
:root_key => Setting_name,
|
16
|
+
:channels => %w[#nadoka #Ruby:*.jp],
|
17
|
+
},
|
18
|
+
]
|
19
|
+
=end
|
20
|
+
|
21
|
+
|
22
|
+
require 'nkf'
|
23
|
+
require 'time'
|
24
|
+
require 'yaml/store'
|
25
|
+
|
26
|
+
class MessageBot < Nadoka::NDK_Bot
|
27
|
+
|
28
|
+
def bot_initialize
|
29
|
+
@store = YAML::Store.new(@bot_config[:message_file])
|
30
|
+
@root_key = @bot_config[:root_key]
|
31
|
+
@channels = @bot_config[:channels].collect{|ch| ch.downcase }
|
32
|
+
load_message
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_message
|
36
|
+
@store.transaction do |db|
|
37
|
+
if db.root?(@root_key)
|
38
|
+
h = db[@root_key]
|
39
|
+
@list = h['list'] || Hash.new
|
40
|
+
@message = h['message'] || Hash.new
|
41
|
+
else
|
42
|
+
@list = Hash.new
|
43
|
+
@message = Hash.new
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def save_message
|
49
|
+
@store.transaction do |db|
|
50
|
+
db[@root_key] = {
|
51
|
+
'list' => @list,
|
52
|
+
'message' => @message,
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_privmsg prefix, ch, msg
|
58
|
+
user = prefix.nick
|
59
|
+
c = NKF.nkf('-e', ch.to_s).downcase
|
60
|
+
return unless @channels.include?(c)
|
61
|
+
u = user.downcase
|
62
|
+
now = Time.now
|
63
|
+
key = "#{c} #{u}"
|
64
|
+
message_id = "<#{now.strftime('%Y%m%d%H%M%S')}.#{now.usec}.#{u}@#{c}>"
|
65
|
+
if @list.key?(key)
|
66
|
+
message_id_list = @list[key]
|
67
|
+
message_id_list.each do |message_id|
|
68
|
+
h = @message[message_id]
|
69
|
+
next if h.key?('delivered')
|
70
|
+
message = "#{h['from']}����#{h['to']}�����������#{h['body']}��"
|
71
|
+
send_notice(ch, NKF.nkf('-Ej -m0', message))
|
72
|
+
@message[message_id]['delivered'] = now
|
73
|
+
end
|
74
|
+
@list.delete(key)
|
75
|
+
save_message
|
76
|
+
end
|
77
|
+
if /^���� (\S+) (.+)$/e =~ NKF.nkf('-e -m0', msg.to_s)
|
78
|
+
to_nick, body = $1, $2
|
79
|
+
@message[message_id] = {
|
80
|
+
'from' => user,
|
81
|
+
'to' => to_nick,
|
82
|
+
'date' => now,
|
83
|
+
'channel' => ch,
|
84
|
+
'body' => body,
|
85
|
+
}
|
86
|
+
key = "#{c} #{to_nick.downcase}"
|
87
|
+
@list[key] ||= []
|
88
|
+
@list[key].push(message_id)
|
89
|
+
save_message
|
90
|
+
send_notice(ch, NKF.nkf('-Ej -m0', "#{$1}����ؤ�������ޤ��� > #{u}����"))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
#
|
3
|
+
# Copyright (c) 2004-2005 SASADA Koichi <ko1 at atdot.net>
|
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
|
+
# $Id$
|
11
|
+
#
|
12
|
+
|
13
|
+
|
14
|
+
=begin
|
15
|
+
|
16
|
+
== Abstract
|
17
|
+
|
18
|
+
Mode management bot
|
19
|
+
|
20
|
+
== Configuration
|
21
|
+
|
22
|
+
=== nadokarc
|
23
|
+
|
24
|
+
BotConfig => [
|
25
|
+
{
|
26
|
+
:name => :ModeManager,
|
27
|
+
#
|
28
|
+
# You can specify modes setting in file or
|
29
|
+
# String directly.
|
30
|
+
#
|
31
|
+
:file => 'modes',
|
32
|
+
# or :modes_file => 'modes',
|
33
|
+
|
34
|
+
:modes => <<-__EOS__,
|
35
|
+
[all]
|
36
|
+
+o=*.jp
|
37
|
+
__EOS__
|
38
|
+
# wait for setting modes (by second, avarage)
|
39
|
+
:wait => 5,
|
40
|
+
}
|
41
|
+
]
|
42
|
+
|
43
|
+
=== mode setting format
|
44
|
+
|
45
|
+
[<channel name> or 'all']
|
46
|
+
<+-><mode> pattern
|
47
|
+
<+-><mode> /regexp pattern/
|
48
|
+
|
49
|
+
<mode>: 'b' or 'v' or 'o'
|
50
|
+
<+->: '+' means add mode, '-' means remove mode
|
51
|
+
|
52
|
+
[example] -------------------------------
|
53
|
+
[all]
|
54
|
+
+o=*.jp
|
55
|
+
+o=/.*\.net/
|
56
|
+
|
57
|
+
[#nadoka]
|
58
|
+
+o=kiyoya* unak*
|
59
|
+
-o=ko1*
|
60
|
+
-----------------------------------------
|
61
|
+
|
62
|
+
|
63
|
+
=end
|
64
|
+
|
65
|
+
class ModeManager < Nadoka::NDK_Bot
|
66
|
+
|
67
|
+
class Fnmexp
|
68
|
+
def initialize str
|
69
|
+
@str = str
|
70
|
+
end
|
71
|
+
|
72
|
+
def =~ x
|
73
|
+
File.fnmatch @str, x, File::FNM_CASEFOLD
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_setting setting
|
78
|
+
s = nil
|
79
|
+
setting.each_line{|l|
|
80
|
+
l.strip!
|
81
|
+
if /^\[(all|[\#\&\!\+].+)\]/ =~ l
|
82
|
+
s = @config.identical_channel_name($1)
|
83
|
+
elsif /^\[%(.+)\]/ =~ l # for compatibility with madoka
|
84
|
+
s = @config.identical_channel_name("\##{$1}:*.jp")
|
85
|
+
elsif s && l.sub!(/^([+-][bvo]+)\s*=\s*/, '')
|
86
|
+
mode = $1
|
87
|
+
l.scan(/\S+/){|prefix|
|
88
|
+
if %r!^/(.*)\/$! =~ prefix
|
89
|
+
user = [mode, Regexp.new($1, Regexp::IGNORECASE)]
|
90
|
+
else
|
91
|
+
user = [mode, Fnmexp.new(prefix)]
|
92
|
+
end
|
93
|
+
@userlist[s] << user
|
94
|
+
}
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
def bot_initialize
|
100
|
+
@userlist = Hash.new{|h, k| h[k] = []}
|
101
|
+
if file = (@bot_config[:modes_file] || @bot_config[:file])
|
102
|
+
begin
|
103
|
+
parse_setting File.read(file)
|
104
|
+
rescue Exception => e
|
105
|
+
"operator manager: #{e.class}(#{e.message})"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
if setting = @bot_config[:modes]
|
109
|
+
parse_setting setting
|
110
|
+
end
|
111
|
+
@wait = @bot_config[:wait].to_i
|
112
|
+
@wait = 3 if @wait <= 0
|
113
|
+
end
|
114
|
+
|
115
|
+
def search_mode_in_list list, prefix
|
116
|
+
list.each{|e|
|
117
|
+
if e[1] =~ prefix
|
118
|
+
return e[0]
|
119
|
+
end
|
120
|
+
}
|
121
|
+
nil
|
122
|
+
end
|
123
|
+
|
124
|
+
def search_mode ch, prefix
|
125
|
+
search_mode_in_list(@userlist['all'], prefix) ||
|
126
|
+
search_mode_in_list(@userlist[ch], prefix)
|
127
|
+
end
|
128
|
+
|
129
|
+
def on_join prefix, rch
|
130
|
+
ch = @config.canonical_channel_name(rch)
|
131
|
+
Thread.new{
|
132
|
+
sleep(rand(@wait * 20) / 10.0)
|
133
|
+
if prefix.nick != @state.nick &&
|
134
|
+
(/o/ =~ @state.channel_user_mode(ch, @state.nick))
|
135
|
+
if mode = search_mode(ch, prefix.to_s)
|
136
|
+
current_modes = @state.channel_user_mode(ch, prefix.nick).split(//)
|
137
|
+
if /^\+/ =~ mode
|
138
|
+
noneed = mode.split(//)[1..-1].all?{|c| current_modes.include?(c)}
|
139
|
+
else
|
140
|
+
noneed = mode.split(//)[1..-1].all?{|c| !current_modes.include?(c)}
|
141
|
+
end
|
142
|
+
|
143
|
+
change_mode(rch, mode, prefix.nick) unless noneed
|
144
|
+
end
|
145
|
+
end
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# -*-ruby-*- #
|
2
|
+
# Copyright (C) 2011 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
|
+
== Usage with irc client
|
12
|
+
|
13
|
+
bing> keyword
|
14
|
+
-> search keyword by bing
|
15
|
+
|
16
|
+
googlecode> keyword
|
17
|
+
-> search keyword by Google Code Search Data API (Deprecated)
|
18
|
+
|
19
|
+
koders> keyword
|
20
|
+
-> search keyword by koders
|
21
|
+
|
22
|
+
== Configuration:
|
23
|
+
|
24
|
+
BotConfig << {
|
25
|
+
:name => :OpenSearchBot,
|
26
|
+
:bot_name => 'bing',
|
27
|
+
:ch => //,
|
28
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
29
|
+
:ch_kcode => :jis,
|
30
|
+
:html => 'http://www.bing.com/search?q={searchTerms}',
|
31
|
+
:rss => 'http://api.search.live.com/rss.aspx?source=web&query={searchTerms}'
|
32
|
+
,
|
33
|
+
}
|
34
|
+
|
35
|
+
BotConfig << {
|
36
|
+
:name => :OpenSearchBot,
|
37
|
+
:bot_name => 'googlecode',
|
38
|
+
:ch => //,
|
39
|
+
:ch_kcode => :jis,
|
40
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
41
|
+
# Google Code Search Data API (Deprecated)
|
42
|
+
# http://code.google.com/intl/ja/apis/codesearch/docs/2.0/developers_guide.h
|
43
|
+
tml
|
44
|
+
:html => 'http://www.google.com/codesearch?q={searchTerms}',
|
45
|
+
:rss => 'http://www.google.com/codesearch/feeds/search?q={searchTerms}',
|
46
|
+
}
|
47
|
+
|
48
|
+
BotConfig << {
|
49
|
+
:name => :OpenSearchBot,
|
50
|
+
:bot_name => 'koders',
|
51
|
+
:ch => //,
|
52
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
53
|
+
:ch_kcode => :jis,
|
54
|
+
# http://www.koders.com/search/KodersDescriptionOS1_1.xml
|
55
|
+
:html => 'http://www.koders.com/?s={searchTerms}',
|
56
|
+
:rss => 'http://www.koders.com/?s={searchTerms}&results=code&output=rss&OSve
|
57
|
+
rsion=1.1',
|
58
|
+
}
|
59
|
+
|
60
|
+
=end
|
61
|
+
|
62
|
+
require 'open-uri'
|
63
|
+
require 'uri'
|
64
|
+
require 'cgi'
|
65
|
+
|
66
|
+
class OpenSearch
|
67
|
+
def initialize(options)
|
68
|
+
@html = options[:html]
|
69
|
+
@rss = options[:rss]
|
70
|
+
@referer = options[:referer] || 'http://rubyforge.org/projects/nadoka/'
|
71
|
+
end
|
72
|
+
|
73
|
+
def result(key)
|
74
|
+
escaped_key = CGI.escape(key)
|
75
|
+
link = @html.sub(/\{searchTerms\}/) { escaped_key }
|
76
|
+
uri = @rss.sub(/\{searchTerms\}/) { escaped_key }
|
77
|
+
open(uri, "Referer" => @referer) do |f|
|
78
|
+
result = f.read
|
79
|
+
if /<([A-Za-z]+):totalResults>(\d+)<\/\1:totalResults>/ =~ result
|
80
|
+
total = $2.to_i
|
81
|
+
return "#{total.to_s.gsub(/\d(?=\d{3}+\z)/,'\&,')} result#{total > 1 ? 's' : ''} in #{link}"
|
82
|
+
else
|
83
|
+
return "#{key} - not found in #{link}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
if __FILE__ == $0
|
90
|
+
h = {
|
91
|
+
'bing' => {
|
92
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
93
|
+
:html => 'http://www.bing.com/search?q={searchTerms}',
|
94
|
+
:rss => 'http://api.search.live.com/rss.aspx?source=web&query={searchTerms}',
|
95
|
+
},
|
96
|
+
'googlecode' => {
|
97
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
98
|
+
# Google Code Search Data API (Deprecated)
|
99
|
+
# http://code.google.com/intl/ja/apis/codesearch/docs/2.0/developers_guide.html
|
100
|
+
:html => 'http://www.google.com/codesearch?q={searchTerms}',
|
101
|
+
:rss => 'http://www.google.com/codesearch/feeds/search?q={searchTerms}',
|
102
|
+
},
|
103
|
+
'koders' => {
|
104
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
105
|
+
# http://www.koders.com/search/KodersDescriptionOS1_1.xml
|
106
|
+
:html => 'http://www.koders.com/?s={searchTerms}',
|
107
|
+
:rss => 'http://www.koders.com/?s={searchTerms}&results=code&output=rss&OSversion=1.1',
|
108
|
+
},
|
109
|
+
'youtube' => {
|
110
|
+
:referer => 'http://rubyforge.org/projects/nadoka/',
|
111
|
+
:html => 'http://www.youtube.com/results?search_query={searchTerms}',
|
112
|
+
:rss => 'http://gdata.youtube.com/feeds/api/videos?q={searchTerms}',
|
113
|
+
},
|
114
|
+
}
|
115
|
+
engine = ARGV.shift
|
116
|
+
if h.key?(engine)
|
117
|
+
open_search = OpenSearch.new(h[engine])
|
118
|
+
ARGV.each do |key|
|
119
|
+
result = open_search.result(key)
|
120
|
+
puts result
|
121
|
+
end
|
122
|
+
else
|
123
|
+
STDERR.puts "usage: #{$0} {#{h.keys.sort.join('|')}} key ..."
|
124
|
+
end
|
125
|
+
exit
|
126
|
+
end
|
127
|
+
|
128
|
+
class OpenSearchBot < Nadoka::NDK_Bot
|
129
|
+
def bot_initialize
|
130
|
+
if @bot_config.key?(:channels)
|
131
|
+
channels = '\A(?:' + @bot_config[:channels].collect{|ch|
|
132
|
+
Regexp.quote(ch)
|
133
|
+
}.join('|') + ')\z'
|
134
|
+
@available_channel = Regexp.compile(channels)
|
135
|
+
else
|
136
|
+
@available_channel = @bot_config[:ch] || //
|
137
|
+
end
|
138
|
+
|
139
|
+
@bot_name = @bot_config[:bot_name] || 'OpenSearchBot'
|
140
|
+
@open_search = OpenSearch.new(@bot_config)
|
141
|
+
@pattern = @bot_config[:pattern] || /\A#{Regexp.quote(@bot_name)}\s*[<:>]\s*(.+)/
|
142
|
+
@ch_kcode = @bot_config[:ch_kcode]
|
143
|
+
end
|
144
|
+
|
145
|
+
def on_privmsg prefix, ch, msg
|
146
|
+
if @pattern =~ msg
|
147
|
+
key = $1
|
148
|
+
if @ch_kcode == :jis
|
149
|
+
ret = @open_search.result(key.toutf8).tojis
|
150
|
+
else
|
151
|
+
ret = @open_search.result(key)
|
152
|
+
end
|
153
|
+
send_notice ch, "#{@bot_name} bot: #{ret}"
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
data/plugins/opshop.nb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
#
|
3
|
+
# Copyright (c) 2004-2005 SASADA Koichi <ko1 at atdot.net>
|
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
|
+
# operator shop
|
11
|
+
#
|
12
|
+
# $Id$
|
13
|
+
#
|
14
|
+
|
15
|
+
class OpShop < Nadoka::NDK_Bot
|
16
|
+
def on_join prefix, ch
|
17
|
+
if prefix.nick != @state.nick
|
18
|
+
change_mode(ch, "+o", prefix.nick)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
data/plugins/pastebot.nb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This plugin is test version.
|
4
|
+
|
5
|
+
=end
|
6
|
+
|
7
|
+
|
8
|
+
require 'open-uri'
|
9
|
+
|
10
|
+
class PasteBot < Nadoka::NDK_Bot
|
11
|
+
|
12
|
+
def bot_initialize
|
13
|
+
@ch = @bot_config[:ch] || /./
|
14
|
+
@msg = @bot_config[:mgs] || /\Apaste>/
|
15
|
+
@service_uri = @bot_config[:service_uri] ||
|
16
|
+
'http://www.atdot.net/sp'
|
17
|
+
@fmsg = @bot_config[:mgs] || /\Afpaste>/
|
18
|
+
@fservice_uri = @bot_config[:service_uri] ||
|
19
|
+
'http://www.atdot.net/fp'
|
20
|
+
end
|
21
|
+
|
22
|
+
def nick_escape nick
|
23
|
+
nick.gsub(/[^A-Za-z\d\-_]/, '_')
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_privmsg prefix, ch, msg
|
27
|
+
nick = nick_escape prefix.nick
|
28
|
+
|
29
|
+
if @ch === ch
|
30
|
+
if @msg === msg
|
31
|
+
nid = ''
|
32
|
+
open("#{@service_uri}/check/newid"){|f|
|
33
|
+
nid = f.gets
|
34
|
+
}
|
35
|
+
send_notice ch, "#{@service_uri}/view/#{nid}_#{nick}"
|
36
|
+
end
|
37
|
+
if @fmsg === msg
|
38
|
+
nid = ''
|
39
|
+
open("#{@fservice_uri}/check/newid"){|f|
|
40
|
+
nid = f.gets
|
41
|
+
}
|
42
|
+
send_notice ch, "#{@fservice_uri}/view/#{nid}_#{nick}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|