net-irc 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
3
 
4
4
  $LOAD_PATH << "lib"
5
5
  $LOAD_PATH << "../lib"
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
3
 
4
4
  $LOAD_PATH << "lib"
5
5
  $LOAD_PATH << "../lib"
6
6
 
7
- $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
7
+ $KCODE = "u" unless defined? ::Encoding
8
8
 
9
9
  require "rubygems"
10
10
  require "net/irc"
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
3
  =begin
4
4
 
5
5
  ## Licence
@@ -11,7 +11,7 @@ Ruby's by cho45
11
11
  $LOAD_PATH << "lib"
12
12
  $LOAD_PATH << "../lib"
13
13
 
14
- $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
14
+ $KCODE = "u" unless defined? ::Encoding # json use this
15
15
 
16
16
  require "rubygems"
17
17
  require "json"
@@ -48,7 +48,10 @@ class HatenaStarStream < Net::IRC::Server::Session
48
48
  post server_name, MODE, main_channel, "+o", @prefix.nick
49
49
 
50
50
  @real, *@opts = @opts.name || @real.split(/\s+/)
51
- @opts ||= []
51
+ @opts = @opts.inject({}) {|r,i|
52
+ key, value = i.split("=")
53
+ r.update(key => value)
54
+ }
52
55
 
53
56
  start_observer
54
57
  end
@@ -115,7 +118,10 @@ class HatenaStarStream < Net::IRC::Server::Session
115
118
  end
116
119
  }
117
120
 
118
- post server_name, NOTICE, main_channel, "#{entry} #{title(entry)}" if s.length > 0
121
+ post server_name, NOTICE, main_channel, "#{entry} #{title(entry)}" if s.length > 0
122
+ if @opts.key?("metadata")
123
+ post "metadata", NOTICE, main_channel, JSON.generate({ "uri" => entry })
124
+ end
119
125
 
120
126
  s.each do |star|
