net-irc2 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
data/examples/2ig.rb ADDED
@@ -0,0 +1,267 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+
4
+ $LOAD_PATH << "lib"
5
+ $LOAD_PATH << "../lib"
6
+
7
+ $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
8
+
9
+ require "rubygems"
10
+ require "net/irc"
11
+ require "logger"
12
+ require "pathname"
13
+ require "yaml"
14
+ require 'uri'
15
+ require 'net/http'
16
+ require 'nkf'
17
+ require 'stringio'
18
+ require 'zlib'
19
+
20
+ require "#{Pathname.new(__FILE__).parent.expand_path}/2ch.rb"
21
+ Net::HTTP.version_1_2
22
+
23
+ class NiChannelIrcGateway < Net::IRC::Server::Session
24
+ def server_name
25
+ "2ch"
26
+ end
27
+
28
+ def server_version
29
+ "0.0.0"
30
+ end
31
+
32
+
33
+ def initialize(*args)
34
+ super
35
+ @channels = {}
36
+ end
37
+
38
+ def on_disconnected
39
+ @channels.each do |chan, info|
40
+ begin
41
+ info[:observer].kill if info[:observer]
42
+ rescue
43
+ end
44
+ end
45
+ end
46
+
47
+ def on_user(m)
48
+ super
49
+ @real, *@opts = @real.split(/\s+/)
50
+ @opts ||= []
51
+ end
52
+
53
+ def on_join(m)
54
+ channels = m.params.first.split(/,/)
55
+ channels.each do |channel|
56
+ @channels[channel] = {
57
+ :topic => "",
58
+ :dat => nil,
59
+ :interval => nil,
60
+ :observer => nil,
61
+ } unless @channels.key?(channel)
62
+ post @prefix, JOIN, channel
63
+ post nil, RPL_NAMREPLY, @prefix.nick, "=", channel, "@#{@prefix.nick}"
64
+ post nil, RPL_ENDOFNAMES, @prefix.nick, channel, "End of NAMES list"
65
+ end
66
+ end
67
+
68
+ def on_part(m)
69
+ channel = m.params[0]
70
+ if @channels.key?(channel)
71
+ info = @channels.delete(channel)
72
+ info[:observer].kill if info[:observer]
73
+ post @prefix, PART, channel
74
+ end
75
+ end
76
+
77
+ def on_privmsg(m)
78
+ target, mesg = *m.params
79
+ m.ctcps.each {|ctcp| on_ctcp(target, ctcp) } if m.ctcp?
80
+ end
81
+
82
+ def on_ctcp(target, mesg)
83
+ type, mesg = mesg.split(" ", 2)
84
+ method = "on_ctcp_#{type.downcase}".to_sym
85
+ send(method, target, mesg) if respond_to? method, true
86
+ end
87
+
88
+ def on_ctcp_action(target, mesg)
89
+ command, *args = mesg.split(" ")
90
+ command.downcase!
91
+
92
+ case command
93
+ when 'next'
94
+ if @channels.key?(target)
95
+ guess_next_thread(target)
96
+ end
97
+ end
98
+ rescue Exception => e
99
+ @log.error e.inspect
100
+ e.backtrace.each do |l|
101
+ @log.error "\t#{l}"
102
+ end
103
+ end
104
+
105
+ def on_topic(m)
106
+ channel, topic, = m.params
107
+ p m.params
108
+ if @channels.key?(channel)
109
+ info = @channels[channel]
110
+
111
+ unless topic
112
+ post nil, '332', channel, info[:topic]
113
+ return
114
+ end
115
+
116
+ uri, interval = *topic.split(/\s/)
117
+ interval = interval.to_i
118
+
119
+ post @prefix, TOPIC, channel, topic
120
+
121
+ case
122
+ when !info[:dat], uri != info[:dat].uri
123
+ post @prefix, NOTICE, channel, "Thread URL has been changed."
124
+ info[:dat] = ThreadData.new(uri)
125
+ create_observer(channel)
126
+ when info[:interval] != interval
127
+ post @prefix, NOTICE, channel, "Interval has been changed."
128
+ create_observer(channel)
129
+ end
130
+ info[:topic] = topic
131
+ info[:interval] = interval > 0 ? interval : 90
132
+ end
133
+ end
134
+
135
+ def guess_next_thread(channel)
136
+ info = @channels[channel]
137
+ post server_name, NOTICE, channel, "Current Thread: #{info[:dat].subject}"
138
+ threads = info[:dat].guess_next_thread
139
+ threads.first(3).each do |t|
140
+ if t[:continuous_num] && t[:appear_recent]
141
+ post server_name, NOTICE, channel, "#{t[:uri]} \003%d#{t[:subject]}\017" % 10
142
+ else
143
+ post server_name, NOTICE, channel, "#{t[:uri]} #{t[:subject]}"
144
+ end
145
+ end
146
+ threads
147
+ end
148
+
149
+ def create_observer(channel)
150
+ info = @channels[channel]
151
+ info[:observer].kill if info[:observer]
152
+
153
+ @log.debug "create_observer %s, interval %d" % [channel, info[:interval].to_i]
154
+ info[:observer] = Thread.start(info, channel) do |info, channel|
155
+ Thread.pass
156
+
157
+ loop do
158
+ begin
159
+ sleep info[:interval]
160
+ @log.debug "retrieving (interval %d) %s..." % [info[:interval], info[:dat].uri]
161
+ info[:dat].retrieve.last(100).each do |line|
162
+ priv_line channel, line
163
+ end
164
+
165
+ if info[:dat].length >= 1000
166
+ post server_name, NOTICE, channel, "Thread is over 1000. Guessing next thread..."
167
+ guess_next_thread(channel)
168
+ break
169
+ end
170
+ rescue UnknownThread
171
+ # pass
172
+ rescue Exception => e
173
+ @log.error "Error: #{e.inspect}"
174
+ e.backtrace.each do |l|
175
+ @log.error "\t#{l}"
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ def priv_line(channel, line)
183
+ post "%d{%s}" % [line.n, line.id], PRIVMSG, channel, line.aa?? encode_aa(line.body) : line.body
184
+ end
185
+
186
+ def encode_aa(aa)
187
+ uri = URI('http://tinyurl.com/api-create.php')
188
+ uri.query = 'url=' + URI.escape(<<-EOS.gsub(/[\n\t]/, ''))
189
+ data:text/html,<pre style='font-family:"IPA モナー Pゴシック"'>#{aa.gsub(/\n/, '<br>')}</pre>
190
+ EOS
191
+ Net::HTTP.get(uri.host, uri.request_uri, uri.port)
192
+ end
193
+ end
194
+
195
+ if __FILE__ == $0
196
+ require "optparse"
197
+
198
+ opts = {
199
+ :port => 16701,
200
+ :host => "localhost",
201
+ :log => nil,
202
+ :debug => false,
203
+ :foreground => false,
204
+ }
205
+
206
+ OptionParser.new do |parser|
207
+ parser.instance_eval do
208
+ self.banner = <<-EOB.gsub(/^\t+/, "")
209
+ Usage: #{$0} [opts]
210
+
211
+ EOB
212
+
213
+ separator ""
214
+
215
+ separator "Options:"
216
+ on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
217
+ opts[:port] = port
218
+ end
219
+
220
+ on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
221
+ opts[:host] = host
222
+ end
223
+
224
+ on("-l", "--log LOG", "log file") do |log|
225
+ opts[:log] = log
226
+ end
227
+
228
+ on("--debug", "Enable debug mode") do |debug|
229
+ opts[:log] = $stdout
230
+ opts[:debug] = true
231
+ end
232
+
233
+ on("-f", "--foreground", "run foreground") do |foreground|
234
+ opts[:log] = $stdout
235
+ opts[:foreground] = true
236
+ end
237
+
238
+ parse!(ARGV)
239
+ end
240
+ end
241
+
242
+ opts[:logger] = Logger.new(opts[:log], "daily")
243
+ opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
244
+
245
+ def daemonize(foreground=false)
246
+ trap("SIGINT") { exit! 0 }
247
+ trap("SIGTERM") { exit! 0 }
248
+ trap("SIGHUP") { exit! 0 }
249
+ return yield if $DEBUG || foreground
250
+ Process.fork do
251
+ Process.setsid
252
+ Dir.chdir "/"
253
+ File.open("/dev/null") {|f|
254
+ STDIN.reopen f
255
+ STDOUT.reopen f
256
+ STDERR.reopen f
257
+ }
258
+ yield
259
+ end
260
+ exit! 0
261
+ end
262
+
263
+ daemonize(opts[:debug] || opts[:foreground]) do
264
+ Net::IRC::Server.new(opts[:host], opts[:port], NiChannelIrcGateway, opts).start
265
+ end
266
+ end
267
+
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:fileencoding=UTF-8:
3
+
4
+ $LOAD_PATH << "lib"
5
+ $LOAD_PATH << "../lib"
6
+
7
+ require "rubygems"
8
+ require "net/irc"
9
+
10
+ require "pp"
11
+
12
+ class SimpleClient < Net::IRC::Client
13
+ def initialize(*args)
14
+ super
15
+ end
16
+ end
17
+
18
+ SimpleClient.new("foobar", "6667", {
19
+ :nick => "foobartest",
20
+ :user => "foobartest",
21
+ :real => "foobartest",
22
+ }).start
23
+
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+
4
+ $LOAD_PATH << "lib"
5
+ $LOAD_PATH << "../lib"
6
+
7
+ require "rubygems"
8
+ require "net/irc"
9
+
10
+ require "pp"
11
+
12
+ class EchoBot < Net::IRC::Client
13
+ def initialize(*args)
14
+ super
15
+ end
16
+
17
+ def on_rpl_welcome(m)
18
+ post JOIN, "#bot_test"
19
+ end
20
+
21
+ def on_privmsg(m)
22
+ post NOTICE, m[0], m[1]
23
+ end
24
+ end
25
+
26
+ EchoBot.new("foobar", "6667", {
27
+ :nick => "foobartest",
28
+ :user => "foobartest",
29
+ :real => "foobartest",
30
+ }).start
31
+
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+
4
+ $LOAD_PATH << "lib"
5
+ $LOAD_PATH << "../lib"
6
+
7
+ require "rubygems"
8
+ require "net/irc"
9
+
10
+ require "pp"
11
+
12
+ require 'celluloid/io'
13
+
14
+ class EchoBot < Net::IRC::Client
15
+ include Celluloid::IO
16
+ def on_rpl_welcome(m)
17
+ post JOIN, "#demo"
18
+ super
19
+ end
20
+
21
+ def on_privmsg(m)
22
+ post NOTICE, m[0], m[1]
23
+ end
24
+ end
25
+
26
+
27
+ supervisor = EchoBot.supervise_as :echo_bot, "127.0.0.1", "6667", {
28
+ :nick => "foo",
29
+ :user => "foo",
30
+ :real => "foobartest",
31
+ }
32
+ supervisor.actor.start!
33
+ sleep
data/examples/gig.rb ADDED
@@ -0,0 +1,192 @@
1
+ #!/usr/bin/env ruby
2
+ # vim:encoding=UTF-8:
3
+ =begin
4
+ # gig.rb
5
+
6
+ Github IRC Gateway
7
+
8
+ =end
9
+
10
+ $LOAD_PATH << "lib"
11
+ $LOAD_PATH << "../lib"
12
+
13
+ $KCODE = "u" unless defined? ::Encoding
14
+
15
+ require "rubygems"
16
+ require "net/irc"
17
+ require "net/https"
18
+ require "logger"
19
+ require "pathname"
20
+ require "libxml"
21
+ require "ostruct"
22
+ require 'time'
23
+
24
+ class ServerLogIrcGateway < Net::IRC::Server::Session
25
+ EVENTS = {
26
+ 'DownloadEvent' => '6',
27
+ 'GistEvent' => '10',
28
+ 'WatchEvent' => '15',
29
+ 'FollowEvent' => '15',
30
+ 'CreateEvent' => '13',
31
+ 'ForkEvent' => '3',
32
+ 'PushEvent' => '14',
33
+ }
34
+
35
+ def server_name
36
+ "github"
37
+ end
38
+
39
+ def server_version
40
+ "0.0.0"
41
+ end
42
+
43
+ def main_channel
44
+ @opts.main_channel || "#github"
45
+ end
46
+
47
+ def initialize(*args)
48
+ super
49
+ @last_retrieved = Time.now
50
+ @cert_store = OpenSSL::X509::Store.new
51
+ @cert_store.set_default_paths
52
+ end
53
+
54
+ def on_disconnected
55
+ @retrieve_thread.kill rescue nil
56
+ end
57
+
58
+ def on_user(m)
59
+ super
60
+ @real, *@opts = @real.split(/\s+/)
61
+ @opts = OpenStruct.new @opts.inject({}) {|r, i|
62
+ key, value = i.split("=", 2)
63
+ r.update key => case value
64
+ when nil then true
65
+ when /\A\d+\z/ then value.to_i
66
+ when /\A(?:\d+\.\d*|\.\d+)\z/ then value.to_f
67
+ else value
68
+ end
69
+ }
70
+ post @nick, JOIN, main_channel
71
+
72
+ @retrieve_thread = Thread.start do
73
+ loop do
74
+ begin
75
+ @log.info 'retrieveing feed...'
76
+ uri = URI.parse("https://github.com/#{@real}.private.atom?token=#{@pass}")
77
+ http = Net::HTTP.new(uri.host, uri.port)
78
+ http.use_ssl = true
79
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
80
+ http.cert_store = @cert_store
81
+ req = Net::HTTP::Get.new(uri.request_uri)
82
+ res = http.request(req)
83
+
84
+ doc = LibXML::XML::Document.string(res.body, :base_uri => uri.to_s)
85
+ ns = %w|a:http://www.w3.org/2005/Atom|
86
+ entries = []
87
+ doc.find('/a:feed/a:entry', ns).each do |n|
88
+ entries << {
89
+ :datetime => Time.parse(n.find('string(a:published)', ns)),
90
+ :id => n.find('string(a:id)', ns),
91
+ :title => n.find('string(a:title)', ns),
92
+ :author => n.find('string(a:author/a:name)', ns),
93
+ :link => n.find('string(a:link/@href)', ns),
94
+ }
95
+ end
96
+
97
+ entries.reverse_each do |entry|
98
+ next if entry[:datetime] <= @last_retrieved
99
+ type = entry[:id][%r|tag:github.com,2008:(.+?)/\d+|, 1]
100
+ post entry[:author], PRIVMSG, main_channel,
101
+ "\003#{EVENTS[type] || '5'}#{entry[:title]}\017 \00314#{entry[:link]}\017"
102
+ end
103
+
104
+ @last_retrieved = entries.first[:datetime]
105
+ @log.info 'sleep'
106
+ sleep 30
107
+ rescue Exception => e
108
+ @log.error e.inspect
109
+ e.backtrace.each do |l|
110
+ @log.error "\t#{l}"
111
+ end
112
+ sleep 10
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ if __FILE__ == $0
120
+ require "optparse"
121
+
122
+ opts = {
123
+ :port => 16705,
124
+ :host => "localhost",
125
+ :log => nil,
126
+ :debug => false,
127
+ :foreground => false,
128
+ }
129
+
130
+ OptionParser.new do |parser|
131
+ parser.instance_eval do
132
+ self.banner = <<-EOB.gsub(/^\t+/, "")
133
+ Usage: #{$0} [opts]
134
+
135
+ EOB
136
+
137
+ separator ""
138
+
139
+ separator "Options:"
140
+ on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
141
+ opts[:port] = port
142
+ end
143
+
144
+ on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
145
+ opts[:host] = host
146
+ end
147
+
148
+ on("-l", "--log LOG", "log file") do |log|
149
+ opts[:log] = log
150
+ end
151
+
152
+ on("--debug", "Enable debug mode") do |debug|
153
+ opts[:log] = $stdout
154
+ opts[:debug] = true
155
+ end
156
+
157
+ on("-f", "--foreground", "run foreground") do |foreground|
158
+ opts[:log] = $stdout
159
+ opts[:foreground] = true
160
+ end
161
+
162
+ parse!(ARGV)
163
+ end
164
+ end
165
+
166
+ opts[:logger] = Logger.new(opts[:log], "daily")
167
+ opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
168
+
169
+ def daemonize(foreground=false)
170
+ trap("SIGINT") { exit! 0 }
171
+ trap("SIGTERM") { exit! 0 }
172
+ trap("SIGHUP") { exit! 0 }
173
+ return yield if $DEBUG || foreground
174
+ Process.fork do
175
+ Process.setsid
176
+ Dir.chdir "/"
177
+ File.open("/dev/null") {|f|
178
+ STDIN.reopen f
179
+ STDOUT.reopen f
180
+ STDERR.reopen f
181
+ }
182
+ yield
183
+ end
184
+ exit! 0
185
+ end
186
+
187
+ daemonize(opts[:debug] || opts[:foreground]) do
188
+ Net::IRC::Server.new(opts[:host], opts[:port], ServerLogIrcGateway, opts).start
189
+ end
190
+ end
191
+
192
+