]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - data/rbot/plugins/twitter.rb
markov: refactor triplet learning
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / twitter.rb
index 25ceb63a4ea0daeac179743d42f278bb9cb99104..ec5e3b92a474e36cf9565c3ac1f54f135eee8b28 100644 (file)
@@ -7,6 +7,7 @@
 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
 #
 # Copyright:: (C) 2007 Carter Parks
 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
 #
 # Copyright:: (C) 2007 Carter Parks
+# Copyright:: (C) 2007 Giuseppe Bilotta
 #
 # Users can setup their twitter username and password and then begin updating
 # twitter whenever
 #
 # Users can setup their twitter username and password and then begin updating
 # twitter whenever
@@ -18,6 +19,9 @@ class TwitterPlugin < Plugin
   Config.register Config::IntegerValue.new('twitter.status_count',
     :default => 1, :validate => Proc.new { |v| v > 0 && v <= 10},
     :desc => "Maximum number of status updates shown by 'twitter status'")
   Config.register Config::IntegerValue.new('twitter.status_count',
     :default => 1, :validate => Proc.new { |v| v > 0 && v <= 10},
     :desc => "Maximum number of status updates shown by 'twitter status'")
+  Config.register Config::IntegerValue.new('twitter.friends_status_count',
+    :default => 3, :validate => Proc.new { |v| v > 0 && v <= 10},
+    :desc => "Maximum number of status updates shown by 'twitter friends status'")
 
   def initialize
     super
 
   def initialize
     super
@@ -38,7 +42,7 @@ class TwitterPlugin < Plugin
 
   # return a help string when the bot is asked for help on this plugin
   def help(plugin, topic="")
 
   # return a help string when the bot is asked for help on this plugin
   def help(plugin, topic="")
-    return "twitter status [status] => updates your status on twitter | twitter identify [username] [password] => ties your nick to your twitter username and password"
+    return "twitter status [nick] => show nick's (or your) status, use 'twitter friends status [nick]' to also show the friends' timeline | twitter update [status] => updates your status on twitter | twitter identify [username] [password] => ties your nick to your twitter username and password | twitter actions [on|off] => enable/disable twitting of actions (/me does ...)"
   end
 
   # update the status on twitter
   end
 
   # update the status on twitter
@@ -46,6 +50,8 @@ class TwitterPlugin < Plugin
 
     nick = params[:nick] || @registry[m.sourcenick + "_username"]
 
 
     nick = params[:nick] || @registry[m.sourcenick + "_username"]
 
+    friends = params[:friends]
+
     if not nick
       m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
       return false
     if not nick
       m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
       return false
@@ -54,7 +60,19 @@ class TwitterPlugin < Plugin
     user = URI.escape(nick)
 
     count = @bot.config['twitter.status_count']
     user = URI.escape(nick)
 
     count = @bot.config['twitter.status_count']
-    uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
+    unless friends
+      uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
+    else
+      count = @bot.config['twitter.friends_status_count']
+      auth = ""
+      if m.private?
+        auth << URI.escape(@registry[m.sourcenick + "_username"])
+        auth << ":"
+        auth << URI.escape(@registry[m.sourcenick + "_password"])
+        auth << "@"
+      end
+      uri = "http://#{auth}twitter.com/statuses/friends_timeline/#{user}.xml"
+    end
 
     response = @bot.httputil.get(uri, :headers => @header, :cache => false)
     debug response
 
     response = @bot.httputil.get(uri, :headers => @header, :cache => false)
     debug response
@@ -65,23 +83,43 @@ class TwitterPlugin < Plugin
       begin
         rex = REXML::Document.new(response)
         rex.root.elements.each("status") { |st|
       begin
         rex = REXML::Document.new(response)
         rex.root.elements.each("status") { |st|
-          month, day, hour, min, sec, year = st.elements['created_at'].text.match(/\w+ (\w+) (\d+) (\d+):(\d+):(\d+) \S+ (\d+)/)[1..6]
-          debug [year, month, day, hour, min, sec].inspect
-          time = Time.local(year.to_i, month, day.to_i, hour.to_i, min.to_i, sec.to_i)
+          # month, day, hour, min, sec, year = st.elements['created_at'].text.match(/\w+ (\w+) (\d+) (\d+):(\d+):(\d+) \S+ (\d+)/)[1..6]
+          # debug [year, month, day, hour, min, sec].inspect
+          # time = Time.local(year.to_i, month, day.to_i, hour.to_i, min.to_i, sec.to_i)
+          time = Time.parse(st.elements['created_at'].text)
           now = Time.now
           now = Time.now
-          delta = now - time
+          # Sometimes, time can be in the future; invert the relation in this case
+          delta = ((time > now) ? time - now : now - time)
           msg = st.elements['text'].to_s + " (#{Utils.secs_to_string(delta.to_i)} ago via #{st.elements['source'].to_s})"
           msg = st.elements['text'].to_s + " (#{Utils.secs_to_string(delta.to_i)} ago via #{st.elements['source'].to_s})"
-          texts << Utils.decode_html_entities(msg).ircify_html
+          author = ""
+          if friends
+            author = Utils.decode_html_entities(st.elements['user'].elements['name'].text) + ": " rescue ""
+          end
+          texts << author+Utils.decode_html_entities(msg).ircify_html
         }
         }
