root/lang/ruby/net-irc/trunk/examples/wig.rb @ 18053

Revision 18053, 19.3 kB (checked in by cho45, 6 years ago)

変なときに reply のやつが走ってきもちわるいのでスペース必須に

  • Property svn:executable set to *
Line 
1#!/usr/bin/env ruby
2=begin
3
4# wig.rb
5
6wig.rb channel: http://wassr.jp/channel/wigrb
7
8## Launch
9
10        $ ruby wig.rb
11
12If you want to help:
13
14        $ ruby wig.rb --help
15
16## Configuration
17
18Options specified by after irc realname.
19
20Configuration example for Tiarra ( http://coderepos.org/share/wiki/Tiarra ).
21
22        wassr {
23                host: localhost
24                port: 16670
25                name: username@example.com athack jabber=username@example.com:jabberpasswd tid=10 ratio=10:3:5
26                password: password on Wassr
27                in-encoding: utf8
28                out-encoding: utf8
29        }
30
31### athack
32
33If `athack` client option specified,
34all nick in join message is leading with @.
35
36So if you complemente nicks (e.g. Irssi),
37it's good for Twitter like reply command (@nick).
38
39In this case, you will see torrent of join messages after connected,
40because NAMES list can't send @ leading nick (it interpreted op.)
41
42### tid=<color>
43
44Apply id to each message for make favorites by CTCP ACTION.
45
46        /me fav id
47
48<color> can be
49
50        0  => white
51        1  => black
52        2  => blue         navy
53        3  => green
54        4  => red
55        5  => brown        maroon
56        6  => purple
57        7  => orange       olive
58        8  => yellow
59        9  => lightgreen   lime
60        10 => teal
61        11 => lightcyan    cyan aqua
62        12 => lightblue    royal
63        13 => pink         lightpurple fuchsia
64        14 => grey
65        15 => lightgrey    silver
66
67
68### jabber=<jid>:<pass>
69
70If `jabber=<jid>:<pass>` option specified,
71use jabber to get friends timeline.
72
73You must setup im notifing settings in the site and
74install "xmpp4r-simple" gem.
75
76        $ sudo gem install xmpp4r-simple
77
78Be careful for managing password.
79
80### alwaysim
81
82Use IM instead of any APIs (e.g. post)
83
84### ratio=<timeline>:<friends>:<channel>
85
86## License
87
88Ruby's by cho45
89
90=end
91
92$LOAD_PATH << "lib"
93$LOAD_PATH << "../lib"
94
95$KCODE = "u" # json use this
96
97require "rubygems"
98require "net/irc"
99require "net/http"
100require "uri"
101require "json"
102require "socket"
103require "time"
104require "logger"
105require "yaml"
106require "pathname"
107require "cgi"
108require "digest/md5"
109
110Net::HTTP.version_1_2
111
112class WassrIrcGateway < Net::IRC::Server::Session
113        def server_name
114                "wassrgw"
115        end
116
117        def server_version
118                "0.0.0"
119        end
120
121        def main_channel
122                "#wassr"
123        end
124
125        def api_base
126                URI("http://api.wassr.jp/")
127        end
128
129        def api_source
130                "wig.rb"
131        end
132
133        def jabber_bot_id
134                "wassr-bot@wassr.jp"
135        end
136
137        def hourly_limit
138                60
139        end
140
141        class ApiFailed < StandardError; end
142
143        def initialize(*args)
144                super
145                @channels   = {}
146                @user_agent = "#{self.class}/#{server_version} (wig.rb)"
147                @map        = nil
148                @counters   = {} # for jabber fav
149        end
150
151        def on_user(m)
152                super
153                post @prefix, JOIN, main_channel
154                post server_name, MODE, main_channel, "+o", @prefix.nick
155
156                @real, *@opts = @opts.name || @real.split(/\s+/)
157                @opts = @opts.inject({}) {|r,i|
158                        key, value = i.split("=")
159                        r.update(key => value)
160                }
161                @tmap = TypableMap.new
162
163                if @opts["jabber"]
164                        jid, pass = @opts["jabber"].split(":", 2)
165                        @opts["jabber"].replace("jabber=#{jid}:********")
166                        if jabber_bot_id
167                                begin
168                                        require "xmpp4r-simple"
169                                        start_jabber(jid, pass)
170                                rescue LoadError
171                                        log "Failed to start Jabber."
172                                        log 'Installl "xmpp4r-simple" gem or check your id/pass.'
173                                        finish
174                                end
175                        else
176                                @opts.delete("jabber")
177                                log "This gateway does not support Jabber bot."
178                        end
179                end
180
181                log "Client Options: #{@opts.inspect}"
182                @log.info "Client Options: #{@opts.inspect}"
183
184                @ratio  = Struct.new(:timeline, :friends, :channel).new(*(@opts["ratio"] || "10:3:5").split(":").map {|ratio| ratio.to_f })
185                @footing = @ratio.inject {|r,i| r + i }
186
187                @timeline = []
188                @check_friends_thread = Thread.start do
189                        loop do
190                                begin
191                                        check_friends
192                                rescue ApiFailed => e
193                                        @log.error e.inspect
194                                rescue Exception => e
195                                        @log.error e.inspect
196                                        e.backtrace.each do |l|
197                                                @log.error "\t#{l}"
198                                        end
199                                end
200                                sleep freq(@ratio[:friends] / @footing)
201                        end
202                end
203
204                return if @opts["jabber"]
205
206                @check_timeline_thread = Thread.start do
207                        sleep 3
208                        loop do
209                                begin
210                                        check_timeline
211                                        # check_direct_messages
212                                rescue ApiFailed => e
213                                        @log.error e.inspect
214                                rescue Exception => e
215                                        @log.error e.inspect
216                                        e.backtrace.each do |l|
217                                                @log.error "\t#{l}"
218                                        end
219                                end
220                                sleep freq(@ratio[:timeline] / @footing)
221                        end
222                end
223
224                @check_channel_thread = Thread.start do
225                        sleep 5
226                        Thread.abort_on_exception= true
227                        loop do
228                                begin
229                                        check_channel
230                                        # check_direct_messages
231                                rescue ApiFailed => e
232                                        @log.error e.inspect
233                                rescue Exception => e
234                                        @log.error e.inspect
235                                        e.backtrace.each do |l|
236                                                @log.error "\t#{l}"
237                                        end
238                                end
239                                sleep freq(@ratio[:channel] / @footing)
240                        end
241                end
242        end
243
244        def on_disconnected
245                @check_friends_thread.kill  rescue nil
246                @check_timeline_thread.kill rescue nil
247                @check_channel_thread.kill  rescue nil
248                @im_thread.kill             rescue nil
249                @im.disconnect              rescue nil
250        end
251
252        def on_privmsg(m)
253                return on_ctcp(m[0], ctcp_decoding(m[1])) if m.ctcp?
254                retry_count = 3
255                ret = nil
256                target, message = *m.params
257                begin
258                        if target =~ /^#(.+)/
259                                channel = Regexp.last_match[1]
260                                reply   = message[/\s+>(.+)$/, 1]
261                                if !reply && @opts.key?("alwaysim") && @im && @im.connected? # in jabber mode, using jabber post
262                                        message = "##{channel} #{message}" unless "##{channel}" == main_channel
263                                        ret = @im.deliver(jabber_bot_id, message)
264                                        post "#{nick}!#{nick}@#{api_base.host}", TOPIC, channel, untinyurl(message)
265                                else
266                                        if "##{channel}" == main_channel
267                                                rid = rid_for(reply) if reply
268                                                ret = api("statuses/update", {"status" => message, "reply_status_rid" => rid})
269                                        else
270                                                ret = api("channel_message/update", {"name_en" => channel, "body" => message})
271                                        end
272                                        log "Status Updated via API"
273                                end
274                        else
275                                # direct message
276                                ret = api("direct_messages/new", {"user" => target, "text" => message})
277                        end
278                        raise ApiFailed, "API failed" unless ret
279                rescue => e
280                        @log.error [retry_count, e.inspect].inspect
281                        if retry_count > 0
282                                retry_count -= 1
283                                @log.debug "Retry to setting status..."
284                                retry
285                        else
286                                log "Some Error Happened on Sending #{message}. #{e}"
287                        end
288                end
289        end
290
291        def on_ctcp(target, message)
292                _, command, *args = message.split(/\s+/)
293                case command
294                when "list"
295                        nick = args[0]
296                        @log.debug([ nick, message ])
297                        res = api("statuses/user_timeline", { "id" => nick }).reverse_each do |s|
298                                @log.debug(s)
299                                post nick, NOTICE, main_channel, "#{generate_status_message(s)}"
300                        end
301
302                        unless res
303                                post server_name, ERR_NOSUCHNICK, nick, "No such nick/channel"
304                        end
305                when "fav"
306                        target = args[0]
307                        st  = @tmap[target]
308                        id  = rid_for(target)
309                        if st || id
310                                unless id
311                                        if @im && @im.connected?
312                                                # IM のときはいろいろめんどうなことする
313                                                nick, count = *st
314                                                pos = @counters[nick] - count
315                                                @log.debug "%p %s %d/%d => %d" % [
316                                                        st,
317                                                        nick,
318                                                        count,
319                                                        @counters[nick],
320                                                        pos
321                                                ]
322                                                res = api("statuses/user_timeline", { "id" => nick })
323                                                raise ApiFailed, "#{nick} may be private mode" if res.empty?
324                                                if res[pos]
325                                                        id = res[pos]["rid"]
326                                                else
327                                                        raise ApiFailed, "#{pos} of #{nick} is not found."
328                                                end
329                                        else
330                                                id = st["id"] || st["rid"]
331                                        end
332                                end
333                                res = api("favorites/create/#{id}", {})
334                                post server_name, NOTICE, main_channel, "Fav: #{res["screen_name"]}: #{res["text"]}"
335                        else
336                                post server_name, NOTICE, main_channel, "No such id or status #{target}"
337                        end
338                when "link"
339                        tid = args[0]
340                        st  = @tmap[tid]
341                        if st
342                                st["link"] = (api_base + "/#{st["user"]["screen_name"]}/statuses/#{st["id"]}").to_s unless st["link"]
343                                post server_name, NOTICE, main_channel, st["link"]
344                        else
345                                post server_name, NOTICE, main_channel, "No such id #{tid}"
346                        end
347                end
348        rescue ApiFailed => e
349                log e.inspect
350        end
351
352        def on_whois(m)
353                nick = m.params[0]
354                f = (@friends || []).find {|i| i["screen_name"] == nick }
355                if f
356                        post server_name, RPL_WHOISUSER,   @nick, nick, nick, api_base.host, "*", "#{f["name"]} / #{f["description"]}"
357                        post server_name, RPL_WHOISSERVER, @nick, nick, api_base.host, api_base.to_s
358                        post server_name, RPL_WHOISIDLE,   @nick, nick, "0", "seconds idle"
359                        post server_name, RPL_ENDOFWHOIS,  @nick, nick, "End of WHOIS list"
360                else
361                        post server_name, ERR_NOSUCHNICK, nick, "No such nick/channel"
362                end
363        end
364
365        def on_join(m)
366                channels = m.params[0].split(/\s*,\s*/)
367                channels.each do |channel|
368                        next if channel == main_channel
369                        res = api("channel/exists", { "name_en" => channel.sub(/^#/, "") })
370                        if res["exists"]
371                                @channels[channel] = {
372                                        :read => []
373                                }
374                                post "#{@nick}!#{@nick}@#{api_base.host}", JOIN, channel
375                        else
376                                post server_name, ERR_NOSUCHNICK, channel, "No such nick/channel"
377                        end
378                end
379        end
380
381        def on_part(m)
382                channel = m.params[0]
383                return if channel == main_channel
384                @channels.delete(channel)
385                post "#{@nick}!#{@nick}@#{api_base.host}", PART, channel
386        end
387
388        def on_who(m)
389                channel = m.params[0]
390                case
391                when channel == main_channel
392                        #     "<channel> <user> <host> <server> <nick>
393                        #         ( "H" / "G" > ["*"] [ ( "@" / "+" ) ]
394                        #             :<hopcount> <real name>"
395                        @friends.each do |f|
396                                user = nick = f["screen_name"]
397                                host = serv = api_base.host
398                                real = f["name"]
399                                post server_name, RPL_WHOREPLY, @nick, channel, user, host, serv, nick, "H*@", "0 #{real}"
400                        end
401                        post server_name, RPL_ENDOFWHO, @nick, channel
402                when @groups.key?(channel)
403                        @groups[channel].each do |name|
404                                f = @friends.find {|i| i["screen_name"] == name }
405                                user = nick = f["screen_name"]
406                                host = serv = api_base.host
407                                real = f["name"]
408                                post server_name, RPL_WHOREPLY, @nick, channel, user, host, serv, nick, "H*@", "0 #{real}"
409                        end
410                        post server_name, RPL_ENDOFWHO, @nick, channel
411                else
412                        post server_name, ERR_NOSUCHNICK, @nick, nick, "No such nick/channel"
413                end
414        end
415
416        private
417        def check_timeline
418                @prev_time ||= Time.at(0)
419                api("statuses/friends_timeline", {"since" => @prev_time.httpdate}).reverse_each do |s|
420                        id = s["id"] || s["rid"]
421                        next if id.nil? || @timeline.include?(id)
422                        @timeline << id
423                        nick = s["user_login_id"]
424                        mesg = generate_status_message(s)
425
426                        tid = @tmap.push(s)
427
428                        @log.debug [id, nick, mesg]
429                        if nick == @nick # 自分のときは topic に
430                                post "#{nick}!#{nick}@#{api_base.host}", TOPIC, main_channel, untinyurl(mesg)
431                        else
432                                if @opts["tid"]
433                                        message(nick, main_channel, "%s \x03%s [%s]" % [mesg, @opts["tid"], tid])
434                                else
435                                        message(nick, main_channel, "%s" % [mesg, tid])
436                                end
437                        end
438                end
439                @log.debug "@timeline.size = #{@timeline.size}"
440                @timeline  = @timeline.last(100)
441                @prev_time = Time.now
442        end
443
444        def check_channel
445                @channels.keys.each do |channel|
446                        @log.debug "getting channel -> #{channel}..."
447                        api("channel_message/list", { "name_en" => channel.sub(/^#/, "") }).reverse_each do |s|
448                                begin
449                                        id = Digest::MD5.hexdigest(s["user"]["login_id"] + s["body"])
450                                        next if @channels[channel][:read].include?(id)
451                                        @channels[channel][:read] << id
452                                        nick = s["user"]["login_id"]
453                                        mesg = s["body"]
454
455                                        if nick == @nick
456                                                post nick, NOTICE, channel, mesg
457                                        else
458                                                message(nick, channel, mesg)
459                                        end
460                                rescue Execepton => e
461                                        post server_name, NOTICE, channel, e.inspect
462                                end
463                        end
464                        @channels[channel][:read] = @channels[channel][:read].last(100)
465                end
466        end
467
468        def generate_status_message(status)
469                s = status
470                mesg = s["text"]
471                @log.debug(mesg)
472
473                # added @user in no use @user reply message (Wassr only)
474                if s.has_key?("reply_status_url") and s["reply_status_url"] and s["text"] !~ /^@.*/ and %r{([^/]+)/statuses/[^/]+}.match(s["reply_status_url"])
475                        reply_user_id = $1
476                        mesg = "@#{reply_user_id} #{mesg}"
477                end
478                # display area name (Wassr only)
479                if s.has_key?("areaname") and s["areaname"]
480                        mesg += " L: #{s["areaname"]}"
481                end
482                # display photo URL (Wassr only)
483                if s.has_key?("photo_url") and s["photo_url"]
484                        mesg += " #{s["photo_url"]}"
485                end
486
487                # time = Time.parse(s["created_at"]) rescue Time.now
488                m = { "&quot;" => "\"", "&lt;"=> "<", "&gt;"=> ">", "&amp;"=> "&", "\n" => " "}
489                mesg.gsub!(/(#{m.keys.join("|")})/) { m[$1] }
490                mesg
491        end
492
493        def check_direct_messages
494                @prev_time_d ||= Time.now
495                api("direct_messages", {"since" => @prev_time_d.httpdate}).reverse_each do |s|
496                        nick = s["sender_screen_name"]
497                        mesg = s["text"]
498                        time = Time.parse(s["created_at"])
499                        @log.debug [nick, mesg, time].inspect
500                        message(nick, @nick, mesg)
501                end
502                @prev_time_d = Time.now
503        end
504
505        def check_friends
506                first = true unless @friends
507                @friends ||= []
508                friends = api("statuses/friends")
509                if first && !@opts.key?("athack")
510                        @friends = friends
511                        post server_name, RPL_NAMREPLY,   @nick, "=", main_channel, @friends.map{|i| "@#{i["screen_name"]}" }.join(" ")
512                        post server_name, RPL_ENDOFNAMES, @nick, main_channel, "End of NAMES list"
513                else
514                        prv_friends = @friends.map {|i| i["screen_name"] }
515                        now_friends = friends.map {|i| i["screen_name"] }
516
517                        # Twitter API bug?
518                        return if !first && (now_friends.length - prv_friends.length).abs > 10
519
520                        (now_friends - prv_friends).each do |join|
521                                join = "@#{join}" if @opts.key?("athack")
522                                post "#{join}!#{join}@#{api_base.host}", JOIN, main_channel
523                        end
524                        (prv_friends - now_friends).each do |part|
525                                part = "@#{part}" if @opts.key?("athack")
526                                post "#{part}!#{part}@#{api_base.host}", PART, main_channel, ""
527                        end
528                        @friends = friends
529                end
530        end
531
532        def freq(ratio)
533                ret = 3600 / (hourly_limit * ratio).round
534                @log.debug "Frequency: #{ret}"
535                ret
536        end
537
538        def start_jabber(jid, pass)
539                @log.info "Logging-in with #{jid} -> jabber_bot_id: #{jabber_bot_id}"
540                @im = Jabber::Simple.new(jid, pass)
541                @im.add(jabber_bot_id)
542                @im_thread = Thread.start do
543                        loop do
544                                begin
545                                        @im.received_messages.each do |msg|
546                                                @log.debug [msg.from, msg.body]
547                                                if msg.from.strip == jabber_bot_id
548                                                        # Wassr -> 'nick(id): msg'
549                                                        body = msg.body.sub(/^(.+?)(?:\((.+?)\))?: /, "")
550                                                        if Regexp.last_match
551                                                                nick, id = Regexp.last_match.captures
552                                                                body = CGI.unescapeHTML(body)
553
554                                                                case
555                                                                when nick == "投稿完了"
556                                                                        log "#{nick}: #{body}"
557                                                                when nick == "チャンネル投稿完了"
558                                                                        log "#{nick}: #{body}"
559                                                                when body =~ /^#([a-z_]+)\s+(.+)$/i
560                                                                        # channel message or not
561                                                                        message(id || nick, "##{Regexp.last_match[1]}", Regexp.last_match[2])
562                                                                when nick == "photo" && body =~ %r|^http://wassr\.jp/user/([^/]+)/|
563                                                                        nick = Regexp.last_match[1]
564                                                                        message(nick, main_channel, body)
565                                                                else
566                                                                        @counters[nick] ||= 0
567                                                                        @counters[nick] += 1
568                                                                        tid = @tmap.push([nick, @counters[nick]])
569                                                                        message(nick, main_channel, "%s \x03%s [%s]" % [body, @opts["tid"], tid])
570                                                                end
571                                                        end
572                                                end
573                                        end
574                                rescue Exception => e
575                                        @log.error "Error on Jabber loop: #{e.inspect}"
576                                        e.backtrace.each do |l|
577                                                @log.error "\t#{l}"
578                                        end
579                                end
580                                sleep 1
581                        end
582                end
583        end
584
585        def require_post?(path)
586                [
587                        "statuses/update",
588                        "direct_messages/new",
589                        "channel_message/update",
590                        %r|^favorites/create|,
591                ].any? {|i| i === path }
592        end
593
594        def api(path, q={})
595                ret           = {}
596                q["source"] ||= api_source
597
598                uri = api_base.dup
599                uri.path  = "/#{path}.json"
600                uri.query = q.inject([]) {|r,(k,v)| v ? r << "#{k}=#{URI.escape(v, /[^-.!~*'()\w]/n)}" : r }.join("&")
601
602
603                req = nil
604                if require_post?(path)
605                        req = Net::HTTP::Post.new(uri.path)
606                        req.body = uri.query
607                else
608                        req = Net::HTTP::Get.new(uri.request_uri)
609                end
610                req.basic_auth(@real, @pass)
611                req["User-Agent"]        = @user_agent
612                req["If-Modified-Since"] = q["since"] if q.key?("since")
613
614                @log.debug uri.inspect
615                ret = Net::HTTP.start(uri.host, uri.port) { |http| http.request(req) }
616
617                case ret
618                when Net::HTTPOK # 200
619                        ret = JSON.parse(ret.body.gsub(/'(y(?:es)?|no?|true|false|null)'/, '"\1"'))
620                        raise ApiFailed, "Server Returned Error: #{ret["error"]}" if ret.kind_of?(Hash) && ret["error"]
621                        ret
622                when Net::HTTPNotModified # 304
623                        []
624                when Net::HTTPBadRequest # 400
625                        # exceeded the rate limitation
626                        raise ApiFailed, "#{ret.code}: #{ret.message}"
627                else
628                        raise ApiFailed, "Server Returned #{ret.code} #{ret.message}"
629                end
630        rescue Errno::ETIMEDOUT, JSON::ParserError, IOError, Timeout::Error, Errno::ECONNRESET => e
631                raise ApiFailed, e.inspect
632        end
633
634        def message(sender, target, str)
635                str    = untinyurl(str)
636                sender = "#{sender}!#{sender}@#{api_base.host}"
637                post sender, PRIVMSG, target, str
638        end
639
640        def log(str)
641                str.gsub!(/\n/, " ")
642                post server_name, NOTICE, main_channel, str
643        end
644
645        def untinyurl(text)
646                text.gsub(%r|http://(preview\.)?tinyurl\.com/[0-9a-z=]+|i) {|m|
647                        uri = URI(m)
648                        uri.host = uri.host.sub($1, "") if $1
649                        Net::HTTP.start(uri.host, uri.port) {|http|
650                                http.open_timeout = 3
651                                begin
652                                        http.head(uri.request_uri, { "User-Agent" => @user_agent })["Location"] || m
653                                rescue Timeout::Error
654                                        m
655                                end
656                        }
657                }
658        end
659
660        # return rid of most recent matched status with text
661        def rid_for(text)
662                target = Regexp.new(Regexp.quote(text.strip), "i")
663                status = api("statuses/friends_timeline").find {|i|
664                        next false if i["user_login_id"] == @nick # 自分は除外
665                        i["text"] =~ target
666                }
667
668                @log.debug "Looking up status contains #{text.inspect} -> #{status.inspect}"
669                status ? status["rid"] : nil
670        end
671
672        class TypableMap < Hash
673                Roma = %w|k g ky gy s z sh j t d ch n ny h b p hy by py m my y r ry w v q|.unshift("").map {|consonant|
674                        case
675                        when consonant.size > 1, consonant == "y"
676                                %w|a u o|
677                        when consonant == "q"
678                                %w|a i e o|
679                        else
680                                %w|a i u e o|
681                        end.map {|vowel| "#{consonant}#{vowel}" }
682                }.flatten
683
684                def initialize(size=1)
685                        @seq  = Roma
686                        @map  = {}
687                        @n    = 0
688                        @size = size
689                end
690
691                def generate(n)
692                        ret = []
693                        begin
694                                n, r = n.divmod(@seq.size)
695                                ret << @seq[r]
696                        end while n > 0
697                        ret.reverse.join
698                end
699
700                def push(obj)
701                        id = generate(@n)
702                        self[id] = obj
703                        @n += 1
704                        @n = @n % (@seq.size ** @size)
705                        id
706                end
707                alias << push
708
709                def clear
710                        @n = 0
711                        super
712                end
713
714                private :[]=
715                undef update, merge, merge!, replace
716        end
717
718
719end
720
721if __FILE__ == $0
722        require "optparse"
723
724        opts = {
725                :port  => 16670,
726                :host  => "localhost",
727                :log   => nil,
728                :debug => false,
729                :foreground => false,
730        }
731
732        OptionParser.new do |parser|
733                parser.instance_eval do
734                        self.banner = <<-EOB.gsub(/^\t+/, "")
735                                Usage: #{$0} [opts]
736
737                        EOB
738
739                        separator ""
740
741                        separator "Options:"
742                        on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
743                                opts[:port] = port
744                        end
745
746                        on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
747                                opts[:host] = host
748                        end
749
750                        on("-l", "--log LOG", "log file") do |log|
751                                opts[:log] = log
752                        end
753
754                        on("--debug", "Enable debug mode") do |debug|
755                                opts[:log]   = $stdout
756                                opts[:debug] = true
757                        end
758
759                        on("-f", "--foreground", "run foreground") do |foreground|
760                                opts[:log]        = $stdout
761                                opts[:foreground] = true
762                        end
763
764                        on("-n", "--name [user name or email address]") do |name|
765                                opts[:name] = name
766                        end
767
768                        parse!(ARGV)
769                end
770        end
771
772        opts[:logger] = Logger.new(opts[:log], "daily")
773        opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
774
775#       def daemonize(foreground=false)
776#               trap("SIGINT")  { exit! 0 }
777#               trap("SIGTERM") { exit! 0 }
778#               trap("SIGHUP")  { exit! 0 }
779#               return yield if $DEBUG || foreground
780#               Process.fork do
781#                       Process.setsid
782#                       Dir.chdir "/"
783#                       File.open("/dev/null") {|f|
784#                               STDIN.reopen  f
785#                               STDOUT.reopen f
786#                               STDERR.reopen f
787#                       }
788#                       yield
789#               end
790#               exit! 0
791#       end
792
793#       daemonize(opts[:debug] || opts[:foreground]) do
794                Net::IRC::Server.new(opts[:host], opts[:port], WassrIrcGateway, opts).start
795#       end
796end
797
798# Local Variables:
799# coding: utf-8
800# End:
Note: See TracBrowser for help on using the browser.