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