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 +7 -0
- data/AUTHORS.txt +33 -0
- data/ChangeLog +95 -0
- data/README +91 -0
- data/Rakefile +69 -0
- data/examples/2ch.rb +225 -0
- data/examples/2ig.rb +267 -0
- data/examples/client.rb +23 -0
- data/examples/echo_bot.rb +31 -0
- data/examples/echo_bot_celluloid.rb +33 -0
- data/examples/gig.rb +192 -0
- data/examples/gmail.rb +202 -0
- data/examples/gtig.rb +420 -0
- data/examples/hatena-star-stream.rb +270 -0
- data/examples/hcig.rb +285 -0
- data/examples/hig.rb +771 -0
- data/examples/iig.rb +819 -0
- data/examples/ircd.rb +358 -0
- data/examples/lig.rb +551 -0
- data/examples/lingr.rb +327 -0
- data/examples/mixi.rb +252 -0
- data/examples/sig.rb +188 -0
- data/examples/tig.rb +2712 -0
- data/lib/net/irc/client/channel_manager.rb +144 -0
- data/lib/net/irc/client.rb +117 -0
- data/lib/net/irc/constants.rb +214 -0
- data/lib/net/irc/message/modeparser.rb +85 -0
- data/lib/net/irc/message/serverconfig.rb +30 -0
- data/lib/net/irc/message.rb +109 -0
- data/lib/net/irc/pattern.rb +68 -0
- data/lib/net/irc/server.rb +186 -0
- data/lib/net/irc.rb +77 -0
- data/spec/channel_manager_spec.rb +184 -0
- data/spec/modeparser_spec.rb +165 -0
- data/spec/net-irc_spec.rb +337 -0
- data/spec/spec.opts +1 -0
- metadata +91 -0
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
|
+
|