1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# List the twitter friends that are not friendfeed friends
# usage: ruby script_name.rb <twitter/friendfeed username> <twitter password>
# 2008-July-6 Don Park
require 'net/https'
require "rexml/document"
require 'rubygems'
begin
  gem 'json'
  require 'json'
rescue Gem::LoadError
  puts "the 'json' gem is missing. please run \"gem install json\""
  exit
end

class Twitter
  def initialize(username, password)
    @username = username
    @password = password
    @http = Net::HTTP.new("twitter.com")
  end

  def get(url)
    @http.start do |http|
      req = Net::HTTP::Get.new(url, {"User-Agent" => 
          "ruby net::http"})
      req.basic_auth(@username, @password)
      response = http.request(req)
      resp = response.body
      raise resp if response.is_a?(Net::HTTPNotFound)
      raise resp if response.is_a?(Net::HTTPUnauthorized)
      doc = REXML::Document.new(resp)
      err = doc.elements["hash/error"]
      raise err.text if err
      doc
    end     
  end

  def friends_count
    doc = get("/users/show/#{@username}.xml")
    doc.elements["user/friends_count"].text.to_i
  end

  def followers_count
    doc = get("/users/show/#{@username}.xml")
    doc.elements["user/followers_count"].text.to_i
  end

  def friends
    pages = (1..(friends_count / 100) + 1)
    friends = []
    pages.each do |page_number| 
      doc = get("/statuses/friends.xml?page=#{page_number}")
      friends << doc.elements.to_a("//user/screen_name").map{|s|s.text}
    end
    friends.flatten
  end
end

class FriendFeed
  def initialize(username, password=nil)
    @username = username
    @password = password
    @http = Net::HTTP.new("friendfeed.com")
  end

  def get(url)
    @http.start do |http|
      req = Net::HTTP::Get.new(url, {"User-Agent" => 
          "ruby net::http"})
      req.basic_auth(@username, @password)
      response = http.request(req)
      resp = response.body
      raise resp if response.is_a?(Net::HTTPNotFound)
      raise resp if response.is_a?(Net::HTTPUnauthorized)
      JSON::parse(resp)
    end     
  end

  def friends
    doc = get("/api/user/#{@username}/profile")
    doc["subscriptions"].map {|s| s["nickname"]}
  end
end

if ARGV.size != 2
  puts "twitter/friendfeed sync."
  puts "usage: #{$0} <twitter/friendfeed username> <twitter password>"
end
begin
  username = ARGV[0]
  twitter = Twitter.new(username, ARGV[1])
  tw_friends = twitter.friends
  puts "twitter user '#{username}: #{tw_friends.size} loaded"

  ff = FriendFeed.new(ARGV[0])
  ff_friends = ff.friends
#  puts "friendfeed user '#{username}': #{ff_friends.size} loaded"

  missing_tw_friends = tw_friends - ff_friends
  puts " #{missing_tw_friends.size} friends on twitter that are not on friendfeed: #{missing_tw_friends.join(',')}"
  
#  missing_ff_friends = ff_friends - tw_friends
#  puts " #{missing_ff_friends.size} friends on friendfeed that are not on twitter: #{missing_ff_friends.join(',')}"
  
rescue SocketError
  raise "Host " + host + " connection error"
rescue REXML::ParseException => e
  print "error parsing XML " + e.to_s
end