net-irc2 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e4908aab25b550d867b561bb113e159e740dd000
4
+ data.tar.gz: c29e4d4ed4cf1bcd644a3c47270fb6da528b6a2d
5
+ SHA512:
6
+ metadata.gz: f2c08bc4d72354eecefd9c8242d32675061ee8f0d5507466c5ed68ba7304a946e8b6a0b75c4442a33fd98b3aa03565dfe2f4e5f0ca20c3fc1e6850283db44370
7
+ data.tar.gz: d3c4e3feff8ec09ab13f8bb28fa7b7a08176e5fb04b2087dc8a62a7dfe05fbbf7778ecfd4bd32ad3279f71e35886d8a3b82c0ebd51310a94fe9d9b53549b0988
data/AUTHORS.txt ADDED
@@ -0,0 +1,33 @@
1
+ Core Authors::
2
+ cho45
3
+ drry
4
+ czaks
5
+ Satoshi Nakagawa
6
+ kouhei
7
+ Tim Carey-Smith
8
+ Wataru TOYA
9
+ Yuki Sonoda (Yugui)
10
+ yappo
11
+
12
+ Example Contributors::
13
+ cho45
14
+ drry
15
+ mzp
16
+ smbd
17
+ Keiji, Yoshimi
18
+ HIROSE Masaaki
19
+ dzfl
20
+ shunirr
21
+ Kazuhiro NISHIYAMA
22
+ Takeru Naito
23
+ Wataru TOYA
24
+ Yuki Sonoda (Yugui)
25
+ czaks
26
+ yappo
27
+ Keisuke SATO
28
+ SHIBATA Hiroshi
29
+ Sotaro KARASAWA
30
+ Tim Carey-Smith
31
+ Tokuhiro Matsuno
32
+ kusigahama
33
+ motemen
data/ChangeLog ADDED
@@ -0,0 +1,95 @@
1
+ 2010-01-13 SATOH Hiroh <cho45@lowreal.net>
2
+
3
+ * Remove method_missing:
4
+ Defining method_missing produce big side-effects.
5
+ (eg. no error on undefined values)
6
+
7
+ 2009-10-11 SATOH Hiroh <cho45@lowreal.net>
8
+
9
+ * [new]
10
+ Implemented Server#sessions which returns all sessions connected to
11
+ the server.
12
+ * Released 0.0.9
13
+
14
+ 2009-08-08 SATOH Hiroh <cho45@lowreal.net>
15
+
16
+ * [bug]:
17
+ Fixed to work on ruby1.9.1 (now can send iso-2022-jp)
18
+ * [new]
19
+ Implemented Message#ctcps returns embedded all ctcp messages (drry).
20
+ * Released 0.0.8
21
+
22
+ 2009-02-19 SATOH Hiroh <cho45@lowreal.net>
23
+
24
+ * [bug]:
25
+ Fixed net/irc.rb permission.
26
+ * Released 0.0.7
27
+
28
+ 2009-02-01 SATOH Hiroh <cho45@lowreal.net>
29
+
30
+ * [bug]:
31
+ Fixed to work on ruby1.9.1
32
+ * [release]:
33
+ Released 0.0.6
34
+
35
+ 2008-07-06 SATOH Hiroh <cho45@lowreal.net>
36
+
37
+ * [interface]:
38
+ Removed around @channels and separeted to
39
+ Net::IRC::Client::ChannelManager as just a sample of managing
40
+ channels.
41
+ * [release]:
42
+ Released 0.0.5
43
+
44
+ 2008-07-06 Satoshi Nakagawa <psychs@limechat.net>
45
+
46
+ * [new]:
47
+ Added a mode parser which can be configured automatically from 005 replies.
48
+
49
+ 2008-06-28 cho45
50
+
51
+ * [interface]:
52
+ Change mode character to symbol.
53
+ * [new]:
54
+ Seperate each class to some files.
55
+ * [release]:
56
+ Released 0.0.4
57
+
58
+ 2008-06-14 cho45
59
+
60
+ * [bug]:
61
+ Fixed examples. (twitter, wassr, lingr gateways)
62
+ * [release]:
63
+ Released 0.0.3
64
+
65
+ 2008-02-06 cho45
66
+
67
+ * [release] @5832:
68
+ Released 0.0.2
69
+
70
+
71
+ 2008-02-01 cho45
72
+
73
+ * [bug] @5986:
74
+ Fixed to destroy closed stream.
75
+
76
+ 2008-01-31 cho45
77
+
78
+ * [new] @5939:
79
+ Added client example.
80
+
81
+ * [new] @5929:
82
+ Updated tests.
83
+ Made allow lame prefix in RPL_WELCOME (like freenode)
84
+
85
+ 2008-01-29 cho45
86
+
87
+ * [bug] @5846:
88
+ athack つかわないときの処理がもろに間違ってた。
89
+
90
+ * [bug] @5843:
91
+ Net::IRC::Server の修正に追従できていなかった
92
+
93
+ * [release] @5832:
94
+ Released 0.0.1
95
+
data/README ADDED
@@ -0,0 +1,91 @@
1
+
2
+ = net-irc
3
+
4
+
5
+ == Description
6
+
7
+ IRC library. This is mostly conform to RFC 1459 but partly not for convenience.
8
+
9
+
10
+ == Installation
11
+
12
+ === Archive Installation
13
+
14
+ rake install
15
+
16
+ === Gem Installation
17
+
18
+ gem install net-irc
19
+
20
+
21
+ == Features/Problems
22
+
23
+ * IRC client (for bot)
24
+ * IRC server (for gateway to webservices)
25
+
26
+ == Synopsis
27
+
28
+ === Client
29
+
30
+ require "net/irc"
31
+
32
+ class SimpleClient < Net::IRC::Client
33
+ def on_privmsg(m)
34
+ super
35
+ channel, message = *m
36
+ if message =~ /Hello/
37
+ post NOTICE, channel, "Hello!"
38
+ end
39
+ end
40
+ end
41
+
42
+ Net::IRC::Client manages channel status and the information is set in @channels.
43
+ So, be careful to use @channels instance variable and call super surely.
44
+
45
+ === Server
46
+
47
+ see example/tig.rb
48
+
49
+
50
+ == IRC Gateways
51
+
52
+ There are some gateways connecting to webservices.
53
+
54
+ * Twitter
55
+ * Wassr
56
+ * Hatena Haiku
57
+ * Hatena Star
58
+
59
+ If you want to run it, type following:
60
+
61
+ $ cd `ruby -rubygems -e 'print Gem.searcher.find("net/irc").full_gem_path+"/examples"'`
62
+
63
+ Twitter:
64
+ $ ./tig.rb -f >> /dev/null 2>&1
65
+
66
+ Wassr:
67
+ $ ./wig.rb
68
+
69
+ Run as daemon in default. If you want to help:
70
+
71
+ $ ./tig.rb --help
72
+ Usage: tig.rb [opts]
73
+
74
+
75
+ Options:
76
+ -p, --port [PORT=16668] port number to listen
77
+ -h, --host [HOST=localhost] host name or IP address to listen
78
+ -l, --log LOG log file
79
+ --debug Enable debug mode
80
+ -f, --foreground run foreground
81
+ -n [user name or email address]
82
+ --name
83
+
84
+
85
+ == Copyright
86
+
87
+ This library is based on RICE <http://arika.org/ruby/rice> written by akira yamada.
88
+
89
+ Author:: cho45 <cho45@lowreal.net>
90
+ Copyright:: Copyright (c) 2008-2009 cho45
91
+ License:: Ruby's
data/Rakefile ADDED
@@ -0,0 +1,69 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+ require 'bundler/setup'
4
+ Bundler.setup(:development)
5
+
6
+ require 'shipit'
7
+ require 'rake'
8
+ require 'rake/clean'
9
+ require 'rake/contrib/sshpublisher'
10
+ require 'rdoc/task'
11
+ require 'fileutils'
12
+
13
+ require 'rspec/core/rake_task'
14
+
15
+ include FileUtils
16
+
17
+ $LOAD_PATH.unshift "lib"
18
+ require "net/irc"
19
+
20
+ GEMSPEC = Gem.latest_spec_for('net-irc')
21
+
22
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
23
+
24
+ task :default => [:spec]
25
+ task :package => [:clean]
26
+
27
+ RSpec::Core::RakeTask.new do |t|
28
+ t.rspec_opts = ['--options', "spec/spec.opts"]
29
+ end
30
+
31
+ task :upload_doc => [:rdoc] do
32
+ sh %{rsync --update -avptr html/ lowreal@cho45.stfuawsc.com:/virtual/lowreal/public_html/cho45.stfuawsc.com/net-irc}
33
+ end
34
+
35
+ Rake::RDocTask.new do |rdoc|
36
+ rdoc.rdoc_dir = 'html'
37
+ rdoc.options += GEMSPEC.rdoc_options
38
+ rdoc.template = "resh"
39
+ if ENV['DOC_FILES']
40
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
41
+ else
42
+ rdoc.rdoc_files.include('README', 'ChangeLog')
43
+ rdoc.rdoc_files.include('lib/**/*.rb')
44
+ rdoc.rdoc_files.include('ext/**/*.c')
45
+ end
46
+ end
47
+
48
+ Rake::ShipitTask.new do |s|
49
+ s.ChangeVersion "lib/net/irc.rb", "VERSION"
50
+ s.Commit
51
+ s.Task :clean, :package, :upload_doc
52
+ s.Step.new {
53
+ }.and {
54
+ system("gem", "push", "pkg/net-irc2-#{GEMSPEC.version}.gem")
55
+ }
56
+ s.Tag
57
+ s.Twitter
58
+ end
59
+
60
+ task 'AUTHORS.txt' do
61
+ File.open('AUTHORS.txt', 'w') do |f|
62
+ f.puts "Core Authors::"
63
+ f.puts `git shortlog -s -n lib`.gsub(/^\s*\d+\s*/, '')
64
+ f.puts
65
+ f.puts "Example Contributors::"
66
+ f.puts `git shortlog -s -n examples`.gsub(/^\s*\d+\s*/, '')
67
+ end
68
+ end
69
+
data/examples/2ch.rb ADDED
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+ $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
4
+
5
+ require 'uri'
6
+ require 'net/http'
7
+ require 'stringio'
8
+ require 'zlib'
9
+ require 'nkf'
10
+
11
+ class ThreadData
12
+ class UnknownThread < StandardError; end
13
+
14
+ attr_accessor :uri
15
+ attr_accessor :last_modified, :size
16
+
17
+ Line = Struct.new(:n, :name, :mail, :misc, :body, :opts, :id) do
18
+ def aa?
19
+ body = self.body
20
+ return false if body.count("\n") < 3
21
+
22
+ significants = body.scan(/[>\n0-9a-z0-9A-Za-zA-Zぁ-んァ-ン一-龠]/u).size.to_f
23
+ body_length = body.scan(/./u).size
24
+ is_aa = 1 - significants / body_length
25
+
26
+ is_aa > 0.6
27
+ end
28
+ end
29
+
30
+ def initialize(thread_uri)
31
+ @uri = URI(thread_uri)
32
+ _, _, _, @board, @num, = *@uri.path.split('/')
33
+ @dat = []
34
+ end
35
+
36
+ def length
37
+ @dat.length
38
+ end
39
+
40
+ def subject
41
+ retrieve(true) if @dat.size.zero?
42
+ self[1].opts || ""
43
+ end
44
+
45
+ def [](n)
46
+ l = @dat[n - 1]
47
+ return nil unless l
48
+ name, mail, misc, body, opts = * l.split(/<>/)
49
+ id = misc[/ID:([^\s]+)/, 1]
50
+
51
+ body.gsub!(/<br>/, "\n")
52
+ body.gsub!(/<[^>]+>/, "")
53
+ body.gsub!(/^\s+|\s+$/, "")
54
+ body.gsub!(/&(gt|lt|amp|nbsp);/) {|s|
55
+ { 'gt' => ">", 'lt' => "<", 'amp' => "&", 'nbsp' => " " }[$1]
56
+ }
57
+
58
+ Line.new(n, name, mail, misc, body, opts, id)
59
+ end
60
+
61
+ def dat
62
+ @num
63
+ end
64
+
65
+ def retrieve(force=false)
66
+ @dat = [] if @force
67
+
68
+ res = Net::HTTP.start(@uri.host, @uri.port) do |http|
69
+ req = Net::HTTP::Get.new('/%s/dat/%d.dat' % [@board, @num])
70
+ req['User-Agent'] = 'Monazilla/1.00 (2ig.rb/0.0e)'
71
+ req['Accept-Encoding'] = 'gzip' unless @size
72
+ unless force
73
+ req['If-Modified-Since'] = @last_modified if @last_modified
74
+ req['Range'] = "bytes=%d-" % @size if @size
75
+ end
76
+
77
+ http.request(req)
78
+ end
79
+
80
+ ret = nil
81
+ case res.code.to_i
82
+ when 200, 206
83
+ body = res.body
84
+ if res['Content-Encoding'] == 'gzip'
85
+ body = StringIO.open(body, 'rb') {|io| Zlib::GzipReader.new(io).read }
86
+ end
87
+
88
+ @last_modified = res['Last-Modified']
89
+ if res.code == '206'
90
+ @size += body.size
91
+ else
92
+ @size = body.size
93
+ end
94
+
95
+ body = NKF.nkf('-w', body)
96
+
97
+ curr = @dat.size + 1
98
+ @dat.concat(body.split(/\n/))
99
+ last = @dat.size
100
+
101
+ (curr..last).map {|n|
102
+ self[n]
103
+ }
104
+ when 416 # たぶん削除が発生
105
+ p ['416']
106
+ retrieve(true)
107
+ []
108
+ when 304 # Not modified
109
+ []
110
+ when 302 # dat 落ち
111
+ p ['302', res['Location']]
112
+ raise UnknownThread
113
+ else
114
+ p ['Unknown Status:', res.code]
115
+ []
116
+ end
117
+ end
118
+
119
+ def canonicalize_subject(subject)
120
+ subject.gsub(/[A-Za-z0-9]/u) {|c|
121
+ c.unpack("U*").map {|i| i - 65248 }.pack("U*")
122
+ }
123
+ end
124
+
125
+ def guess_next_thread
126
+ res = Net::HTTP.start(@uri.host, @uri.port) do |http|
127
+ req = Net::HTTP::Get.new('/%s/subject.txt' % @board)
128
+ req['User-Agent'] = 'Monazilla/1.00 (2ig.rb/0.0e)'
129
+ http.request(req)
130
+ end
131
+
132
+ recent_posted_threads = (900..999).inject({}) {|r,i|
133
+ line = self[i]
134
+ line.body.scan(%r|ttp://#{@uri.host}/test/read.cgi/[^/]+/\d+/|).each do |uri|
135
+ r["h#{uri}"] = i
136
+ end if line
137
+ r
138
+ }
139
+
140
+ current_subject = canonicalize_subject(self.subject)
141
+ current_thread_rev = current_subject.scan(/\d+/).map {|d| d.to_i }
142
+ current = current_subject.scan(/./u)
143
+
144
+ body = NKF.nkf('-w', res.body)
145
+ threads = body.split(/\n/).map {|l|
146
+ dat, rest = *l.split(/<>/)
147
+ dat.sub!(/\.dat$/, "")
148
+
149
+ uri = "http://#{@uri.host}/test/read.cgi/#{@board}/#{dat}/"
150
+
151
+ subject, n = */(.*?) \((\d+)\)/.match(rest).captures
152
+ canonical_subject = canonicalize_subject(subject)
153
+ thread_rev = canonical_subject[/\d+/].to_i
154
+
155
+ distance = (dat == self.dat) ? Float::MAX :
156
+ (subject == self.subject) ? 0 :
157
+ levenshtein(canonical_subject.scan(/./u), current)
158
+ continuous_num = current_thread_rev.find {|rev| rev == thread_rev - 1 }
159
+ appear_recent = recent_posted_threads[uri]
160
+
161
+ score = distance
162
+ score -= 10 if continuous_num
163
+ score -= 10 if appear_recent
164
+ score += 10 if dat.to_i < self.dat.to_i
165
+ {
166
+ :uri => uri,
167
+ :dat => dat,
168
+ :subject => subject,
169
+ :distance => distance,
170
+ :continuous_num => continuous_num,
171
+ :appear_recent => appear_recent,
172
+ :score => score.to_f
173
+ }
174
+ }.sort_by {|o|
175
+ o[:score]
176
+ }
177
+
178
+ threads
179
+ end
180
+
181
+ def levenshtein(a, b)
182
+ case
183
+ when a.empty?
184
+ b.length
185
+ when b.empty?
186
+ a.length
187
+ when a == b
188
+ 0
189
+ else
190
+ d = Array.new(a.length + 1) { |s|
191
+ Array.new(b.length + 1, 0)
192
+ }
193
+
194
+ (0..a.length).each do |i|
195
+ d[i][0] = i
196
+ end
197
+
198
+ (0..b.length).each do |j|
199
+ d[0][j] = j
200
+ end
201
+
202
+ (1..a.length).each do |i|
203
+ (1..b.length).each do |j|
204
+ cost = (a[i - 1] == b[j - 1]) ? 0 : 1
205
+ d[i][j] = [
206
+ d[i-1][j ] + 1,
207
+ d[i ][j-1] + 1,
208
+ d[i-1][j-1] + cost
209
+ ].min
210
+ end
211
+ end
212
+
213
+ d[a.length][b.length]
214
+ end
215
+ end
216
+ end
217
+
218
+ if __FILE__ == $0
219
+ require 'pp'
220
+ thread = ThreadData.new(ARGV[0])
221
+ pp thread.guess_next_thread.reverse
222
+
223
+ p thread.subject
224
+ end
225
+