Changeset 15038

Show
Ignore:
Timestamp:
07/02/08 13:50:14 (5 months ago)
Author:
drry
Message:
  • Replies 確認機能を追加しました。
  • 各ステータスの取得間隔の比率設定を追加しました。
    • 既定値は「10:3」で従来の20回、6回と同じです。
  • 現在の API 制限値を一時間毎に確認する機能を追加しました。
  • TypableMap のローマ字 ID 列を変更しました。
  • ソビエトロシアでは、エラーが wig.rb を起こす!
    • あとはよろしくお願いします。
  • ほか。
Location:
lang/ruby/net-irc/trunk/examples
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • lang/ruby/net-irc/trunk/examples/nig.rb

    r9422 r15038  
    7373        def jabber_bot_id 
    7474                nil 
     75        end 
     76 
     77        def hourly_limit 
     78                30 
    7579        end 
    7680end 
  • lang/ruby/net-irc/trunk/examples/tig.rb

    r14783 r15038  
    2424                host: localhost 
    2525                port: 16668 
    26                 name: username@example.com athack jabber=username@example.com:jabberpasswd tid=10 
     26                name: username@example.com athack jabber=username@example.com:jabberpasswd tid=10 ratio=32:1:6 replies 
    2727                password: password on Twitter 
    2828                in-encoding: utf8 
     
    6262        11 => lightcyan    cyan aqua 
    6363        12 => lightblue    royal 
    64         13 => pink         lightpurple  fuchsia 
     64        13 => pink         lightpurple fuchsia 
    6565        14 => grey 
    6666        15 => lightgrey    silver 
     
    7373 
    7474You must setup im notifing settings in the site and 
    75 install 'xmpp4r-simple' gem. 
     75install "xmpp4r-simple" gem. 
    7676 
    7777        $ sudo gem install xmpp4r-simple 
     
    8383Use IM instead of any APIs (ex. post) 
    8484 
    85  
    86 ## Licence 
     85### ratio=<timeline>:<friends>[:<replies>] 
     86 
     87### replies[=<ratio>] 
     88 
     89### checkrls[=<interval seconds>] 
     90 
     91## License 
    8792 
    8893Ruby's by cho45 
     
    135140        end 
    136141 
     142        def hourly_limit 
     143                20 
     144        end 
     145 
    137146        class ApiFailed < StandardError; end 
    138147 
     
    157166                        r.update(key => value) 
    158167                } 
    159                 @tmap   = TypableMap.new 
     168                @tmap = TypableMap.new 
    160169 
    161170                if @opts["jabber"] 
    162                         jid, pass = @opts["jabber"].split(/:/, 2) 
     171                        jid, pass = @opts["jabber"].split(":", 2) 
    163172                        @opts["jabber"].replace("jabber=#{jid}:********") 
    164173                        if jabber_bot_id 
     
    168177                                rescue LoadError 
    169178                                        log "Failed to start Jabber." 
    170                                         log "Installl 'xmpp4r-simple' gem or check your id/pass." 
     179                                        log 'Installl "xmpp4r-simple" gem or check your id/pass.' 
    171180                                        finish 
    172181                                end 
     
    179188                log "Client Options: #{@opts.inspect}" 
    180189                @log.info "Client Options: #{@opts.inspect}" 
     190 
     191                @hourly_limit = hourly_limit 
     192                @check_rate_limit_thread = Thread.start do 
     193                        loop do 
     194                                begin 
     195                                        check_rate_limit 
     196                                rescue ApiFailed => e 
     197                                        @log.error e.inspect 
     198                                rescue Exception => e 
     199                                        @log.error e.inspect 
     200                                        e.backtrace.each do |l| 
     201                                                @log.error "\t#{l}" 
     202                                        end 
     203                                end 
     204                                sleep @opts["checkrls"] || 3600 # 1 time / hour 
     205                        end 
     206                end 
     207                sleep 5 
     208 
     209                timeline_ratio, friends_ratio, replies_ratio = 
     210                        (@opts["ratio"] || "10:3").split(":", 3).map {|ratio| ratio.to_i } 
     211                footing = (timeline_ratio + friends_ratio).to_f 
     212                if @opts.key?("replies") 
     213                        replies_ratio ||= (@opts["replies"] || 5).to_i 
     214                        footing += replies_ratio 
     215                end 
    181216 
    182217                @timeline = [] 
     
    193228                                        end 
    194229                                end 
    195                                 sleep 10 * 60 # 6 times/hour 
    196                         end 
    197                 end 
     230                                sleep freq(friends_ratio / footing) 
     231                        end 
     232                end 
     233 
     234                return if @opts["jabber"] 
     235 
    198236                sleep 3 
    199  
    200                 return if @opts["jabber"] 
    201  
    202237                @check_timeline_thread = Thread.start do 
    203238                        loop do 
     
    213248                                        end 
    214249                                end 
    215                                 sleep 180 # 20 times/hour 
     250                                sleep freq(timeline_ratio / footing) 
     251                        end 
     252                end 
     253 
     254                return unless @opts.key?("replies") 
     255 
     256                sleep 10 
     257                @check_replies_thread = Thread.start do 
     258                        loop do 
     259                                begin 
     260                                        check_replies 
     261                                rescue ApiFailed => e 
     262                                        @log.error e.inspect 
     263                                rescue Exception => e 
     264                                        @log.error e.inspect 
     265                                        e.backtrace.each do |l| 
     266                                                @log.error "\t#{l}" 
     267                                        end 
     268                                end 
     269                                sleep freq(replies_ratio / footing) 
    216270                        end 
    217271                end 
     
    219273 
    220274        def on_disconnected 
    221                 @check_friends_thread.kill  rescue nil 
    222                 @check_timeline_thread.kill rescue nil 
    223                 @im_thread.kill             rescue nil 
    224                 @im.disconnect              rescue nil 
     275                @check_friends_thread.kill    rescue nil 
     276                @check_replies_thread.kill    rescue nil 
     277                @check_timeline_thread.kill   rescue nil 
     278                @check_rate_limit_thread.kill rescue nil 
     279                @im_thread.kill               rescue nil 
     280                @im.disconnect                rescue nil 
    225281        end 
    226282 
     
    262318                        nick = args[0] 
    263319                        @log.debug([ nick, message ]) 
    264                         res = api('statuses/user_timeline', { 'id' => nick }).reverse_each do |s| 
     320                        res = api("statuses/user_timeline", { "id" => nick }).reverse_each do |s| 
    265321                                @log.debug(s) 
    266322                                post nick, NOTICE, main_channel, "#{generate_status_message(s)}" 
     
    421477                @log.debug(mesg) 
    422478 
    423                 # added @user in no use @user reply message ( Wassr only ) 
    424                 if s.has_key?('reply_status_url') and s['reply_status_url'] and s['text'] !~ /^@.*/ and %r{([^/]+)/statuses/[^/]+}.match(s['reply_status_url']) 
     479                # added @user in no use @user reply message (Wassr only) 
     480                if s.has_key?("reply_status_url") and s["reply_status_url"] and s["text"] !~ /^@.*/ and %r{([^/]+)/statuses/[^/]+}.match(s["reply_status_url"]) 
    425481                        reply_user_id = $1 
    426482                        mesg = "@#{reply_user_id} #{mesg}" 
    427483                end 
    428                 # display area name(Wassr only) 
    429                 if s.has_key?('areaname') and s["areaname"] 
    430                         mesg += " L: #{s['areaname']}" 
    431                 end 
    432                 # display photo url(Wassr only) 
    433                 if s.has_key?('photo_url') and s["photo_url"] 
    434                         mesg += " #{s['photo_url']}" 
     484                # display area name (Wassr only) 
     485                if s.has_key?("areaname") and s["areaname"] 
     486                        mesg += " L: #{s["areaname"]}" 
     487                end 
     488                # display photo URL (Wassr only) 
     489                if s.has_key?("photo_url") and s["photo_url"] 
     490                        mesg += " #{s["photo_url"]}" 
    435491                end 
    436492 
     
    439495                mesg.gsub!(/(#{m.keys.join("|")})/) { m[$1] } 
    440496                mesg 
     497        end 
     498 
     499        def check_replies 
     500                @prev_time_r ||= Time.now 
     501                api("statuses/replies").reverse_each do |s| 
     502                        id = s["id"] || s["rid"] 
     503                        next if id.nil? || @timeline.include?(id) 
     504                        time = Time.parse(s["created_at"]) rescue next 
     505                        next if time < @prev_time_r 
     506                        @timeline << id 
     507                        nick = s["user_login_id"] || s["user"]["screen_name"] 
     508                        mesg = generate_status_message(s) 
     509 
     510                        tid = @tmap.push(s) 
     511 
     512                        @log.debug [id, nick, mesg] 
     513                        if @opts["tid"] 
     514                                message(nick, main_channel, "%s \x03%s [%s]" % [mesg, @opts["tid"], tid]) 
     515                        else 
     516                                message(nick, main_channel, "%s" % mesg) 
     517                        end 
     518                end 
     519                @log.debug "@timeline.size = #{@timeline.size}" 
     520                @timeline    = @timeline.last(100) 
     521                @prev_time_r = Time.now 
    441522        end 
    442523 
     
    465546                        now_friends = friends.map {|i| i["screen_name"] } 
    466547 
    467                         # twitter api bug? 
     548                        # Twitter api bug? 
    468549                        return if !first && (now_friends.length - prv_friends.length).abs > 10 
    469550 
     
    478559                        @friends = friends 
    479560                end 
     561        end 
     562 
     563        def check_rate_limit 
     564                @log.debug rate_limit = api("account/rate_limit_status") 
     565                if @hourly_limit != rate_limit["hourly_limit"] 
     566                        log "Rate limit changed: #{@hourly_limit} to #{rate_limit["hourly_limit"]}" 
     567                        @log.info "Rate limit changed: #{@hourly_limit} to #{rate_limit["hourly_limit"]}" 
     568                        @hourly_limit = rate_limit["hourly_limit"] 
     569                end 
     570                # rate_limit["remaining_hits"] < 1 
     571                # rate_limit["reset_time_in_seconds"] - Time.now.to_i 
     572        end 
     573 
     574        def freq(ratio) 
     575                ret = 3600 / (@hourly_limit * ratio).round 
     576                @log.debug "Frequency: #{ret}" 
     577                ret 
    480578        end 
    481579 
     
    532630        def api(path, q={}) 
    533631                ret     = {} 
    534                 header = { 
    535                         "User-Agent"               => @user_agent, 
    536                         "Authorization"            => "Basic " + ["#{@real}:#{@pass}"].pack("m"), 
    537 #                       "X-Twitter-Client"         => api_source, 
    538 #                       "X-Twitter-Client-Version" => server_version, 
    539 #                       "X-Twitter-Client-URL"     => "http://coderepos.org/share/browser/lang/ruby/misc/tig.rb", 
     632                headers = { 
     633                        "User-Agent"    => @user_agent, 
     634                        "Authorization" => "Basic " + ["#{@real}:#{@pass}"].pack("m"), 
    540635                } 
    541                 header["If-Modified-Since"]    = q["since"] if q.key?("since") 
     636                headers["If-Modified-Since"] = q["since"] if q.key?("since") 
    542637 
    543638                q["source"] ||= api_source 
    544639                q = q.inject([]) {|r,(k,v)| v.inject(r) {|r,i| r << "#{k}=#{URI.escape(i, /[^-.!~*'()\w]/n)}" } }.join("&") 
    545                 p q 
    546640 
    547641                uri = api_base.dup 
     
    558652                        case uri.path 
    559653                        when "/statuses/update.json", "/direct_messages/new.json" 
    560                                 ret = http.post(uri.request_uri, q, header) 
     654                                ret = http.post(uri.request_uri, q, headers) 
    561655                        else 
    562                                 ret = http.get(uri.request_uri, header) 
     656                                ret = http.get(uri.request_uri, headers) 
    563657                        end 
    564658                end 
     
    611705 
    612706        class TypableMap < Hash 
    613                 Roma = "a i u e o k g s z t d n h b p m y r w j v l q".split(/ /).map {|k| 
    614                         %w|a i u e o|.map {|v| "#{k}#{v}" } 
     707                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| 
     708                        case 
     709                        when consonant.size > 1, consonant == "y" 
     710                                %w|a u o| 
     711                        when consonant == "q" 
     712                                %w|a i e o| 
     713                        else 
     714                                %w|a i u e o| 
     715                        end.map {|vowel| "#{consonant}#{vowel}" } 
    615716                }.flatten 
    616717 
    617718                def initialize(size=1) 
    618                         @seq = Roma 
    619                         @map = {} 
    620                         @n   = 0 
     719                        @seq  = Roma 
     720                        @map  = {} 
     721                        @n    = 0 
    621722                        @size = size 
    622723                end 
     
    665766        OptionParser.new do |parser| 
    666767                parser.instance_eval do 
    667                         self.banner  = <<-EOB.gsub(/^\t+/, "") 
     768                        self.banner = <<-EOB.gsub(/^\t+/, "") 
    668769                                Usage: #{$0} [opts] 
    669770 
  • lang/ruby/net-irc/trunk/examples/wig.rb

    r13159 r15038  
    8787                "wassr-bot@wassr.jp" 
    8888        end 
     89 
     90        def hourly_limit 
     91                30 
     92        end 
    8993end 
    9094