net-irc2 0.0.10

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.
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
+