#
# Copyright (c) 2007 Naoki Hiroshima
# You can redistribute it and/or modify it under the same terms as Ruby.
#
# Author:: Naoki Hiroshima <n at h7a dot org>

require 'time'
require 'net/http'
require 'rexml/document'
require 'Growl'

@@user = 'foo@example.com'
@@pass = 'bar'
@@freq = 1 # in minute

class TwitterGrowler
  def initialize(user, pass, freq=5)
    @user = user
    @pass = pass
    @freq = freq
    @icons = {}
    @growl = GrowlNotifier.new('Twitter', ["message"], nil, nil)
    @growl.register
    @updated = Time.now - 3600
  end

  def run
    while true
      update
      sleep @freq * 60
    end
  end

  def get(method='friends', since=nil)
    begin
      Net::HTTP.version_1_2
      page = "/statuses/#{method}_timeline.xml"
      page += "?since=#{urlencode(since.httpdate)}" if since
      req = Net::HTTP::Get.new(page);
      req.basic_auth @user, @pass
      Net::HTTP.start('twitter.com', 80) {|http|
        response = http.request(req)
        response.body
      }
    rescue Exception
    end
  end

  def update
    xml = get 'friends', @updated
    doc = REXML::Document.new xml
    doc.elements.each('statuses/status') { |i|
      msg = i.elements['text'].text
      name = i.elements['user/name'].text
      nick = i.elements['user/screen_name'].text
      icon_url = i.elements['user/profile_image_url'].text

      unless @icons[icon_url]
        nsurl = OSX::NSURL.URLWithString_(icon_url)
        @icons[icon_url] = OSX::NSImage.alloc.initWithContentsOfURL(nsurl)
      end

      @growl.notify("message", "#{name} (#{nick})", msg, @icons[icon_url])
    }

    @updated = Time.now
  end

  def urlencode(s)
    s.gsub( /[^a-zA-Z0-9\-_\.!~*'()]/n ) {|x| sprintf('%%%02x', x[0]) }
  end
end

t = TwitterGrowler.new @@user, @@pass, @@freq
t.run