+        if friends
+          # friends always return the latest 20 updates, so we clip the count
+          texts[count..-1]=nil
+        end
       rescue
         error $!
       rescue
         error $!
-        m.reply "could not parse status for #{nick}"
+        if friends
+          m.reply "could not parse status for #{nick}'s friends"
+        else
+          m.reply "could not parse status for #{nick}"
+        end
         return false
       end
       m.reply texts.reverse.join("\n")
       return true
     else
         return false
       end
       m.reply texts.reverse.join("\n")
       return true
     else
-      m.reply "could not get status for #{nick}"
+      if friends
+        rep = "could not get status for #{nick}'s friends"
+        rep << ", try asking in private" unless m.private?
+      else
+        rep = "could not get status for #{nick}"
+      end
+      m.reply rep
       return false
     end
   end
       return false
     end
   end
@@ -110,15 +148,18 @@ class TwitterPlugin < Plugin
       m.reply "your status message is longer than 140 characters, which is not optimal, but I'm going to update anyway"
     end
 
       m.reply "your status message is longer than 140 characters, which is not optimal, but I'm going to update anyway"
     end
 
-    body = "status=#{CGI.escape(msg)}"
+    source = "source=rbot"
+    msg = "status=#{CGI.escape(msg)}"
+    body = [source,msg].join("&")
 
     response = @bot.httputil.post(uri, body, :headers => @header)
     debug response
 
 
     response = @bot.httputil.post(uri, body, :headers => @header)
     debug response
 
+    reply_method = params[:notify] ? :notify : :reply
     if response.class == Net::HTTPOK
     if response.class == Net::HTTPOK
-      m.reply "status updated"
+      m.__send__(reply_method, "status updated")
     else
     else
-      m.reply "could not update status"
+      m.__send__(reply_method, "could not update status")
     end
   end
 
     end
   end
 
@@ -128,6 +169,31 @@ class TwitterPlugin < Plugin
     @registry[m.sourcenick + "_password"] = params[:password].to_s
     m.reply "you're all setup!"
   end
     @registry[m.sourcenick + "_password"] = params[:password].to_s
     m.reply "you're all setup!"
   end
+
+  # update on ACTION if the user has enabled the option
+  def ctcp_listen(m)
+    return unless m.action?
+    return unless @registry[m.sourcenick + "_actions"]
+    update_status(m, :status => m.message, :notify => true)
+  end
+
+  # show or toggle action twitting
+  def actions(m, params)
+    case params[:toggle]
+    when 'on'
+      @registry[m.sourcenick + "_actions"] = true
+      m.okay
+    when 'off'
+      @registry.delete(m.sourcenick + "_actions")
+      m.okay
+    else
+      if @registry[m.sourcenick + "_actions"]
+        m.reply _("actions will be twitted")
+      else
+        m.reply _("actions will not be twitted")
+      end
+    end
+  end
 end
 
 # create an instance of our plugin class and register for the "length" command
 end
 
 # create an instance of our plugin class and register for the "length" command
@@ -135,4 +201,6 @@ plugin = TwitterPlugin.new
 plugin.map 'twitter identify :username :password', :action => "identify", :public => false
 plugin.map 'twitter update *status', :action => "update_status", :threaded => true
 plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true
 plugin.map 'twitter identify :username :password', :action => "identify", :public => false
 plugin.map 'twitter update *status', :action => "update_status", :threaded => true
 plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true
+plugin.map 'twitter actions [:toggle]', :action => "actions", :requirements => { :toggle => /^on|off$/ }
+plugin.map 'twitter :friends [status] [:nick]', :action => "get_status", :requirements => { :friends => /^friends?$/ }, :threaded => true