nadoka 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.gitignore +5 -0
  2. data/ChangeLog.old +1553 -0
  3. data/Gemfile +4 -0
  4. data/README.org +31 -0
  5. data/Rakefile +1 -0
  6. data/bin/nadoka +13 -0
  7. data/lib/rss_check.rb +206 -0
  8. data/lib/tagparts.rb +206 -0
  9. data/nadoka.gemspec +29 -0
  10. data/nadoka.rb +123 -0
  11. data/nadokarc +267 -0
  12. data/ndk/bot.rb +241 -0
  13. data/ndk/client.rb +288 -0
  14. data/ndk/config.rb +571 -0
  15. data/ndk/error.rb +61 -0
  16. data/ndk/logger.rb +311 -0
  17. data/ndk/server.rb +784 -0
  18. data/ndk/server_state.rb +324 -0
  19. data/ndk/version.rb +44 -0
  20. data/plugins/autoawaybot.nb +66 -0
  21. data/plugins/autodumpbot.nb +227 -0
  22. data/plugins/autoop.nb +56 -0
  23. data/plugins/backlogbot.nb +88 -0
  24. data/plugins/checkbot.nb +64 -0
  25. data/plugins/cronbot.nb +20 -0
  26. data/plugins/dictbot.nb +53 -0
  27. data/plugins/drbcl.rb +39 -0
  28. data/plugins/drbot.nb +93 -0
  29. data/plugins/evalbot.nb +49 -0
  30. data/plugins/gonzuibot.nb +41 -0
  31. data/plugins/googlebot.nb +345 -0
  32. data/plugins/identifynickserv.nb +43 -0
  33. data/plugins/mailcheckbot.nb +0 -0
  34. data/plugins/marldiabot.nb +99 -0
  35. data/plugins/messagebot.nb +96 -0
  36. data/plugins/modemanager.nb +150 -0
  37. data/plugins/opensearchbot.nb +156 -0
  38. data/plugins/opshop.nb +23 -0
  39. data/plugins/pastebot.nb +46 -0
  40. data/plugins/roulettebot.nb +33 -0
  41. data/plugins/rss_checkbot.nb +121 -0
  42. data/plugins/samplebot.nb +24 -0
  43. data/plugins/sendpingbot.nb +17 -0
  44. data/plugins/shellbot.nb +59 -0
  45. data/plugins/sixamobot.nb +77 -0
  46. data/plugins/tenkibot.nb +111 -0
  47. data/plugins/timestampbot.nb +62 -0
  48. data/plugins/titlebot.nb +226 -0
  49. data/plugins/translatebot.nb +301 -0
  50. data/plugins/twitterbot.nb +138 -0
  51. data/plugins/weba.nb +209 -0
  52. data/plugins/xibot.nb +113 -0
  53. data/rice/irc.rb +780 -0
  54. metadata +102 -0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nadoka.gemspec