121
127
  post server_name, NOTICE, main_channel, "id:%s \x03%d%s%s\x030 %s" % [
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
3
  =begin
4
4
  # hig.rb
5
5
 
@@ -90,7 +90,7 @@ Ruby's by cho45
90
90
  $LOAD_PATH << "lib"
91
91
  $LOAD_PATH << "../lib"
92
92
 
93
- $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
93
+ $KCODE = "u" unless defined? ::Encoding # json use this
94
94
 
95
95
  require "rubygems"
96
96
  require "net/irc"
@@ -227,7 +227,7 @@ class HaikuIrcGateway < Net::IRC::Server::Session
227
227
  end
228
228
 
229
229
  def on_privmsg(m)
230
- return m[1].ctcps.each {|ctcp| on_ctcp(m[0], ctcp) } if m.ctcp?
230
+ return m.ctcps.each {|ctcp| on_ctcp(m[0], ctcp) } if m.ctcp?
231
231
  retry_count = 3
232
232
  ret = nil
233
233
  target, message = *m.params
@@ -316,7 +316,7 @@ class HaikuIrcGateway < Net::IRC::Server::Session
316
316
  tid = args[0]
317
317
  st = @tmap[tid]
318
318
  if st
319
- st["link"] = (api_base + "/#{st["user"]["screen_name"]}/statuses/#{st["id"]}").to_s unless st["link"]
319
+ st["link"] = (api_base + "/#{st["user"]["screen_name"]}/#{st["id"]}").to_s unless st["link"]
320
320
  post nil, NOTICE, main_channel, st["link"]
321
321
  else
322
322
  post nil, NOTICE, main_channel, "No such id #{tid}"
@@ -343,6 +343,7 @@ class HaikuIrcGateway < Net::IRC::Server::Session
343
343
  end
344
344
 
345
345
  def on_join(m)
346
+ return ### なんかしらんけど何度も入ってしまってうざいので……
346
347
  channels = m.params[0].split(/\s*,\s*/)
347
348
  channels.each do |channel|
348
349
  next if channel == main_channel
@@ -426,6 +427,10 @@ class HaikuIrcGateway < Net::IRC::Server::Session
426
427
  else
427
428
  message(nick, channel, "%s" % [mesg, tid])
428
429
  end
430
+
431
+ if @opts.key?("metadata")
432
+ post "metadata", NOTICE, channel, JSON.generate({ "uri" => (api_base + "/#{s["user"]["screen_name"]}/#{s["id"]}").to_s })
433
+ end
429
434
  end
430
435
  rescue => e
431
436
  @log.debug "Error: %p" % e
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
+ $KCODE = "u" unless defined? ::Encoding # json use this
3
4
  =begin
4
5
 
5
6
  # iig.rb
@@ -100,7 +101,6 @@ Ruby's by cho45
100
101
  =end
101
102
 
102
103
  $LOAD_PATH << "lib" << "../lib"
103
- $KCODE = "u" if RUBY_VERSION < "1.9" # json use this
104
104
 
105
105
  require "rubygems"
106
106
  require "net/irc"
@@ -241,7 +241,7 @@ class IdenticaIrcGateway < Net::IRC::Server::Session
241
241
  end
242
242
 
243
243
  def on_privmsg(m)
244
- return m[1].ctcps.each {|ctcp| on_ctcp(m[0], ctcp) } if m.ctcp?
244
+ return m.ctcps.each {|ctcp| on_ctcp(m[0], ctcp) } if m.ctcp?
245
245
  retry_count = 3
246
246
  ret = nil
247
247
  target, message = *m.params
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # vim:fileencoding=UTF-8:
2
+ # vim:encoding=UTF-8:
3
3
 
4
4
  require 'rubygems'
5
5
  require 'net/irc'
@@ -0,0 +1,551 @@
1
+ #!/usr/bin/env ruby
2
+ =begin
3
+
4
+ # lig.rb
5
+
6
+ Lingr IRC Gateway - IRC Gateway to Lingr ( http://www.lingr.com/ )
7
+
8
+ ## Launch
9
+
10
+ $ ruby lig.rb # daemonized
11
+
12
+ If you want to help:
13
+
14
+ $ ruby lig.rb --help
15
+ Usage: examples/lig.rb [opts]
16
+
17
+
18
+ Options:
19
+ -p, --port [PORT=16669] port number to listen
20
+ -h, --host [HOST=localhost] host name or IP address to listen
21
+ -l, --log LOG log file
22
+ -a, --api_key API_KEY Your api key on Lingr
23
+ --debug Enable debug mode
24
+
25
+ ## Configuration
26
+
27
+ Configuration example for Tiarra ( http://coderepos.org/share/wiki/Tiarra ).
28
+
29
+ lingr {
30
+ host: localhost
31
+ port: 16669
32
+ name: username@example.com (Email on Lingr)
33
+ password: password on Lingr
34
+ in-encoding: utf8
35
+ out-encoding: utf8
36
+ }
37
+
38
+ Set your email as IRC 'real name' field, and password as server password.
39
+ This does not allow anonymous connection to Lingr.
40
+ You must create a account on Lingr and get API key (ask it first time).
41
+
42
+ ## Client
43
+
44
+ This gateway sends multibyte nicknames at Lingr rooms as-is.
45
+ So you should use a client which treats it correctly.
46
+
47
+ Recommended:
48
+
49
+ * LimeChat for OSX ( http://limechat.sourceforge.net/ )
50
+ * Irssi ( http://irssi.org/ )
51
+ * (gateway) Tiarra ( http://coderepos.org/share/wiki/Tiarra )
52
+
53
+ ## Nickname/Mask
54
+
55
+ nick -> nickname in a room.
56
+ o_id -> occupant_id (unique id in a room)
57
+ u_id -> user_id (unique user id in Lingr)
58
+
59
+ * Anonymous User: <nick>|<o_id>!anon@lingr.com
60
+ * Logged-in User: <nick>|<o_id>!<u_id>@lingr.com
61
+ * Your: <nick>|<u_id>!<u_id>@lingr.com
62
+
63
+ So you can see some nicknames in same user, but it is needed for
64
+ nickname management on client.
65
+
66
+ (Lingr allows different nicknames between rooms in a same user, but IRC not)
67
+
68
+ ## Licence
69
+
70
+ Ruby's by cho45
71
+
72
+ ## 備考
73
+
74
+ このクライアントで 1000speakers への応募はできません。lingr.com から行ってください。
75
+
76
+ =end
77
+
78
+ $LOAD_PATH << File.dirname(__FILE__)
79
+ $LOAD_PATH << "lib"
80
+ $LOAD_PATH << "../lib"
81
+
82
+ require "rubygems"
83
+ require "lingr"
84
+ require "net/irc"
85
+ require "pit"
86
+ require "mutex_m"
87
+
88
+
89
+ class LingrIrcGateway < Net::IRC::Server::Session
90
+ def server_name
91
+ "lingrgw"
92
+ end
93
+
94
+ def server_version
95
+ "0.0.0"
96
+ end
97
+
98
+ def initialize(*args)
99
+ super
100
+ @channels = {}
101
+ @channels.extend(Mutex_m)
102
+ end
103
+
104
+ def on_user(m)
105
+ super
106
+ @real, *@copts = @real.split(/\s+/)
107
+ @copts ||= []
108
+
109
+ # Tiarra sends prev nick when reconnects.
110
+ @nick.sub!(/\|.+$/, "")
111
+
112
+ log "Hello #{@nick}, this is Lingr IRC Gateway."
113
+ log "Client Option: #{@copts.join(", ")}"
114
+ @log.info "Client Option: #{@copts.join(", ")}"
115
+ @log.info "Client initialization is completed."
116
+
117
+ @lingr = Lingr::Client.new(@opts.api_key)
118
+ @lingr.create_session('human')
119
+ @lingr.login(@real, @pass)
120
+ @session_observer = Thread.start do
121
+ loop do
122
+ begin
123
+ @log.info "Verifying session..."
124
+ @log.info "Verifed session => #{@lingr.verify_session.inspect}"
125
+ rescue Lingr::Client::APIError => e
126
+ @log.info "Verify session raised APIError<#{e.code}:#{e.message}>. Try to re-create session."
127
+ @lingr.create_session('human')
128
+ @lingr.login(@real, @pass)
129
+ rescue Exception => e
130
+ @log.info "Error on verify_session: #{e.inspect}"
131
+ end
132
+ sleep 9 * 60
133
+ end
134
+ end
135
+ @user_info = @lingr.get_user_info
136
+
137
+ prefix = make_ids(@user_info)
138
+ @user_info["prefix"] = prefix
139
+ post @prefix, NICK, prefix.nick
140
+
141
+ rescue Lingr::Client::APIError => e
142
+ case e.code
143
+ when 105
144
+ post nil, ERR_PASSWDMISMATCH, @nick, "Password incorrect"
145
+ else
146
+ log "Error: #{e.code}: #{e.message}"
147
+ end
148
+ finish
149
+ end
150
+
151
+ def on_privmsg(m)
152
+ target, message = *m.params
153
+ if @channels.key?(target.downcase)
154
+ @lingr.say(@channels[target.downcase][:ticket], message)
155
+ else
156
+ post nil, ERR_NOSUCHNICK, @user_info["prefix"].nick, target, "No such nick/channel"
157
+ end
158
+ rescue Lingr::Client::APIError => e
159
+ log "Error: #{e.code}: #{e.message}"
160
+ log "Coundn't say to #{target}."
161
+ on_join(Message.new(nil, "JOIN", [target])) if e.code == 102 # invalid session
162
+ end
163
+
164
+ def on_notice(m)
165
+ on_privmsg(m)
166
+ end
167
+
168
+ def on_whois(m)
169
+ nick = m.params[0]
170
+ chan = nil
171
+ info = nil
172
+
173
+ @channels.each do |k, v|
174
+ if v[:users].key?(nick)
175
+ chan = k
176
+ info = v[:users][nick]
177
+ break
178
+ end
179
+ end
180
+
181
+ if chan
182
+ prefix = info["prefix"]
183
+ real_name = info["description"].to_s
184
+ server_info = "Lingr: type:#{info["client_type"]} source:#{info["source"]}"
185
+ channels = [info["client_type"] == "human" ? "@#{chan}" : chan]
186
+ me = @user_info["prefix"]
187
+
188
+ post nil, RPL_WHOISUSER, me.nick, prefix.nick, prefix.user, prefix.host, "*", real_name
189
+ post nil, RPL_WHOISSERVER, me.nick, prefix.nick, prefix.host, server_info
190
+ # post nil, RPL_WHOISOPERATOR, me.nick, prefix.nick, "is an IRC operator"
191
+ # post nil, RPL_WHOISIDLE, me.nick, prefix.nick, idle, "seconds idle"
192
+ post nil, RPL_WHOISCHANNELS, me.nick, prefix.nick, channels.join(" ")
193
+ post nil, RPL_ENDOFWHOIS, me.nick, prefix.nick, "End of WHOIS list"
194
+ else
195
+ post nil, ERR_NOSUCHNICK, me.nick, nick, "No such nick/channel"
196
+ end
197
+ rescue Exception => e
198
+ @log.error e.inspect
199
+ e.backtrace.each do |l|
200
+ @log.error "\t#{l}"
201
+ end
202
+ end
203
+
204
+ def on_who(m)
205
+ channel = m.params[0]
206
+ return unless channel
207
+
208
+ info = @channels.synchronize { @channels[channel.downcase] }
209
+ me = @user_info["prefix"]
210
+ res = @lingr.get_room_info(info[:chan_id], nil, info[:password])
211
+ res["occupants"].each do |o|
212
+ next unless o["nickname"]
213
+ u_id, o_id, prefix = *make_ids(o, true)
214
+ op = (o["client_type"] == "human") ? "@" : ""
215
+ post nil, RPL_WHOREPLY, me.nick, channel, o_id, "lingr.com", "lingr.com", prefix.nick, "H*#{op}", "0 #{o["description"].to_s.gsub(/\s+/, " ")}"
216
+ end
217
+ post nil, RPL_ENDOFWHO, me.nick, channel
218
+ rescue Lingr::Client::APIError => e
219
+ log "Maybe gateway don't know password for channel #{channel}. Please part and join."
220
+ end
221
+
222
+ def on_join(m)
223
+ channels = m.params[0].split(/\s*,\s*/)
224
+ password = m.params[1]
225
+ channels.each do |channel|
226
+ next if @channels.key? channel.downcase
227
+ begin
228
+ @log.debug "Enter room -> #{channel}"
229
+ res = @lingr.enter_room(channel.sub(/^#/, ""), @nick, password)
230
+ res["password"] = password
231
+
232
+ @channels.synchronize do
233
+ create_observer(channel, res)
234
+ end
235
+ rescue Lingr::Client::APIError => e
236
+ log "Error: #{e.code}: #{e.message}"
237
+ log "Coundn't join to #{channel}."
238
+ if e.code == 102
239
+ log "Invalid session... prompt the client to reconnect"
240
+ finish
241
+ end
242
+ rescue Exception => e
243
+ @log.error e.inspect
244
+ e.backtrace.each do |l|
245
+ @log.error "\t#{l}"
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ def on_part(m)
252
+ channel = m.params[0]
253
+ info = @channels[channel.downcase]
254
+ prefix = @user_info["prefix"]
255
+
256
+ if info
257
+ info[:observer].kill
258
+ @lingr.exit_room(info[:ticket])
259
+ @channels.delete(channel.downcase)
260
+
261
+ post prefix, PART, channel, "Parted"
262
+ else
263
+ post nil, ERR_NOSUCHCHANNEL, prefix.nick, channel, "No such channel"
264
+ end
265
+ rescue Lingr::Client::APIError => e
266
+ unless e.code == 102
267
+ log "Error: #{e.code}: #{e.message}"
268
+ log "Coundn't say to #{target}."
269
+
270
+ @channels.delete(channel.downcase)
271
+ post prefix, PART, channel, "Parted"
272
+ end
273
+ end
274
+
275
+ def on_disconnected
276
+ @channels.each do |k, info|
277
+ info[:observer].kill
278
+ end
279
+ @session_observer.kill rescue nil
280
+ begin
281
+ @lingr.destroy_session
282
+ rescue
283
+ end
284
+ end
285
+
286
+ private
287
+
288
+ def create_observer(channel, response)
289
+ Thread.start(channel, response) do |chan, res|
290
+ myprefix = @user_info["prefix"]
291
+ if @channels[chan.downcase]
292
+ @channels[chan.downcase][:observer].kill rescue nil
293
+ end
294
+ @channels[chan.downcase] = {
295
+ :ticket => res["ticket"],
296
+ :counter => res["room"]["counter"],
297
+ :o_id => res["occupant_id"],
298
+ :chan_id => res["room"]["id"],
299
+ :password => res["password"],
300
+ :users => res["occupants"].reject {|i| i["nickname"].nil? }.inject({}) {|r,i|
301
+ i["prefix"] = make_ids(i)
302
+ r.update(i["prefix"].nick => i)
303
+ },
304
+ :hcounter => 0,
305
+ :observer => Thread.current,
306
+ }
307
+
308
+ post server_name, TOPIC, chan, "#{res["room"]["url"]} #{res["room"]["description"]}"
309
+ post myprefix, JOIN, channel
310
+ post server_name, MODE, channel, "+o", myprefix.nick
311
+ post nil, RPL_NAMREPLY, myprefix.nick, "=", chan, @channels[chan.downcase][:users].map{|k,v|
312
+ v["client_type"] == "human" ? "@#{k}" : k
313
+ }.join(" ")
314
+ post nil, RPL_ENDOFNAMES, myprefix.nick, chan, "End of NAMES list"
315
+
316
+ info = @channels[chan.downcase]
317
+ while true
318
+ begin
319
+ @log.debug "observe_room<#{info[:counter]}><#{chan}> start <- #{myprefix}"
320
+ res = @lingr.observe_room info[:ticket], info[:counter]
321
+
322
+ info[:counter] = res["counter"] if res["counter"]
323
+
324
+ (res["messages"] || []).each do |m|
325
+ next if m["id"].to_i <= info[:hcounter]
326
+
327
+ u_id, o_id, prefix = *make_ids(m, true)
328
+
329
+ case m["type"]
330
+ when "user"
331
+ # Don't send my messages.
332
+ unless info[:o_id] == o_id
333
+ post prefix, PRIVMSG, chan, m["text"]
334
+ end
335
+ when "private"
336
+ # TODO not sent from lingr?
337
+ post prefix, PRIVMSG, chan, ctcp_encoding("ACTION Sent private: #{m["text"]}")
338
+
339
+ # system:{enter,leave,nickname_changed} should not be used for nick management.
340
+ # when "system:enter"
341
+ # post prefix, PRIVMSG, chan, ctcp_encoding("ACTION #{m["text"]}")
342
+ # when "system:leave"
343
+ # post prefix, PRIVMSG, chan, ctcp_encoding("ACTION #{m["text"]}")
344
+ # when "system:nickname_change"
345
+ # post prefix, PRIVMSG, chan, ctcp_encoding("ACTION #{m["text"]}")
346
+ when "system:broadcast"
347
+ post "system.broadcast", NOTICE, chan, m["text"]
348
+ end
349
+
350
+ info[:hcounter] = m["id"].to_i if m["id"]
351
+ end
352
+
353
+ if res["occupants"]
354
+ enter = [], leave = []
355
+ newusers = res["occupants"].reject {|i| i["nickname"].nil? }.inject({}) {|r,i|
356
+ i["prefix"] = make_ids(i)
357
+ r.update(i["prefix"].nick => i)
358
+ }
359
+
360
+
361
+ nickchange = newusers.inject({:new => [], :old => []}) {|r,(k,new)|
362
+ old = info[:users].find {|l,old|
363
+ # same occupant_id and different nickname
364
+ # when nickname was changed and when un-authed user promoted to authed user.
365
+ new["prefix"] != old["prefix"] && new["id"] == old["id"]
366
+ }
367
+ if old
368
+ old = old[1]
369
+ post old["prefix"], NICK, new["prefix"].nick
370
+ r[:old] << old["prefix"].nick
371
+ r[:new] << new["prefix"].nick
372
+ end
373
+ r
374
+ }
375
+
376
+ entered = newusers.keys - info[:users].keys - nickchange[:new]
377
+ leaved = info[:users].keys - newusers.keys - entered - nickchange[:old]
378
+
379
+ leaved.each do |leave|
380
+ leave = info[:users][leave]
381
+ post leave["prefix"], PART, chan, ""
382
+ end
383
+
384
+ entered.each do |enter|
385
+ enter = newusers[enter]
386
+ prefix = enter["prefix"]
387
+ post prefix, JOIN, chan
388
+ if enter["client_type"] == "human"
389
+ post server_name, MODE, chan, "+o", prefix.nick
390
+ end
391
+ end
392
+
393
+ info[:users] = newusers
394
+ end
395
+
396
+
397
+ rescue Lingr::Client::APIError => e
398
+ case e.code
399
+ when 100
400
+ @log.fatal "BUG: API returns invalid HTTP method"
401
+ exit 1
402
+ when 102
403
+ @log.error "BUG: API returns invalid session. Prompt the client to reconnect."
404
+ finish
405
+ when 104
406
+ @log.fatal "BUG: API returns invalid response format. JSON is unsupported?"
407
+ exit 1
408
+ when 109
409
+ @log.error "Error: API returns invalid ticket. Rejoin this channel..."
410
+ on_part(Message.new(nil, PART, [chan, res["error"]["message"]]))
411
+ on_join(Message.new(nil, JOIN, [chan, info["password"]]))
412
+ when 114
413
+ @log.fatal "BUG: API returns no counter parameter."
414
+ exit 1
415
+ when 120
416
+ @log.error "Error: API returns invalid encoding. But continues."
417
+ when 122
418
+ @log.error "Error: API returns repeated counter. But continues."
419
+ info[:counter] += 10
420
+ log "Error: repeated counter. Some message may be ignored..."
421
+ else
422
+ # may be socket error?
423
+ @log.debug "observe failed : #{res.inspect}"
424
+ log "Error: #{e.code}: #{e.message}"
425
+ end
426
+ rescue Timeout::Error
427
+ # pass
428
+ rescue JSON::ParserError => e
429
+ @log.error e
430
+ info[:counter] += 10
431
+ log "Error: JSON::ParserError Some message may be ignored..."
432
+ rescue Exception => e
433
+ @log.error e.inspect
434
+ e.backtrace.each do |l|
435
+ @log.error "\t#{l}"
436
+ end
437
+ end
438
+ sleep 1
439
+ end
440
+ end
441
+ end
442
+
443
+ def log(str)
444
+ str.gsub!(/\s/, " ")
445
+ begin
446
+ post nil, NOTICE, @user_info["prefix"].nick, str
447
+ rescue
448
+ post nil, NOTICE, @nick, str
449
+ end
450
+ end
451
+
452
+ def make_ids(o, ext=false)
453
+ u_id = o["user_id"] || "anon"
454
+ o_id = o["occupant_id"] || o["id"]
455
+ nick = (o["default_nickname"] || o["nickname"]).gsub(/\s+/, "")
456
+ if o["user_id"] == @user_info["user_id"]
457
+ nick << "|#{o["user_id"]}"
458
+ else
459
+ nick << "|#{o["user_id"] ? o_id : "_"+o_id}"
460
+ end
461
+ pref = Prefix.new("#{nick}!#{u_id}@lingr.com")
462
+ ext ? [u_id, o_id, pref] : pref
463
+ end
464
+ end
465
+
466
+
467
+ if __FILE__ == $0
468
+ require "rubygems"
469
+ require "optparse"
470
+ require "pit"
471
+
472
+ opts = {
473
+ :port => 16669,
474
+ :host => "localhost",
475
+ :log => nil,
476
+ :debug => false,
477
+ :foreground => false,
478
+ }
479
+
480
+ OptionParser.new do |parser|
481
+ parser.instance_eval do
482
+ self.banner = <<-EOB.gsub(/^\t+/, "")
483
+ Usage: #{$0} [opts]
484
+
485
+ EOB
486
+
487
+ separator ""
488
+
489
+ separator "Options:"
490
+ on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
491
+ opts[:port] = port
492
+ end
493
+
494
+ on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
495
+ opts[:host] = host
496
+ end
497
+
498
+ on("-l", "--log LOG", "log file") do |log|
499
+ opts[:log] = log
500
+ end
501
+
502
+ on("-a", "--api_key API_KEY", "Your api key on Lingr") do |key|
503
+ opts[:api_key] = key
504
+ end
505
+
506
+ on("--debug", "Enable debug mode") do |debug|
507
+ opts[:log] = $stdout
508
+ opts[:debug] = true
509
+ end
510
+
511
+ on("-f", "--foreground", "run foreground") do |foreground|
512
+ opts[:log] = $stdout
513
+ opts[:foreground] = true
514
+ end
515
+
516
+ parse!(ARGV)
517
+ end
518
+ end
519
+
520
+ opts[:logger] = Logger.new(opts[:log], "daily")
521
+ opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
522
+
523
+ def daemonize(foreground=false)
524
+ [:INT, :TERM, :HUP].each do |sig|
525
+ Signal.trap sig, "EXIT"
526
+ end
527
+ return yield if $DEBUG || foreground
528
+ Process.fork do
529
+ Process.setsid
530
+ Dir.chdir "/"
531
+ File.open("/dev/null") {|f|
532
+ STDIN.reopen f
533
+ STDOUT.reopen f, "w"
534
+ STDERR.reopen f, "w"
535
+ }
536
+ yield
537
+ end
538
+ exit! 0
539
+ end
540
+
541
+ opts[:api_key] = Pit.get("lig.rb", :require => {
542
+ "api_key" => "API key of Lingr"
543
+ })["api_key"] unless opts[:api_key]
544
+
545
+ daemonize(opts[:debug] || opts[:foreground]) do
546
+ Net::IRC::Server.new(opts[:host], opts[:port], LingrIrcGateway, opts).start
547
+ end
548
+
549
+ end
550
+
551
+