chirpstream 0.0.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/Gemfile.lock +13 -1
- data/Readme.rdoc +29 -20
- data/VERSION +1 -1
- data/bin/chirp_growl +4 -4
- data/lib/chirpstream.rb +121 -122
- data/lib/chirpstream/connect.rb +62 -0
- data/lib/chirpstream/event/direct_message.rb +1 -0
- data/lib/chirpstream/event/unfavorite.rb +8 -0
- data/lib/chirpstream/twitter_object.rb +13 -13
- data/lib/chirpstream/user.rb +2 -2
- metadata +5 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -8,6 +8,14 @@ dependencies:
|
|
8
8
|
group:
|
9
9
|
- :default
|
10
10
|
version: ">= 0"
|
11
|
+
growl:
|
12
|
+
group:
|
13
|
+
- :default
|
14
|
+
version: ">= 0"
|
15
|
+
json:
|
16
|
+
group:
|
17
|
+
- :default
|
18
|
+
version: ">= 0"
|
11
19
|
em-http-request:
|
12
20
|
group:
|
13
21
|
- :default
|
@@ -33,6 +41,10 @@ specs:
|
|
33
41
|
version: 0.12.10
|
34
42
|
- em-http-request:
|
35
43
|
version: 0.2.7
|
44
|
+
- growl:
|
45
|
+
version: 1.0.3
|
46
|
+
- json:
|
47
|
+
version: 1.4.3
|
36
48
|
- load_path_find:
|
37
49
|
version: 0.0.5
|
38
50
|
- oauth:
|
@@ -41,7 +53,7 @@ specs:
|
|
41
53
|
version: 1.0.4
|
42
54
|
- yajl-ruby:
|
43
55
|
version: 0.7.6
|
44
|
-
hash:
|
56
|
+
hash: 751ca486a5dabecc00361525588fc94f8bf428d9
|
45
57
|
sources:
|
46
58
|
- Rubygems:
|
47
59
|
uri: http://gemcutter.org
|
data/Readme.rdoc
CHANGED
@@ -19,26 +19,35 @@ Wow! It's growling my tweets! How meta.
|
|
19
19
|
require 'chirpstream'
|
20
20
|
require 'rainbow'
|
21
21
|
|
22
|
-
chirp = Chirpstream.new
|
23
|
-
chirp.
|
24
|
-
chirp.
|
25
|
-
chirp.
|
26
|
-
chirp.
|
27
|
-
chirp.
|
28
|
-
chirp.
|
29
|
-
chirp.connect
|
22
|
+
chirp = Chirpstream.new
|
23
|
+
chirp.on_reconnect{ puts "reconnecting..." }
|
24
|
+
chirp.on_tweet {|t, u| puts "#{t.text} (from #{t.user.name.foreground(:red)} (#{('@' + t.user.screen_name).foreground(:green)}))" }
|
25
|
+
chirp.on_follow {|t, u| puts "#{t.source.screen_name.foreground(:green)} following #{t.target.screen_name.foreground(:green)}" }
|
26
|
+
chirp.on_favorite {|t, u| puts "#{t.source.screen_name.foreground(:green)} <3 -> #{t.target_object.text}" }
|
27
|
+
chirp.on_retweet {|t, u| puts "#{t.source.screen_name.foreground(:green)} RT -> #{t.target_object.text}" }
|
28
|
+
chirp.on_direct_message {|t, u| puts "DM : #{t.text} (from #{t.sender.name.foreground(:red)} (#{('@' + t.sender.screen_name).foreground(:green)}))" }
|
29
|
+
chirp.connect(Chirpstream::Connect::User.basic('joshbuddy', 'xxxxxxxx'))
|
30
30
|
|
31
31
|
== Oauth Usage
|
32
32
|
|
33
|
-
chirp = Chirpstream.
|
34
|
-
chirp.
|
35
|
-
chirp.
|
36
|
-
chirp.
|
37
|
-
chirp.
|
38
|
-
chirp.
|
39
|
-
chirp.
|
40
|
-
chirp.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
chirp.
|
33
|
+
chirp = Chirpstream.oauth(consumer_token, consumer_secret)
|
34
|
+
chirp.on_reconnect{ puts "reconnecting..." }
|
35
|
+
chirp.on_tweet {|t, u| puts "#{t.text} (from #{t.user.name.foreground(:red)} (#{('@' + t.user.screen_name).foreground(:green)}))" }
|
36
|
+
chirp.on_follow {|t, u| puts "#{t.source.screen_name.foreground(:green)} following #{t.target.screen_name.foreground(:green)}" }
|
37
|
+
chirp.on_favorite {|t, u| puts "#{t.source.screen_name.foreground(:green)} <3 -> #{t.target_object.text}" }
|
38
|
+
chirp.on_retweet {|t, u| puts "#{t.source.screen_name.foreground(:green)} RT -> #{t.target_object.text}" }
|
39
|
+
chirp.on_direct_message {|t, u| puts "DM : #{t.text} (from #{t.sender.name.foreground(:red)} (#{('@' + t.sender.screen_name).foreground(:green)}))" }
|
40
|
+
chirp.connect(Chirpstream::Connect::User.oauth(access_token, access_secret))
|
41
|
+
|
42
|
+
== Multi User Usage
|
43
|
+
|
44
|
+
chirp = Chirpstream.new(consumer_token, consumer_secret)
|
45
|
+
|
46
|
+
chirp.on_reconnect{ puts "reconnecting..." }
|
47
|
+
chirp.on_tweet {|t, u| puts "#{t.text} (from #{t.user.name.foreground(:red)} (#{('@' + t.user.screen_name).foreground(:green)}))" }
|
48
|
+
chirp.on_follow {|t, u| puts "#{t.source.screen_name.foreground(:green)} following #{t.target.screen_name.foreground(:green)}" }
|
49
|
+
chirp.on_favorite {|t, u| puts "#{t.source.screen_name.foreground(:green)} <3 -> #{t.target_object.text}" }
|
50
|
+
chirp.on_retweet {|t, u| puts "#{t.source.screen_name.foreground(:green)} RT -> #{t.target_object.text}" }
|
51
|
+
chirp.on_direct_message {|t, u| puts "DM : #{t.text} (from #{t.sender.name.foreground(:red)} (#{('@' + t.sender.screen_name).foreground(:green)}))" }
|
52
|
+
|
53
|
+
chirp.connect(Chirpstream::Connect::User.oauth(access_token1, access_secret1), Chirpstream::Connect::User.oauth(access_token2, access_secret2))
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/chirp_growl
CHANGED
@@ -36,7 +36,7 @@ else
|
|
36
36
|
File.open(json_file, 'w') {|f| f << {:username => @username, :password => @password}.to_json}
|
37
37
|
end
|
38
38
|
|
39
|
-
chirp = Chirpstream.new
|
39
|
+
chirp = Chirpstream.new
|
40
40
|
|
41
41
|
Growl.notify {
|
42
42
|
self.message = 'Starting chirp_growl...'
|
@@ -44,8 +44,8 @@ Growl.notify {
|
|
44
44
|
self.image = File.join(File.dirname(__FILE__), '..', 'image', 'bird.png')
|
45
45
|
}
|
46
46
|
|
47
|
-
chirp.
|
48
|
-
t.user.with_profile_image(cache_dir) do |image_path|
|
47
|
+
chirp.on_tweet { |t, u|
|
48
|
+
t.user.with_profile_image(u, cache_dir) do |image_path|
|
49
49
|
Growl.notify {
|
50
50
|
self.message = t.text
|
51
51
|
self.title = "@#{t.user.screen_name}"
|
@@ -54,6 +54,6 @@ chirp.tweet { |t|
|
|
54
54
|
end
|
55
55
|
}
|
56
56
|
|
57
|
-
chirp.connect
|
57
|
+
chirp.connect(Chirpstream::Connect::User.basic(@username, @password))
|
58
58
|
|
59
59
|
|
data/lib/chirpstream.rb
CHANGED
@@ -15,76 +15,71 @@ require 'chirpstream/event/follow'
|
|
15
15
|
require 'chirpstream/event/direct_message'
|
16
16
|
require 'chirpstream/event/retweet'
|
17
17
|
require 'chirpstream/event/favorite'
|
18
|
+
require 'chirpstream/event/unfavorite'
|
18
19
|
require 'chirpstream/event/delete'
|
19
20
|
require 'chirpstream/user'
|
20
21
|
require 'chirpstream/tweet'
|
22
|
+
require 'chirpstream/connect'
|
21
23
|
|
22
24
|
class Chirpstream
|
23
25
|
|
26
|
+
include Connect
|
27
|
+
|
24
28
|
attr_reader :handlers
|
25
29
|
|
26
|
-
Handlers = Struct.new(:friend, :tweet, :follow, :favorite, :retweet, :delete, :reconnect, :direct_message)
|
27
|
-
|
28
|
-
attr_reader :username, :password
|
29
|
-
attr_accessor :consumer_token, :consumer_secret, :access_token, :access_secret, :fill_in
|
30
|
-
|
31
|
-
def self.basic(username, password, options = nil)
|
32
|
-
chirpstream = new(username, password)
|
33
|
-
chirpstream.fill_in = options[:fill_in] if options && options.key?(:fill_in)
|
34
|
-
end
|
30
|
+
Handlers = Struct.new(:friend, :tweet, :follow, :favorite, :unfavorite, :retweet, :delete, :reconnect, :connect, :direct_message)
|
35
31
|
|
36
|
-
|
37
|
-
chirpstream = new
|
38
|
-
chirpstream.consumer_token = consumer_token
|
39
|
-
chirpstream.consumer_secret = consumer_secret
|
40
|
-
chirpstream.access_token = access_token
|
41
|
-
chirpstream.access_secret = access_secret
|
42
|
-
chirpstream.fill_in = options[:fill_in] if options && options.key?(:fill_in)
|
43
|
-
chirpstream
|
44
|
-
end
|
32
|
+
attr_reader :consumer_token, :consumer_secret, :fill_in
|
45
33
|
|
46
|
-
def initialize(
|
47
|
-
@
|
48
|
-
@
|
49
|
-
@
|
34
|
+
def initialize(options = nil)
|
35
|
+
@consumer_token = options && options[:consumer_token]
|
36
|
+
@consumer_secret = options && options[:consumer_secret]
|
37
|
+
@fill_in = options && options[:fill_in]
|
50
38
|
@connect_url = "http://chirpstream.twitter.com/2b/user.json"
|
51
|
-
@handlers = Handlers.new([], [], [], [], [], [], [], [])
|
52
|
-
@data = ''
|
39
|
+
@handlers = Handlers.new([], [], [], [], [], [], [], [], [], [])
|
53
40
|
end
|
54
|
-
|
55
|
-
def
|
41
|
+
|
42
|
+
def on_friend(&block)
|
56
43
|
@handlers.friend << block
|
57
44
|
end
|
58
45
|
|
59
|
-
def
|
46
|
+
def on_tweet(&block)
|
60
47
|
@handlers.tweet << block
|
61
48
|
end
|
62
49
|
|
63
|
-
def
|
50
|
+
def on_follow(&block)
|
64
51
|
@handlers.follow << block
|
65
52
|
end
|
66
53
|
|
67
|
-
def
|
54
|
+
def on_favorite(&block)
|
68
55
|
@handlers.favorite << block
|
69
56
|
end
|
70
57
|
|
71
|
-
def
|
58
|
+
def on_unfavorite(&block)
|
59
|
+
@handlers.unfavorite << block
|
60
|
+
end
|
61
|
+
|
62
|
+
def on_retweet(&block)
|
72
63
|
@handlers.retweet << block
|
73
64
|
end
|
74
65
|
|
75
|
-
def
|
66
|
+
def on_direct_message(&block)
|
76
67
|
@handlers.direct_message << block
|
77
68
|
end
|
78
69
|
|
79
|
-
def
|
70
|
+
def on_delete(&block)
|
80
71
|
@handlers.delete << block
|
81
72
|
end
|
82
73
|
|
83
|
-
def
|
74
|
+
def on_reconnect(&block)
|
84
75
|
@handlers.reconnect << block
|
85
76
|
end
|
86
77
|
|
87
|
-
def
|
78
|
+
def on_connect(&block)
|
79
|
+
@handlers.connect << block
|
80
|
+
end
|
81
|
+
|
82
|
+
def dispatch_friend(user, data)
|
88
83
|
unless @handlers.friend.empty?
|
89
84
|
data['friends'].each_slice(100) do |friend_ids|
|
90
85
|
parser = Yajl::Parser.new
|
@@ -93,141 +88,145 @@ class Chirpstream
|
|
93
88
|
@handlers.friend.each{|h| h.call(friend)}
|
94
89
|
end
|
95
90
|
}
|
96
|
-
friend_http =
|
97
|
-
|
91
|
+
friend_http = get_connection(user, "http://api.twitter.com/1/users/lookup.json", :post, :body => {'user_id' => friend_ids.join(',')})
|
92
|
+
friend_http.stream { |chunk|
|
98
93
|
parser << chunk
|
99
94
|
}
|
100
95
|
end
|
101
96
|
end
|
102
97
|
end
|
103
98
|
|
104
|
-
def dispatch_tweet(data)
|
99
|
+
def dispatch_tweet(user, data)
|
105
100
|
unless @handlers.tweet.empty?
|
106
101
|
tweet = Tweet.new(self, data)
|
107
|
-
@fill_in ? tweet.load_all { |
|
108
|
-
@handlers.tweet.each{|h| h.call(
|
109
|
-
} : @handlers.tweet.each{|h| h.call(tweet)}
|
102
|
+
@fill_in ? tweet.load_all(user) { |f|
|
103
|
+
@handlers.tweet.each{|h| h.call(f, user)}
|
104
|
+
} : @handlers.tweet.each{|h| h.call(tweet, user)}
|
110
105
|
end
|
111
106
|
end
|
112
107
|
|
113
|
-
def dispatch_follow(data)
|
108
|
+
def dispatch_follow(user, data)
|
114
109
|
unless @handlers.follow.empty?
|
115
110
|
follow = Follow.new(self, data)
|
116
|
-
@fill_in ? follow.load_all { |f|
|
117
|
-
@handlers.follow.each{|h| h.call(f)}
|
118
|
-
} : @handlers.follow.each{|h| h.call(follow)}
|
111
|
+
@fill_in ? follow.load_all(user) { |f|
|
112
|
+
@handlers.follow.each{|h| h.call(f, user)}
|
113
|
+
} : @handlers.follow.each{|h| h.call(follow, user)}
|
119
114
|
end
|
120
115
|
end
|
121
116
|
|
122
|
-
def dispatch_direct_message(data)
|
117
|
+
def dispatch_direct_message(user, data)
|
123
118
|
unless @handlers.direct_message.empty?
|
124
119
|
dm = DirectMessage.new(self, data)
|
125
|
-
@fill_in ? dm.load_all { |f|
|
126
|
-
@handlers.direct_message.each{|h| h.call(f)}
|
127
|
-
} : @handlers.direct_message.each{|h| h.call(dm)}
|
120
|
+
@fill_in ? dm.load_all(user) { |f|
|
121
|
+
@handlers.direct_message.each{|h| h.call(f, user)}
|
122
|
+
} : @handlers.direct_message.each{|h| h.call(dm, user)}
|
128
123
|
end
|
129
124
|
end
|
130
125
|
|
131
|
-
def dispatch_favorite(data)
|
126
|
+
def dispatch_favorite(user, data)
|
132
127
|
unless @handlers.favorite.empty?
|
133
128
|
favorite = Favorite.new(self, data)
|
134
|
-
@fill_in ? favorite.load_all { |f|
|
135
|
-
@handlers.favorite.each{|h| h.call(f)}
|
136
|
-
} : @handlers.favorite.each{|h| h.call(favorite)}
|
129
|
+
@fill_in ? favorite.load_all(user) { |f|
|
130
|
+
@handlers.favorite.each{|h| h.call(f, user)}
|
131
|
+
} : @handlers.favorite.each{|h| h.call(favorite, user)}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def dispatch_unfavorite(user, data)
|
136
|
+
unless @handlers.unfavorite.empty?
|
137
|
+
unfavorite = Unfavorite.new(self, data)
|
138
|
+
@fill_in ? unfavorite.load_all(user) { |f|
|
139
|
+
@handlers.unfavorite.each{|h| h.call(f, user)}
|
140
|
+
} : @handlers.unfavorite.each{|h| h.call(unfavorite, user)}
|
137
141
|
end
|
138
142
|
end
|
139
143
|
|
140
|
-
def dispatch_retweet(data)
|
144
|
+
def dispatch_retweet(user, data)
|
141
145
|
unless @handlers.retweet.empty?
|
142
146
|
retweet = Retweet.new(self, data)
|
143
|
-
@fill_in ? retweet.load_all { |f|
|
144
|
-
@handlers.retweet.each{|h| h.call(f)}
|
145
|
-
} : @handlers.retweet.each{|h| h.call(retweet)}
|
147
|
+
@fill_in ? retweet.load_all(user) { |f|
|
148
|
+
@handlers.retweet.each{|h| h.call(f, user)}
|
149
|
+
} : @handlers.retweet.each{|h| h.call(retweet, user)}
|
146
150
|
end
|
147
151
|
end
|
148
152
|
|
149
|
-
def dispatch_delete(data)
|
153
|
+
def dispatch_delete(user, data)
|
150
154
|
unless @handlers.delete.empty?
|
151
155
|
delete = Delete.new(self, data)
|
152
|
-
@fill_in ? delete.load_all { |f|
|
153
|
-
@handlers.delete.each{|h| h.call(f)}
|
154
|
-
} : @handlers.delete.each{|h| h.call(delete)}
|
156
|
+
@fill_in ? delete.load_all(user) { |f|
|
157
|
+
@handlers.delete.each{|h| h.call(f, user)}
|
158
|
+
} : @handlers.delete.each{|h| h.call(delete, user)}
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
158
|
-
def dispatch_reconnect
|
162
|
+
def dispatch_reconnect(user)
|
159
163
|
return if @handlers.reconnect.empty?
|
160
|
-
@handlers.reconnect.each{|h| h.call}
|
161
|
-
end
|
162
|
-
|
163
|
-
def
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
164
|
+
@handlers.reconnect.each{|h| h.call(user)}
|
165
|
+
end
|
166
|
+
|
167
|
+
def dispatch_connect(user)
|
168
|
+
while h = @handlers.connect.shift
|
169
|
+
h.call(user)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def data_handler(user)
|
174
|
+
Proc.new{|parsed_data|
|
175
|
+
if parsed_data['direct_message']
|
176
|
+
dispatch_direct_message(user, parsed_data)
|
177
|
+
elsif parsed_data['friends']
|
178
|
+
dispatch_friend(user, parsed_data)
|
179
|
+
elsif parsed_data['text']
|
180
|
+
dispatch_tweet(user, parsed_data)
|
181
|
+
elsif parsed_data['event']
|
182
|
+
case parsed_data['event']
|
183
|
+
when 'follow'
|
184
|
+
dispatch_follow(user, parsed_data)
|
185
|
+
when 'favorite'
|
186
|
+
dispatch_favorite(user, parsed_data)
|
187
|
+
when 'unfavorite'
|
188
|
+
dispatch_unfavorite(user, parsed_data)
|
189
|
+
when 'retweet'
|
190
|
+
dispatch_retweet(user, parsed_data)
|
191
|
+
else
|
192
|
+
puts "weird event"
|
193
|
+
pp parsed_data
|
194
|
+
end
|
195
|
+
elsif parsed_data['delete']
|
196
|
+
dispatch_delete(user, parsed_data)
|
178
197
|
else
|
179
|
-
puts "
|
198
|
+
puts "i didn't know what to do with this!"
|
180
199
|
pp parsed_data
|
181
200
|
end
|
182
|
-
|
183
|
-
dispatch_delete(parsed_data)
|
184
|
-
else
|
185
|
-
puts "i didn't know what to do with this!"
|
186
|
-
pp parsed_data
|
187
|
-
end
|
201
|
+
}
|
188
202
|
end
|
189
203
|
|
190
|
-
def connect
|
204
|
+
def connect(*users)
|
191
205
|
unless EM.reactor_running?
|
192
|
-
EM.run { connect }
|
206
|
+
EM.run { connect(*users) }
|
193
207
|
else
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
http.errback { |e, err|
|
198
|
-
dispatch_reconnect
|
199
|
-
connect
|
200
|
-
}
|
201
|
-
http.stream { |chunk|
|
202
|
-
begin
|
203
|
-
parser << chunk
|
204
|
-
rescue Yajl::ParseError
|
205
|
-
puts "bad chunk: #{chunk.inspect}"
|
206
|
-
end
|
207
|
-
}
|
208
|
+
users.each do |user, index|
|
209
|
+
connect_single(user)
|
210
|
+
end
|
208
211
|
end
|
209
212
|
end
|
210
213
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
request.send(method, options) do |client|
|
227
|
-
twitter_oauth_consumer.sign!(client, twitter_oauth_access_token)
|
214
|
+
def connect_single(user)
|
215
|
+
parser = Yajl::Parser.new
|
216
|
+
parser.on_parse_complete = data_handler(user)
|
217
|
+
http = get_connection(user, @connect_url, :get)
|
218
|
+
http.errback { |e, err|
|
219
|
+
dispatch_reconnect(user)
|
220
|
+
connect
|
221
|
+
}
|
222
|
+
http.stream { |chunk|
|
223
|
+
dispatch_connect(user)
|
224
|
+
begin
|
225
|
+
parser << chunk
|
226
|
+
rescue Yajl::ParseError
|
227
|
+
p $!
|
228
|
+
puts "bad chunk: #{chunk.inspect}"
|
228
229
|
end
|
229
|
-
|
230
|
-
http = EM::HttpRequest.new(url).send(method, options.merge(:head => {'authorization' => [@username, @password]}))
|
231
|
-
end
|
230
|
+
}
|
232
231
|
end
|
233
232
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
class Chirpstream
|
2
|
+
module Connect
|
3
|
+
class User
|
4
|
+
|
5
|
+
class Oauth
|
6
|
+
attr_reader :name, :access_token, :access_secret
|
7
|
+
def initialize(access_token, access_secret, name = nil)
|
8
|
+
@name = name
|
9
|
+
@access_token = access_token
|
10
|
+
@access_secret = access_secret
|
11
|
+
end
|
12
|
+
|
13
|
+
def oauth?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Basic
|
19
|
+
attr_reader :name, :password
|
20
|
+
def initialize(name, password)
|
21
|
+
@name = name
|
22
|
+
@password = password
|
23
|
+
end
|
24
|
+
|
25
|
+
def oauth?
|
26
|
+
false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.oauth(access_token, access_secret, name = nil)
|
31
|
+
Oauth.new(access_token, access_secret, name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.basic(name, password)
|
35
|
+
Basic.new(name, password)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_connection(user, url, method, extras = nil)
|
40
|
+
options = extras ? extras.merge(:timeout => 0) : {:timeout => 0}
|
41
|
+
if user.oauth?
|
42
|
+
request = EM::HttpRequest.new(url)
|
43
|
+
request.send(method, options) do |client|
|
44
|
+
twitter_oauth_consumer.sign!(client, twitter_oauth_access_token(user.access_token, user.access_secret))
|
45
|
+
end
|
46
|
+
else
|
47
|
+
http = EM::HttpRequest.new(url).send(method, options.merge(:head => {'authorization' => [user.name, user.password]}))
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def twitter_oauth_consumer
|
53
|
+
@twitter_oauth_consumer ||= OAuth::Consumer.new(consumer_token, consumer_secret, :site => "http://twitter.com")
|
54
|
+
end
|
55
|
+
|
56
|
+
def twitter_oauth_access_token(token=nil,secret=nil)
|
57
|
+
token ||= access_token
|
58
|
+
secret ||= access_secret
|
59
|
+
@twitter_oauth_access_token ||= OAuth::AccessToken.new(twitter_oauth_consumer, token, secret)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -47,14 +47,14 @@ class TwitterObject
|
|
47
47
|
const_get(:ATTRS)
|
48
48
|
end
|
49
49
|
|
50
|
-
def load_all(&block)
|
50
|
+
def load_all(loading_user, &block)
|
51
51
|
attrs = self.class.attrs
|
52
52
|
if respond_to?(:loaded?) && !loaded?
|
53
53
|
if respond_to?(:user_loadable_id)
|
54
|
-
from_json(get_user_data(user_loadable_id)[user_loadable_id])
|
54
|
+
from_json(get_user_data(loading_user, user_loadable_id)[user_loadable_id])
|
55
55
|
load_all(&block)
|
56
56
|
elsif respond_to?(:tweet_loadable_id)
|
57
|
-
from_json(get_tweet_data(tweet_loadable_id)[tweet_loadable_id])
|
57
|
+
from_json(get_tweet_data(loading_user, tweet_loadable_id)[tweet_loadable_id])
|
58
58
|
load_all(&block)
|
59
59
|
end
|
60
60
|
else
|
@@ -70,9 +70,9 @@ class TwitterObject
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
73
|
-
get_tweet_data(tweet_ids.values) { |tweet_data|
|
73
|
+
get_tweet_data(loading_user, tweet_ids.values) { |tweet_data|
|
74
74
|
tweet_ids.each{|k,v| self.send(:"#{k}=", tweet_data[v])}
|
75
|
-
user_data = get_user_data(user_ids.values) { |user_data|
|
75
|
+
user_data = get_user_data(loading_user, user_ids.values) { |user_data|
|
76
76
|
user_ids.each{|k,v| self.send(:"#{k}=", user_data[v])}
|
77
77
|
yield self
|
78
78
|
}
|
@@ -81,17 +81,17 @@ class TwitterObject
|
|
81
81
|
|
82
82
|
end
|
83
83
|
|
84
|
-
def get_tweet_data(ids)
|
84
|
+
def get_tweet_data(loading_user, ids)
|
85
85
|
ids = Array(ids).uniq
|
86
86
|
data = {}
|
87
87
|
if ids.empty?
|
88
88
|
yield data
|
89
89
|
else
|
90
|
-
load_tweet_data(ids, data) { yield data }
|
90
|
+
load_tweet_data(loading_user, ids, data) { yield data }
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
-
def load_tweet_data(ids, data, &block)
|
94
|
+
def load_tweet_data(loading_user, ids, data, &block)
|
95
95
|
id = ids.shift
|
96
96
|
if (id)
|
97
97
|
parser = Yajl::Parser.new
|
@@ -99,7 +99,7 @@ class TwitterObject
|
|
99
99
|
data[id] = parsed
|
100
100
|
load_tweet_data(ids, data, &block)
|
101
101
|
}
|
102
|
-
http = base.
|
102
|
+
http = base.get_connection(loading_user, "http://api.twitter.com/1/statuses/show/%s.json" % id, :get)
|
103
103
|
http.stream { |chunk|
|
104
104
|
parser << chunk
|
105
105
|
}
|
@@ -108,17 +108,17 @@ class TwitterObject
|
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
-
def get_user_data(ids)
|
111
|
+
def get_user_data(loading_user, ids)
|
112
112
|
ids = Array(ids).uniq
|
113
113
|
data = {}
|
114
114
|
if ids.empty?
|
115
115
|
yield data
|
116
116
|
else
|
117
|
-
load_user_data(ids, data) { yield data }
|
117
|
+
load_user_data(loading_user, ids, data) { yield data }
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
-
def load_user_data(ids, data)
|
121
|
+
def load_user_data(loading_user, ids, data)
|
122
122
|
parser = Yajl::Parser.new
|
123
123
|
parser.on_parse_complete = proc { |parsed|
|
124
124
|
parsed.each do |user|
|
@@ -126,7 +126,7 @@ class TwitterObject
|
|
126
126
|
end
|
127
127
|
yield
|
128
128
|
}
|
129
|
-
http = base.
|
129
|
+
http = base.get_connection(loading_user, "http://api.twitter.com/1/users/lookup.json", :post, :body => {'user_id' => ids.join(',')})
|
130
130
|
http.stream { |chunk|
|
131
131
|
parser << chunk
|
132
132
|
}
|
data/lib/chirpstream/user.rb
CHANGED
@@ -21,7 +21,7 @@ class Chirpstream
|
|
21
21
|
id
|
22
22
|
end
|
23
23
|
|
24
|
-
def with_profile_image(cache_dir)
|
24
|
+
def with_profile_image(loading_user, cache_dir)
|
25
25
|
raise unless loaded?
|
26
26
|
|
27
27
|
cached_file = File.join(cache_dir, "#{Digest::MD5.hexdigest(profile_image_url)}#{File.extname(profile_image_url)}")
|
@@ -29,7 +29,7 @@ class Chirpstream
|
|
29
29
|
if File.exist?(cached_file)
|
30
30
|
yield cached_file
|
31
31
|
else
|
32
|
-
http =
|
32
|
+
http = base.get_connection(loading_user, profile_image_url, :get)
|
33
33
|
http.callback do
|
34
34
|
if http.response_header.status == 200
|
35
35
|
File.open(cached_file, 'w') {|f| f << http.response}
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
|
9
|
-
version: 0.0.8
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Joshua Hull
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-05-
|
18
|
+
date: 2010-05-21 00:00:00 -04:00
|
19
19
|
default_executable: chirp_growl
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -105,12 +105,14 @@ files:
|
|
105
105
|
- bin/chirp_growl
|
106
106
|
- image/bird.png
|
107
107
|
- lib/chirpstream.rb
|
108
|
+
- lib/chirpstream/connect.rb
|
108
109
|
- lib/chirpstream/event.rb
|
109
110
|
- lib/chirpstream/event/delete.rb
|
110
111
|
- lib/chirpstream/event/direct_message.rb
|
111
112
|
- lib/chirpstream/event/favorite.rb
|
112
113
|
- lib/chirpstream/event/follow.rb
|
113
114
|
- lib/chirpstream/event/retweet.rb
|
115
|
+
- lib/chirpstream/event/unfavorite.rb
|
114
116
|
- lib/chirpstream/tweet.rb
|
115
117
|
- lib/chirpstream/twitter_object.rb
|
116
118
|
- lib/chirpstream/user.rb
|