4
+ gemspec
@@ -0,0 +1,31 @@
1
+ #######################################################
2
+ # Nadoka: IRC Client server program.
3
+ #
4
+ # Written by SASADA Koichi <ko1 at atdot.net>
5
+ #
6
+ #
7
+ # $Id$
8
+ #
9
+
10
+ * What's this?
11
+
12
+ Nadoka is IRC Client Server program.
13
+ It's same concept as [[http://www.madoka.org/][madoka]].
14
+
15
+ You can do with this software:
16
+
17
+ - connect to IRC usually
18
+ - easy to make a bot with ruby
19
+
20
+
21
+ * more about
22
+
23
+ See Web pages:
24
+ - https://github.com/nadoka/nadoka
25
+ - http://rubyforge.org/projects/nadoka/
26
+ - http://www.atdot.net/nadoka/
27
+
28
+
29
+ : Thank you,
30
+ : --
31
+ : SASADA Koichi at atdot dot net
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/ruby
2
+ require 'rbconfig'
3
+ ruby = nil
4
+ begin
5
+ ruby = RbConfig.ruby
6
+ rescue
7
+ ruby = File.join(
8
+ Config::CONFIG["bindir"],
9
+ Config::CONFIG["ruby_install_name"] + Config::CONFIG["EXEEXT"]
10
+ )
11
+ end
12
+ top_dir = File.expand_path('../..', __FILE__)
13
+ exec(ruby, "-I#{top_dir}", File.join(top_dir, 'nadoka.rb'), *ARGV)
@@ -0,0 +1,206 @@
1
+ #
2
+ # Copyright (c) 2004-2005 SASADA Koichi <ko1 at atdot.net>
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
+ # $Id$
10
+ # Create : K.S. Sat, 24 Apr 2004 12:10:31 +0900
11
+ #
12
+
13
+ require "rss/parser"
14
+ require "rss/1.0"
15
+ require "rss/2.0"
16
+ require "rss/syndication"
17
+ require "rss/dublincore"
18
+ require "open-uri"
19
+ require 'uri'
20
+ require 'yaml/store'
21
+ require 'csv'
22
+ require 'stringio'
23
+ require 'zlib'
24
+
25
+
26
+ class RSS_Check
27
+ class RSS_File
28
+ def initialize path, init_now
29
+ @uri = URI.parse(path)
30
+ @entry_time = @file_time = (init_now ? Time.now : Time.at(0))
31
+ end
32
+
33
+ def check
34
+ begin
35
+ if (mt=mtime) > @file_time
36
+ @file_time = mt
37
+ check_entries
38
+ else
39
+ []
40
+ end
41
+ rescue => e
42
+ [{
43
+ :about => e.message,
44
+ :title => "RSS Check Error (#{@uri})",
45
+ :ccode => 'UTF-8'
46
+ }]
47
+ end
48
+ end
49
+
50
+ def date_of e
51
+ if e.respond_to? :dc_date
52
+ e.dc_date || Time.at(0)
53
+ else
54
+ e.pubDate || Time.at(0)
55
+ end
56
+ end
57
+
58
+ def check_entries
59
+ rss = RSS::Parser.parse(read_content, false)
60
+ et = @entry_time
61
+ items = rss.items.sort_by{|e|
62
+ date_of(e)
63
+ }.map{|e|
64
+ e_date = date_of(e)
65
+ if e_date > @entry_time
66
+ if e_date > et
67
+ et = e_date
68
+ end
69
+ {
70
+ :about => e.about,
71
+ :title => e.title,
72
+ :ccode => 'UTF-8'
73
+ }
74
+ end
75
+ }.compact
76
+ @entry_time = et
77
+ items
78
+ end
79
+
80
+ def read_content
81
+ case @uri.scheme
82
+ when 'http'
83
+ open(@uri){|f|
84
+ if f.content_encoding.any?{|e| /gzip/ =~ e}
85
+ Zlib::GzipReader.new(StringIO.new(f.read)).read || ''
86
+ else
87
+ f.read
88
+ end
89
+ }
90
+ else
91
+ open(@uri.to_s){|f|
92
+ f.read
93
+ }
94
+ end
95
+ end
96
+
97
+ def mtime
98
+ case @uri.scheme
99
+ when 'http'
100
+ open(@uri){|f|
101
+ f.last_modified || Time.now
102
+ }
103
+ else
104
+ File.mtime(@rss_file)
105
+ end
106
+ end
107
+ end
108
+
109
+ class LIRS_File < RSS_File
110
+ def check_entries
111
+ et = @entry_time
112
+ res = []
113
+ CSV::Reader.parse(read_content){|row|
114
+ last_detected = Time.at(row[2].data.to_i)
115
+ if last_detected > @entry_time && row[1].data != row[2].data
116
+ if last_detected > et
117
+ et = last_detected
118
+ end
119
+ res << {
120
+ :about => row[5].data,
121
+ :title => row[6].data,
122
+ :ccode => 'EUC-JP'
123
+ }
124
+ end
125
+ }
126
+ @entry_time = et
127
+ res
128
+ end
129
+ end
130
+
131
+ def initialize paths, cache_file=nil, init_now=false
132
+ @paths = paths
133
+ @db = YAML::Store.new(cache_file) if cache_file
134
+ @rss_files = paths.map{|uri|
135
+ load_file(uri) ||
136
+ if /LIRS:(.+)/ =~ uri
137
+ LIRS_File.new($1, init_now)
138
+ else
139
+ RSS_File.new(uri, init_now)
140
+ end
141
+ }
142
+ end
143
+
144
+ def check
145
+ @rss_files.map{|rf|
146
+ rf.check
147
+ }.flatten
148
+ end
149
+
150
+ def save
151
+ @db.transaction{
152
+ @paths.each_with_index{|path, i|
153
+ @db[path] = @rss_files[i]
154
+ }
155
+ } if @db
156
+ end
157
+
158
+ def load_file file
159
+ @db.transaction{
160
+ @db[file]
161
+ } if @db
162
+ end
163
+
164
+ def clear
165
+ if @db
166
+ @db.transaction{
167
+ @db.keys.each{|k|
168
+ @db.delete k
169
+ }
170
+ }
171
+ end
172
+ end
173
+ end
174
+
175
+
176
+ if $0 == __FILE__
177
+ rss_uri = %w(
178
+ http://www.ruby-lang.org/ja/index.rdf
179
+ http://slashdot.jp/slashdotjp.rss
180
+ http://www3.asahi.com/rss/index.rdf
181
+ http://pcweb.mycom.co.jp/haishin/rss/index.rdf
182
+ http://japan.cnet.com/rss/index.rdf
183
+ http://blog.japan.cnet.com/umeda/index.rdf
184
+ http://jvn.doi.ics.keio.ac.jp/rss/jvnRSS.rdf
185
+ )
186
+ lirs_uri = [
187
+ 'LIRS:http://www.rubyist.net/~kazu/samidare/sites.lirs.gz'
188
+ ]
189
+
190
+ rssc = RSS_Check.new(
191
+ rss_uri + lirs_uri,
192
+ ARGV.shift || './rss_cache',
193
+ false # false
194
+ )
195
+ require 'iconv'
196
+ require 'kconv'
197
+ ic = Iconv.open("EUC-JP", "UTF-8")
198
+
199
+ rssc.check.each{|e|
200
+ puts e[:about]
201
+ title = (e[:ccode] == 'UTF-8') ? ic.iconv(e[:title]) : e[:title]
202
+ puts title
203
+ }
204
+ rssc.dump
205
+ end
206
+
@@ -0,0 +1,206 @@
1
+ #
2
+ # Copyright (c) 2004-2005 SASADA Koichi <ko1 at atdot.net>
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
+ # $Id:$
10
+ #
11
+
12
+ require 'cgi'
13
+ module TagParts
14
+ class TagItem
15
+ include Enumerable
16
+ def initialize tag, body, ignore_empty = false
17
+ @tag = tag.to_s
18
+ @attr = {}
19
+ @body = []
20
+ @ignore_empty = ignore_empty
21
+ body.each{|e|
22
+ add! e
23
+ }
24
+ end
25
+ attr_reader :body, :tag, :attr
26
+
27
+ def make_attr_str
28
+ @attr.map{|k,v|
29
+ " #{CGI.escapeHTML(k.to_s)}='#{CGI.escapeHTML(v)}'"
30
+ }.join
31
+ end
32
+
33
+ def to_s
34
+ if @body.size > 0 || @ignore_empty
35
+ body = @body.flatten.map{|e|
36
+ if e.kind_of? String
37
+ CGI.escapeHTML(e.to_s)
38
+ else
39
+ e.to_s
40
+ end
41
+ }
42
+ "<#{@tag}#{make_attr_str}\n>#{body}</#{@tag}>\n"
43
+ else
44
+ "<#{@tag}#{make_attr_str} /\n>"
45
+ end
46
+ end
47
+
48
+ def inspect
49
+ "<TagItem: <#{@tag}#{make_attr_str}>>"
50
+ end
51
+
52
+ def add!(elem)
53
+ if elem.kind_of? Hash
54
+ @attr.update elem
55
+ else
56
+ @body << elem
57
+ end
58
+ end
59
+
60
+ def [](k)
61
+ @attr[k]
62
+ end
63
+
64
+ def []=(k, v)
65
+ @attr[k] = v
66
+ end
67
+
68
+ def each
69
+ @body.flatten.each{|e|
70
+ yield e
71
+ }
72
+ end
73
+
74
+ def each_leaf
75
+ @body.each{|e|
76
+ if e.kind_of? TagItem
77
+ e.each_leaf(&Proc.new)
78
+ else
79
+ yield e
80
+ end
81
+ }
82
+ end
83
+
84
+ def each_node
85
+ yield(self)
86
+ @body.each{|e|
87
+ if e.kind_of? TagItem
88
+ e.each_node(&Proc.new)
89
+ else
90
+ yield e
91
+ end
92
+ }
93
+ end
94
+
95
+ alias << add!
96
+ end
97
+
98
+ def ignore_empty_tag?
99
+ false
100
+ end
101
+
102
+ # do nothing. please override
103
+ def tag_encoding str
104
+ str
105
+ end
106
+
107
+ def tree2string tag
108
+ tag_encoding(tree2string_(tag))
109
+ end
110
+
111
+ def tree2string_ tag
112
+ bs = tag.map{|body|
113
+ if body.kind_of? TagItem
114
+ tree2string_(body)
115
+ else
116
+ CGI.escapeHTML(body.to_s)
117
+ end
118
+ }
119
+ tagname = tag.tag
120
+ attr = tag.make_attr_str
121
+ if bs.size > 0 || ignore_empty_tag?
122
+ "<#{tagname}#{attr}\n>#{bs}</#{tagname}>\n"
123
+ else
124
+ "<#{tagname}#{attr}\n/>"
125
+ end
126
+ end
127
+
128
+ @@method_prefix = '_'
129
+
130
+ def self.newtag sym, ignore_empty, klass = TagParts
131
+ klass.module_eval <<-EOS
132
+ def #{@@method_prefix}#{sym}(*args)
133
+ TagItem.new(:#{sym}, args, #{ignore_empty})
134
+ end
135
+ EOS
136
+ end
137
+
138
+ TagParts.module_eval <<-EOS
139
+ def #{@@method_prefix}(tag, *args)
140
+ TagItem.new(tag, args, false)
141
+ end
142
+ EOS
143
+
144
+ def method_missing m, *args
145
+ if make_unknown_tag? && (/^#{@@method_prefix}(.+)/ =~ m.to_s)
146
+ TagItem.new($1, args)
147
+ else
148
+ super
149
+ end
150
+ end
151
+
152
+ def make_unknown_tag?
153
+ true
154
+ end
155
+
156
+ end
157
+
158
+ module HTMLParts
159
+ include TagParts
160
+
161
+ def make_unknown_tag?
162
+ false
163
+ end
164
+
165
+ def ignore_empty_tag?
166
+ true
167
+ end
168
+
169
+
170
+ # copy from cgi.rb
171
+ PARTS_1 = %w{
172
+ TT I B BIG SMALL EM STRONG DFN CODE SAMP KBD
173
+ VAR CITE ABBR ACRONYM SUB SUP SPAN BDO ADDRESS DIV MAP OBJECT
174
+ H1 H2 H3 H4 H5 H6 PRE Q INS DEL DL OL UL LABEL SELECT OPTGROUP
175
+ FIELDSET LEGEND BUTTON TABLE TITLE STYLE SCRIPT NOSCRIPT
176
+ TEXTAREA FORM A BLOCKQUOTE CAPTION
177
+ }
178
+ PARTS_2 = %w{
179
+ IMG BASE BR AREA LINK PARAM HR INPUT COL META
180
+ }
181
+ PARTS_3 = %w{
182
+ HTML BODY P DT DD LI OPTION THEAD TFOOT TBODY COLGROUP TR TH TD HEAD
183
+ }
184
+ (PARTS_1 + PARTS_2 + PARTS_3).each{|e|
185
+ elem = e.downcase
186
+ TagParts.newtag elem, true
187
+ }
188
+ end
189
+
190
+ __END__
191
+
192
+ include HTMLParts
193
+ tags = _html(
194
+ _head(
195
+ _title('hogehoge')),
196
+ _body(
197
+ _br(),
198
+ _h1('huga-'),
199
+ _p('hogehoge', _a('hogehoge', 'href' => 'dokka'), 'huga'),
200
+ _p('hogehoge', 'huga', ['ho-', 'hu'])
201
+ ))
202
+
203
+ puts tags.to_s
204
+ puts tree2string(tags)
205
+ p( tags.to_s == tree2string(tags) )
206
+