friendfeed 0.1.12 → 0.1.13
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/VERSION +1 -1
- data/bin/tw2ff +18 -5
- data/friendfeed.gemspec +3 -2
- data/lib/friendfeed.rb +3 -482
- data/lib/friendfeed/compat.rb +2 -2
- data/lib/friendfeed/unofficial.rb +7 -6
- data/lib/friendfeed/v1.rb +490 -0
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.13
|
data/bin/tw2ff
CHANGED
@@ -246,7 +246,8 @@ EOF
|
|
246
246
|
picture_urls[name] = friend.profile_image_url
|
247
247
|
end
|
248
248
|
}
|
249
|
-
|
249
|
+
twitter_me = Config('twitter.username')
|
250
|
+
friends << twitter_me
|
250
251
|
|
251
252
|
Status('friends') { friends.sort }
|
252
253
|
Status('friends_to_watch') { to_watch.sort }
|
@@ -264,6 +265,13 @@ EOF
|
|
264
265
|
ffcli.change_picture_to_url(id, url)
|
265
266
|
end
|
266
267
|
}
|
268
|
+
|
269
|
+
printf <<-EOS, 'http://friendfeed.com/friends/twitter?username=' + URI.escape(twitter_me)
|
270
|
+
|
271
|
+
You may also want to check out the following page
|
272
|
+
to see if someone is joining FriendFeed:
|
273
|
+
%s
|
274
|
+
EOS
|
267
275
|
end
|
268
276
|
end
|
269
277
|
|
@@ -329,7 +337,7 @@ EOF
|
|
329
337
|
liked = Set[]
|
330
338
|
tw_url = {}
|
331
339
|
|
332
|
-
ffcli.get_user_liked_entries.each { |like|
|
340
|
+
ffcli.get_user_liked_entries(nil, 'service' => 'twitter').each { |like|
|
333
341
|
url = like['link']
|
334
342
|
case TWITTER_URI.route_to(url).to_s
|
335
343
|
when %r{\A([A-Za-z0-9_]+)/statuses/([0-9]+)\z}
|
@@ -342,13 +350,18 @@ EOF
|
|
342
350
|
# Favorite FriendFeed-liked entry in Twitter
|
343
351
|
(liked - favorited).each { |id|
|
344
352
|
putinfo "Adding a favorite in Twitter: %s", tw_url[id]
|
345
|
-
|
353
|
+
begin
|
354
|
+
twcli.favorite_create(id)
|
355
|
+
rescue
|
356
|
+
# Maybe already favorited a long ago
|
357
|
+
end
|
346
358
|
}
|
347
359
|
|
348
360
|
# Find Twitter-liked entries in FriendFeed that aren't liked yet
|
349
361
|
(
|
350
|
-
ffcli.get_user_friend_entries(nil, '
|
351
|
-
ffcli.get_user_discussed_entries
|
362
|
+
ffcli.get_user_friend_entries(nil, 'service' => 'twitter') +
|
363
|
+
ffcli.get_user_discussed_entries(nil, 'service' => 'twitter')
|
364
|
+
# Currently imaginary friends entries are not checked
|
352
365
|
).sort_by { |entry|
|
353
366
|
entry["published"]
|
354
367
|
}.each { |entry|
|
data/friendfeed.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{friendfeed}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.13"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Akinori MUSHA"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-18}
|
13
13
|
s.default_executable = %q{tw2ff}
|
14
14
|
s.description = %q{This is a Ruby library to provide access to FriendFeed API's.
|
15
15
|
|
@@ -34,6 +34,7 @@ manipulating friends, groups and services for your personal purposes.
|
|
34
34
|
"lib/friendfeed.rb",
|
35
35
|
"lib/friendfeed/compat.rb",
|
36
36
|
"lib/friendfeed/unofficial.rb",
|
37
|
+
"lib/friendfeed/v1.rb",
|
37
38
|
"test/friendfeed_test.rb",
|
38
39
|
"test/test_helper.rb"
|
39
40
|
]
|
data/lib/friendfeed.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# -*- mode: ruby -*-
|
2
2
|
#--
|
3
3
|
# friendfeed.rb - provides access to FriendFeed API's
|
4
4
|
#++
|
@@ -8,486 +8,7 @@
|
|
8
8
|
# terms as Ruby.
|
9
9
|
#
|
10
10
|
|
11
|
-
require 'rubygems'
|
12
|
-
require 'json'
|
13
|
-
require 'mechanize'
|
14
|
-
require 'uri'
|
15
|
-
require 'friendfeed/compat'
|
16
|
-
|
17
11
|
module FriendFeed
|
18
|
-
|
19
|
-
|
20
|
-
# Client library for FriendFeed API.
|
21
|
-
class Client
|
22
|
-
attr_reader :nickname
|
23
|
-
|
24
|
-
#
|
25
|
-
# Official API
|
26
|
-
#
|
27
|
-
|
28
|
-
API_URI = ROOT_URI + "/api/"
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def get_api_agent
|
33
|
-
@api_agent ||= Mechanize.new
|
34
|
-
end
|
35
|
-
|
36
|
-
def validate
|
37
|
-
call_api('validate')
|
38
|
-
end
|
39
|
-
|
40
|
-
def require_api_login
|
41
|
-
@nickname or raise 'not logged in'
|
42
|
-
end
|
43
|
-
|
44
|
-
def call_subscription_api(path)
|
45
|
-
require_api_login
|
46
|
-
|
47
|
-
uri = API_URI + path
|
48
|
-
|
49
|
-
agent = Mechanize.new
|
50
|
-
agent.auth('username', @nickname)
|
51
|
-
JSON.parse(agent.post(uri, { 'apikey' => @remote_key }).body)
|
52
|
-
end
|
53
|
-
|
54
|
-
public
|
55
|
-
|
56
|
-
attr_reader :nickname, :remote_key
|
57
|
-
|
58
|
-
# Performs a login with a +nickname+ and +remote key+ and returns
|
59
|
-
# self. This enables call of any official API that requires
|
60
|
-
# authentication. It is not needed to call this method if you
|
61
|
-
# have called login(), which internally obtains a remote key and
|
62
|
-
# calls this method. An exception is raised if authentication
|
63
|
-
# fails.
|
64
|
-
def api_login(nickname, remote_key)
|
65
|
-
@nickname = nickname
|
66
|
-
@remote_key = remote_key
|
67
|
-
@api_agent = get_api_agent()
|
68
|
-
@api_agent.auth(@nickname, @remote_key)
|
69
|
-
validate
|
70
|
-
|
71
|
-
self
|
72
|
-
end
|
73
|
-
|
74
|
-
# Calls an official API specified by a +path+ with optional
|
75
|
-
# +get_parameters+ and +post_parameters+, and returns an object
|
76
|
-
# parsed from a JSON response. If +post_parameters+ is given, a
|
77
|
-
# POST request is issued. A GET request is issued otherwise.
|
78
|
-
def call_api(path, get_parameters = nil, post_parameters = nil, raw = false)
|
79
|
-
api_agent = get_api_agent()
|
80
|
-
|
81
|
-
uri = API_URI + path
|
82
|
-
if get_parameters
|
83
|
-
uri.query = get_parameters.map { |key, value|
|
84
|
-
key = key.to_s
|
85
|
-
if array = Array.try_convert(value)
|
86
|
-
value = array.join(',')
|
87
|
-
else
|
88
|
-
value = value.to_s
|
89
|
-
end
|
90
|
-
URI.encode(key) + "=" + URI.encode(value)
|
91
|
-
}.join('&')
|
92
|
-
end
|
93
|
-
|
94
|
-
if post_parameters
|
95
|
-
body = api_agent.post(uri, post_parameters).body
|
96
|
-
else
|
97
|
-
body = api_agent.get_file(uri)
|
98
|
-
end
|
99
|
-
|
100
|
-
if raw
|
101
|
-
body
|
102
|
-
else
|
103
|
-
JSON.parse(body)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Gets profile information of a user of a given +nickname+,
|
108
|
-
# defaulted to the authenticated user, in hash.
|
109
|
-
def get_profile(nickname = nil)
|
110
|
-
nickname ||= @nickname
|
111
|
-
nickname or require_api_login
|
112
|
-
call_api('user/%s/profile' % URI.encode(nickname))
|
113
|
-
end
|
114
|
-
|
115
|
-
# Edits profile information of the authenticated user. The fields
|
116
|
-
# "name" and "picture" are supported.
|
117
|
-
def edit_profile(hash)
|
118
|
-
nickname or require_api_login
|
119
|
-
call_api('user/%s/profile' % URI.encode(nickname), nil, hash)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Gets an array of profile information of users of given
|
123
|
-
# +nicknames+.
|
124
|
-
def get_profiles(nicknames)
|
125
|
-
call_api('profiles', 'nickname' => nicknames)['profiles']
|
126
|
-
end
|
127
|
-
|
128
|
-
# Gets an array of profile information of friends of a user of a
|
129
|
-
# given +nickname+ (defaulted to the authenticated user) is
|
130
|
-
# subscribing to.
|
131
|
-
def get_real_friends(nickname = nil)
|
132
|
-
nickname ||= @nickname
|
133
|
-
nickname or require_api_login
|
134
|
-
nicknames = []
|
135
|
-
get_profile(@nickname)['subscriptions'].each { |subscription|
|
136
|
-
if nickname = subscription['nickname']
|
137
|
-
nicknames << nickname
|
138
|
-
end
|
139
|
-
}
|
140
|
-
get_profiles(nicknames)
|
141
|
-
end
|
142
|
-
|
143
|
-
# Gets an array of profile information of the authenticated user's
|
144
|
-
# imaginary friends.
|
145
|
-
def get_imaginary_friends
|
146
|
-
nickname or require_api_login
|
147
|
-
profiles = []
|
148
|
-
get_profile(@nickname)['subscriptions'].each { |subscription|
|
149
|
-
if subscription['nickname'].nil?
|
150
|
-
profiles << get_profile(subscription['id'])
|
151
|
-
end
|
152
|
-
}
|
153
|
-
profiles
|
154
|
-
end
|
155
|
-
|
156
|
-
# Gets profile information of one of the authenticated user's
|
157
|
-
# imaginary friends.
|
158
|
-
def get_imaginary_friend(id)
|
159
|
-
get_profile(id)
|
160
|
-
end
|
161
|
-
|
162
|
-
# Gets an array of the most recent public entries.
|
163
|
-
def get_public_entries(options = nil)
|
164
|
-
call_api('feed/public', options)['entries']
|
165
|
-
end
|
166
|
-
|
167
|
-
# Gets an array of the entries the authenticated user would see on
|
168
|
-
# their home page.
|
169
|
-
def get_home_entries(options = nil)
|
170
|
-
require_api_login
|
171
|
-
call_api('feed/home', options)['entries']
|
172
|
-
end
|
173
|
-
|
174
|
-
# Gets an array of the entries for the authenticated user's list
|
175
|
-
# of a given +nickname+
|
176
|
-
def get_list_entries(nickname, options = nil)
|
177
|
-
require_api_login
|
178
|
-
call_api('feed/list/%s' % URI.encode(nickname), options)['entries']
|
179
|
-
end
|
180
|
-
|
181
|
-
# Gets an array of the most recent entries from a user of a given
|
182
|
-
# +nickname+ (defaulted to the authenticated user).
|
183
|
-
def get_user_entries(nickname = nil, options = nil)
|
184
|
-
nickname ||= @nickname
|
185
|
-
nickname or require_api_login
|
186
|
-
call_api('feed/user/%s' % URI.encode(nickname), options)['entries']
|
187
|
-
end
|
188
|
-
|
189
|
-
# Gets an array of the most recent entries from users of given
|
190
|
-
# +nicknames+.
|
191
|
-
def get_multi_user_entries(nicknames, options = nil)
|
192
|
-
new_options = { 'nickname' => nicknames }
|
193
|
-
new_options.merge!(options) if options
|
194
|
-
call_api('feed/user', new_options)['entries']
|
195
|
-
end
|
196
|
-
|
197
|
-
# Gets an array of the most recent entries a user of a given
|
198
|
-
# +nickname+ (defaulted to the authenticated user) has commented
|
199
|
-
# on.
|
200
|
-
def get_user_commented_entries(nickname = nil, options = nil)
|
201
|
-
nickname ||= @nickname
|
202
|
-
nickname or require_api_login
|
203
|
-
call_api('feed/user/%s/comments' % URI.encode(nickname), options)['entries']
|
204
|
-
end
|
205
|
-
|
206
|
-
# Gets an array of the most recent entries a user of a given
|
207
|
-
# +nickname+ (defaulted to the authenticated user) has like'd.
|
208
|
-
def get_user_liked_entries(nickname = nil, options = nil)
|
209
|
-
nickname ||= @nickname
|
210
|
-
nickname or require_api_login
|
211
|
-
call_api('feed/user/%s/likes' % URI.encode(nickname), options)['entries']
|
212
|
-
end
|
213
|
-
|
214
|
-
# Gets an array of the most recent entries a user of a given
|
215
|
-
# +nickname+ (defaulted to the authenticated user) has commented
|
216
|
-
# on or like'd.
|
217
|
-
def get_user_discussed_entries(nickname = nil, options = nil)
|
218
|
-
nickname ||= @nickname
|
219
|
-
nickname or require_api_login
|
220
|
-
call_api('feed/user/%s/discussion' % URI.encode(nickname), options)['entries']
|
221
|
-
end
|
222
|
-
|
223
|
-
# Gets an array of the most recent entries from friends of a user
|
224
|
-
# of a given +nickname+ (defaulted to the authenticated user).
|
225
|
-
def get_user_friend_entries(nickname = nil, options = nil)
|
226
|
-
nickname ||= @nickname
|
227
|
-
nickname or require_api_login
|
228
|
-
call_api('feed/user/%s/friends' % URI.encode(nickname), options)['entries']
|
229
|
-
end
|
230
|
-
|
231
|
-
# Gets an array of the most recent entries in a room of a given
|
232
|
-
# +nickname+.
|
233
|
-
def get_room_entries(nickname, options = nil)
|
234
|
-
call_api('feed/room/%s' % URI.encode(nickname), options)['entries']
|
235
|
-
end
|
236
|
-
|
237
|
-
# Gets an array of the entries the authenticated user would see on
|
238
|
-
# their rooms page.
|
239
|
-
def get_rooms_entries(options = nil)
|
240
|
-
call_api('feed/rooms', options)['entries']
|
241
|
-
end
|
242
|
-
|
243
|
-
# Gets an entry of a given +entryid+. An exception is raised when
|
244
|
-
# it fails.
|
245
|
-
def get_entry(entryid)
|
246
|
-
call_api('feed/entry/%s' % URI.encode(entryid))['entries'].first
|
247
|
-
end
|
248
|
-
|
249
|
-
# Gets an array of entries of given +entryids+. An exception is
|
250
|
-
# raised when it fails.
|
251
|
-
def get_entries(entryids)
|
252
|
-
call_api('feed/entry', 'entry_id' => entryids)['entries']
|
253
|
-
end
|
254
|
-
|
255
|
-
# Gets an array of entries that match a given +query+.
|
256
|
-
def search(query, options = nil)
|
257
|
-
new_options = { 'q' => query }
|
258
|
-
new_options.merge!(options) if options
|
259
|
-
call_api('feed/search', 'q' => new_options)['entries']
|
260
|
-
end
|
261
|
-
|
262
|
-
# Gets an array of entries that link to a given +url+.
|
263
|
-
def search_for_url(url, options = nil)
|
264
|
-
new_options = { 'url' => url }
|
265
|
-
new_options.merge!(options) if options
|
266
|
-
call_api('feed/url', new_options)['entries']
|
267
|
-
end
|
268
|
-
|
269
|
-
# Gets an array of entries that link to a given +domain+.
|
270
|
-
def search_for_domain(url, options = nil)
|
271
|
-
new_options = { 'url' => url }
|
272
|
-
new_options.merge!(options) if options
|
273
|
-
call_api('feed/domain', new_options)['entries']
|
274
|
-
end
|
275
|
-
|
276
|
-
# Publishes (shares) a given entry.
|
277
|
-
def add_entry(title, options = nil)
|
278
|
-
require_api_login
|
279
|
-
new_options = { 'title' => title }
|
280
|
-
if options
|
281
|
-
options.each { |key, value|
|
282
|
-
case key = key.to_s
|
283
|
-
when 'title', 'link', 'comment', 'room'
|
284
|
-
new_options[key] = value
|
285
|
-
when 'images'
|
286
|
-
value.each_with_index { |value, i|
|
287
|
-
if url = String.try_convert(value)
|
288
|
-
link = nil
|
289
|
-
else
|
290
|
-
if array = Array.try_convert(value)
|
291
|
-
value1, value2 = *array
|
292
|
-
elsif hash = Hash.try_convert(value)
|
293
|
-
value1, value2 = *hash.values_at('url', 'link')
|
294
|
-
else
|
295
|
-
raise TypeError, "Each image must be specified by <image URL>, [<image URL>, <link URL>], or {'url' => <image URL>, 'link' => <link URL>}."
|
296
|
-
end
|
297
|
-
url = String.try_convert(value1) or
|
298
|
-
raise TypeError, "can't convert #{value1.class} into String"
|
299
|
-
link = String.try_convert(value2) or
|
300
|
-
raise TypeError, "can't convert #{value2.class} into String"
|
301
|
-
end
|
302
|
-
new_options['image%d_url' % i] = url
|
303
|
-
new_options['image%d_link' % i] = link if link
|
304
|
-
}
|
305
|
-
when 'audios'
|
306
|
-
value.each_with_index { |value, i|
|
307
|
-
if url = String.try_convert(value)
|
308
|
-
link = nil
|
309
|
-
else
|
310
|
-
if array = Array.try_convert(value)
|
311
|
-
value1, value2 = *array
|
312
|
-
elsif hash = Hash.try_convert(value)
|
313
|
-
value1, value2 = *hash.values_at('url', 'link')
|
314
|
-
else
|
315
|
-
raise TypeError, "Each audio must be specified by <audio URL>, [<audio URL>, <link URL>], or {'url' => <audio URL>, 'link' => <link URL>}."
|
316
|
-
end
|
317
|
-
url = String.try_convert(value1) or
|
318
|
-
raise TypeError, "can't convert #{value1.class} into String"
|
319
|
-
link = String.try_convert(value2) or
|
320
|
-
raise TypeError, "can't convert #{value2.class} into String"
|
321
|
-
end
|
322
|
-
new_options['audio%d_url' % i] = url
|
323
|
-
new_options['audio%d_link' % i] = link if link
|
324
|
-
}
|
325
|
-
when 'files'
|
326
|
-
value.each_with_index { |value, i|
|
327
|
-
if file = IO.try_convert(value)
|
328
|
-
link = nil
|
329
|
-
else
|
330
|
-
if array = Array.try_convert(value)
|
331
|
-
value1, value2 = *array
|
332
|
-
elsif hash = Hash.try_convert(value)
|
333
|
-
value1, value2 = *hash.values_at('file', 'link')
|
334
|
-
else
|
335
|
-
raise TypeError, "Each file must be specified by <file IO>, [<file IO>, <link URL>], or {'file' => <file IO>, 'link' => <link URL>}."
|
336
|
-
end
|
337
|
-
file = IO.try_convert(value1) or
|
338
|
-
raise TypeError, "can't convert #{value1.class} into IO"
|
339
|
-
link = String.try_convert(value2) or
|
340
|
-
raise TypeError, "can't convert #{value2.class} into String"
|
341
|
-
end
|
342
|
-
new_options['file%d' % i] = file
|
343
|
-
new_options['file%d_link' % i] = link if link
|
344
|
-
}
|
345
|
-
end
|
346
|
-
}
|
347
|
-
end
|
348
|
-
call_api('share', nil, new_options)['entries'].first
|
349
|
-
end
|
350
|
-
|
351
|
-
alias publish add_entry
|
352
|
-
alias share add_entry
|
353
|
-
|
354
|
-
# Adds a comment to a given entry.
|
355
|
-
def add_comment(entryid, body)
|
356
|
-
require_api_login
|
357
|
-
call_api('comment', nil, {
|
358
|
-
'entry' => entryid,
|
359
|
-
'body' => body,
|
360
|
-
})
|
361
|
-
end
|
362
|
-
|
363
|
-
# Edits a given comment.
|
364
|
-
def edit_comment(entryid, commentid, body)
|
365
|
-
require_api_login
|
366
|
-
call_api('comment', nil, {
|
367
|
-
'entry' => entryid,
|
368
|
-
'comment' => commentid,
|
369
|
-
'body' => body,
|
370
|
-
})
|
371
|
-
end
|
372
|
-
|
373
|
-
# Deletes a given comment.
|
374
|
-
def delete_comment(entryid, commentid)
|
375
|
-
require_api_login
|
376
|
-
call_api('comment/delete', nil, {
|
377
|
-
'entry' => entryid,
|
378
|
-
'comment' => commentid,
|
379
|
-
})
|
380
|
-
end
|
381
|
-
|
382
|
-
# Undeletes a given comment that is already deleted.
|
383
|
-
def undelete_comment(entryid, commentid)
|
384
|
-
require_api_login
|
385
|
-
call_api('comment/delete', nil, {
|
386
|
-
'entry' => entryid,
|
387
|
-
'comment' => commentid,
|
388
|
-
'undelete' => 'on',
|
389
|
-
})
|
390
|
-
end
|
391
|
-
|
392
|
-
# Adds a "like" to a given entry.
|
393
|
-
def add_like(entryid)
|
394
|
-
require_api_login
|
395
|
-
call_api('like', nil, {
|
396
|
-
'entry' => entryid,
|
397
|
-
})
|
398
|
-
end
|
399
|
-
|
400
|
-
# Deletes an existing "like" from a given entry.
|
401
|
-
def delete_like(entryid)
|
402
|
-
require_api_login
|
403
|
-
call_api('like/delete', nil, {
|
404
|
-
'entry' => entryid,
|
405
|
-
})
|
406
|
-
end
|
407
|
-
|
408
|
-
# Deletes an existing entry of a given +entryid+.
|
409
|
-
def delete_entry(entryid)
|
410
|
-
require_api_login
|
411
|
-
call_api('entry/delete', nil, {
|
412
|
-
'entry' => entryid,
|
413
|
-
})
|
414
|
-
end
|
415
|
-
|
416
|
-
# Undeletes a given entry that is already deleted.
|
417
|
-
def undelete_entry(entryid)
|
418
|
-
require_api_login
|
419
|
-
call_api('entry/delete', nil, {
|
420
|
-
'entry' => entryid,
|
421
|
-
'undelete' => 'on',
|
422
|
-
})
|
423
|
-
end
|
424
|
-
|
425
|
-
# Hides an existing entry of a given +entryid+.
|
426
|
-
def hide_entry(entryid)
|
427
|
-
require_api_login
|
428
|
-
call_api('entry/hide', nil, {
|
429
|
-
'entry' => entryid,
|
430
|
-
})
|
431
|
-
end
|
432
|
-
|
433
|
-
# Unhides a given entry that is already hidden.
|
434
|
-
def unhide_entry(entryid)
|
435
|
-
require_api_login
|
436
|
-
call_api('entry/hide', nil, {
|
437
|
-
'entry' => entryid,
|
438
|
-
'unhide' => 'on',
|
439
|
-
})
|
440
|
-
end
|
441
|
-
|
442
|
-
# Gets a picture of a user of a given +nickname+ (defaulted to the
|
443
|
-
# authenticated user) in blob. Size can be 'small' (default),
|
444
|
-
# 'medium' or 'large',
|
445
|
-
def get_picture(nickname = nil, size = 'small')
|
446
|
-
nickname ||= @nickname
|
447
|
-
nickname or require_api_login
|
448
|
-
call_api('/%s/picture' % URI.escape(nickname), { 'size' => size }, nil, true)
|
449
|
-
end
|
450
|
-
|
451
|
-
# Gets a picture of a room of a given +nickname+ in blob. Size
|
452
|
-
# can be 'small' (default), 'medium' or 'large',
|
453
|
-
def get_room_picture(nickname, size = 'small')
|
454
|
-
call_api('/rooms/%s/picture' % URI.escape(nickname), { 'size' => size }, nil, true)
|
455
|
-
end
|
456
|
-
|
457
|
-
# Gets profile information of a room of a given +nickname+ in
|
458
|
-
# hash.
|
459
|
-
def get_room_profile(nickname)
|
460
|
-
call_api('room/%s/profile' % URI.encode(nickname))
|
461
|
-
end
|
462
|
-
|
463
|
-
# Gets profile information of the authenticated user's list of a
|
464
|
-
# given +nickname+ in hash.
|
465
|
-
def get_list_profile(nickname)
|
466
|
-
call_api('list/%s/profile' % URI.encode(nickname))
|
467
|
-
end
|
468
|
-
|
469
|
-
# Subscribes to a user of a given +nickname+ and returns a status
|
470
|
-
# string.
|
471
|
-
def subscribe_to_user(nickname)
|
472
|
-
call_subscription_api('user/%s/subscribe' % URI.encode(nickname))['status']
|
473
|
-
end
|
474
|
-
|
475
|
-
# Unsubscribes from a user of a given +nickname+ and returns a
|
476
|
-
# status string.
|
477
|
-
def unsubscribe_from_user(nickname)
|
478
|
-
call_subscription_api('user/%s/subscribe?unsubscribe=1' % URI.encode(nickname))['status']
|
479
|
-
end
|
480
|
-
|
481
|
-
# Subscribes to a room of a given +nickname+ and returns a status
|
482
|
-
# string.
|
483
|
-
def subscribe_to_room(nickname)
|
484
|
-
call_subscription_api('room/%s/subscribe' % URI.encode(nickname))['status']
|
485
|
-
end
|
486
|
-
|
487
|
-
# Unsubscribes from a room of a given +nickname+ and returns a
|
488
|
-
# status string.
|
489
|
-
def unsubscribe_from_room(nickname)
|
490
|
-
call_subscription_api('room/%s/subscribe?unsubscribe=1' % URI.encode(nickname))['status']
|
491
|
-
end
|
492
|
-
end
|
12
|
+
autoload :Client, 'friendfeed/v1'
|
13
|
+
autoload :V2, 'friendfeed/v2'
|
493
14
|
end
|
data/lib/friendfeed/compat.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
# -*- mode:ruby -*-
|
2
2
|
#--
|
3
3
|
# friendfeed/compat.rb - defines compatibility methods for older Ruby
|
4
4
|
#++
|
5
|
-
# Copyright (c) 2009 Akinori MUSHA <knu@iDaemons.org>
|
5
|
+
# Copyright (c) 2009, 2010 Akinori MUSHA <knu@iDaemons.org>
|
6
6
|
#
|
7
7
|
# All rights reserved. You can redistribute and/or modify it under the same
|
8
8
|
# terms as Ruby.
|
@@ -1,18 +1,17 @@
|
|
1
|
-
|
1
|
+
# -*- mode: ruby -*-
|
2
2
|
#--
|
3
3
|
# friendfeed/unofficial.rb - provides access to FriendFeed unofficial API's
|
4
4
|
#++
|
5
|
-
# Copyright (c) 2009 Akinori MUSHA <knu@iDaemons.org>
|
5
|
+
# Copyright (c) 2009, 2010 Akinori MUSHA <knu@iDaemons.org>
|
6
6
|
#
|
7
7
|
# All rights reserved. You can redistribute and/or modify it under the same
|
8
8
|
# terms as Ruby.
|
9
9
|
#
|
10
10
|
|
11
|
-
require 'friendfeed'
|
12
|
-
require 'rubygems'
|
13
11
|
require 'json'
|
14
12
|
require 'mechanize'
|
15
13
|
require 'uri'
|
14
|
+
require 'friendfeed/v1'
|
16
15
|
|
17
16
|
module FriendFeed
|
18
17
|
class Client
|
@@ -20,7 +19,8 @@ module FriendFeed
|
|
20
19
|
# Unofficial API
|
21
20
|
#
|
22
21
|
|
23
|
-
|
22
|
+
ROOT_URI = URI.parse("https://friendfeed.com/")
|
23
|
+
LOGIN_URI = ROOT_URI + "/account/login?v=2"
|
24
24
|
|
25
25
|
private
|
26
26
|
|
@@ -89,7 +89,8 @@ module FriendFeed
|
|
89
89
|
|
90
90
|
# Gets a list of services of a user or a room of a given
|
91
91
|
# +nickname+, defaulted to the authenticated user.
|
92
|
-
def get_services(nickname =
|
92
|
+
def get_services(nickname = nil)
|
93
|
+
nickname ||= @nickname
|
93
94
|
agent = get_login_agent()
|
94
95
|
|
95
96
|
services_uri = ROOT_URI + ("/%s/services" % URI.encode(nickname))
|
@@ -0,0 +1,490 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
#--
|
3
|
+
# friendfeed.rb - provides access to FriendFeed API's
|
4
|
+
#++
|
5
|
+
# Copyright (c) 2009, 2010 Akinori MUSHA <knu@iDaemons.org>
|
6
|
+
#
|
7
|
+
# All rights reserved. You can redistribute and/or modify it under the same
|
8
|
+
# terms as Ruby.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'json'
|
12
|
+
require 'mechanize'
|
13
|
+
require 'uri'
|
14
|
+
require 'friendfeed/compat'
|
15
|
+
|
16
|
+
module FriendFeed
|
17
|
+
# Client library for FriendFeed API.
|
18
|
+
class Client
|
19
|
+
attr_reader :nickname
|
20
|
+
|
21
|
+
#
|
22
|
+
# Official API
|
23
|
+
#
|
24
|
+
|
25
|
+
API_URI = URI.parse("https://friendfeed.com/api/")
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def get_api_agent
|
30
|
+
@api_agent ||= Mechanize.new
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate
|
34
|
+
call_api('validate')
|
35
|
+
end
|
36
|
+
|
37
|
+
def require_api_login
|
38
|
+
@nickname or raise 'not logged in'
|
39
|
+
end
|
40
|
+
|
41
|
+
def call_subscription_api(path)
|
42
|
+
require_api_login
|
43
|
+
|
44
|
+
uri = API_URI + path
|
45
|
+
|
46
|
+
agent = Mechanize.new
|
47
|
+
agent.auth('username', @nickname)
|
48
|
+
JSON.parse(agent.post(uri, { 'apikey' => @remote_key }).body)
|
49
|
+
end
|
50
|
+
|
51
|
+
public
|
52
|
+
|
53
|
+
attr_reader :nickname, :remote_key
|
54
|
+
|
55
|
+
# Performs a login with a +nickname+ and +remote key+ and returns
|
56
|
+
# self. This enables call of any official API that requires
|
57
|
+
# authentication. It is not needed to call this method if you
|
58
|
+
# have called login(), which internally obtains a remote key and
|
59
|
+
# calls this method. An exception is raised if authentication
|
60
|
+
# fails.
|
61
|
+
def api_login(nickname, remote_key)
|
62
|
+
@nickname = nickname
|
63
|
+
@remote_key = remote_key
|
64
|
+
@api_agent = get_api_agent()
|
65
|
+
@api_agent.auth(@nickname, @remote_key)
|
66
|
+
validate
|
67
|
+
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Calls an official API specified by a +path+ with optional
|
72
|
+
# +get_parameters+ and +post_parameters+, and returns an object
|
73
|
+
# parsed from a JSON response. If +post_parameters+ is given, a
|
74
|
+
# POST request is issued. A GET request is issued otherwise.
|
75
|
+
def call_api(path, get_parameters = nil, post_parameters = nil, raw = false)
|
76
|
+
api_agent = get_api_agent()
|
77
|
+
|
78
|
+
uri = API_URI + path
|
79
|
+
if get_parameters
|
80
|
+
uri.query = get_parameters.map { |key, value|
|
81
|
+
key = key.to_s
|
82
|
+
if array = Array.try_convert(value)
|
83
|
+
value = array.join(',')
|
84
|
+
else
|
85
|
+
value = value.to_s
|
86
|
+
end
|
87
|
+
URI.encode(key) + "=" + URI.encode(value)
|
88
|
+
}.join('&')
|
89
|
+
end
|
90
|
+
|
91
|
+
if post_parameters
|
92
|
+
body = api_agent.post(uri, post_parameters).body
|
93
|
+
else
|
94
|
+
body = api_agent.get_file(uri)
|
95
|
+
end
|
96
|
+
|
97
|
+
if raw
|
98
|
+
body
|
99
|
+
else
|
100
|
+
JSON.parse(body)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Gets profile information of a user of a given +nickname+,
|
105
|
+
# defaulted to the authenticated user, in hash.
|
106
|
+
def get_profile(nickname = nil)
|
107
|
+
nickname ||= @nickname
|
108
|
+
nickname or require_api_login
|
109
|
+
call_api('user/%s/profile' % URI.encode(nickname))
|
110
|
+
end
|
111
|
+
|
112
|
+
# Edits profile information of the authenticated user. The fields
|
113
|
+
# "name" and "picture" are supported.
|
114
|
+
def edit_profile(hash)
|
115
|
+
nickname or require_api_login
|
116
|
+
call_api('user/%s/profile' % URI.encode(nickname), nil, hash)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Gets an array of profile information of users of given
|
120
|
+
# +nicknames+.
|
121
|
+
def get_profiles(nicknames)
|
122
|
+
call_api('profiles', 'nickname' => nicknames)['profiles']
|
123
|
+
end
|
124
|
+
|
125
|
+
# Gets an array of profile information of friends of a user of a
|
126
|
+
# given +nickname+ (defaulted to the authenticated user) is
|
127
|
+
# subscribing to.
|
128
|
+
def get_real_friends(nickname = nil)
|
129
|
+
nickname ||= @nickname
|
130
|
+
nickname or require_api_login
|
131
|
+
nicknames = []
|
132
|
+
get_profile(@nickname)['subscriptions'].each { |subscription|
|
133
|
+
if nickname = subscription['nickname']
|
134
|
+
nicknames << nickname
|
135
|
+
end
|
136
|
+
}
|
137
|
+
get_profiles(nicknames)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Gets an array of profile information of the authenticated user's
|
141
|
+
# imaginary friends.
|
142
|
+
def get_imaginary_friends
|
143
|
+
nickname or require_api_login
|
144
|
+
profiles = []
|
145
|
+
get_profile(@nickname)['subscriptions'].each { |subscription|
|
146
|
+
if subscription['nickname'].nil?
|
147
|
+
profiles << get_profile(subscription['id'])
|
148
|
+
end
|
149
|
+
}
|
150
|
+
profiles
|
151
|
+
end
|
152
|
+
|
153
|
+
# Gets profile information of one of the authenticated user's
|
154
|
+
# imaginary friends.
|
155
|
+
def get_imaginary_friend(id)
|
156
|
+
get_profile(id)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Gets an array of the most recent public entries.
|
160
|
+
def get_public_entries(options = nil)
|
161
|
+
call_api('feed/public', options)['entries']
|
162
|
+
end
|
163
|
+
|
164
|
+
# Gets an array of the entries the authenticated user would see on
|
165
|
+
# their home page.
|
166
|
+
def get_home_entries(options = nil)
|
167
|
+
require_api_login
|
168
|
+
call_api('feed/home', options)['entries']
|
169
|
+
end
|
170
|
+
|
171
|
+
# Gets an array of the entries for the authenticated user's list
|
172
|
+
# of a given +nickname+
|
173
|
+
def get_list_entries(nickname, options = nil)
|
174
|
+
require_api_login
|
175
|
+
call_api('feed/list/%s' % URI.encode(nickname), options)['entries']
|
176
|
+
end
|
177
|
+
|
178
|
+
# Gets an array of the most recent entries from a user of a given
|
179
|
+
# +nickname+ (defaulted to the authenticated user).
|
180
|
+
def get_user_entries(nickname = nil, options = nil)
|
181
|
+
nickname ||= @nickname
|
182
|
+
nickname or require_api_login
|
183
|
+
call_api('feed/user/%s' % URI.encode(nickname), options)['entries']
|
184
|
+
end
|
185
|
+
|
186
|
+
# Gets an array of the most recent entries from users of given
|
187
|
+
# +nicknames+.
|
188
|
+
def get_multi_user_entries(nicknames, options = nil)
|
189
|
+
new_options = { 'nickname' => nicknames }
|
190
|
+
new_options.merge!(options) if options
|
191
|
+
call_api('feed/user', new_options)['entries']
|
192
|
+
end
|
193
|
+
|
194
|
+
# Gets an array of the most recent entries a user of a given
|
195
|
+
# +nickname+ (defaulted to the authenticated user) has commented
|
196
|
+
# on.
|
197
|
+
def get_user_commented_entries(nickname = nil, options = nil)
|
198
|
+
nickname ||= @nickname
|
199
|
+
nickname or require_api_login
|
200
|
+
call_api('feed/user/%s/comments' % URI.encode(nickname), options)['entries']
|
201
|
+
end
|
202
|
+
|
203
|
+
# Gets an array of the most recent entries a user of a given
|
204
|
+
# +nickname+ (defaulted to the authenticated user) has like'd.
|
205
|
+
def get_user_liked_entries(nickname = nil, options = nil)
|
206
|
+
nickname ||= @nickname
|
207
|
+
nickname or require_api_login
|
208
|
+
call_api('feed/user/%s/likes' % URI.encode(nickname), options)['entries']
|
209
|
+
end
|
210
|
+
|
211
|
+
# Gets an array of the most recent entries a user of a given
|
212
|
+
# +nickname+ (defaulted to the authenticated user) has commented
|
213
|
+
# on or like'd.
|
214
|
+
def get_user_discussed_entries(nickname = nil, options = nil)
|
215
|
+
nickname ||= @nickname
|
216
|
+
nickname or require_api_login
|
217
|
+
call_api('feed/user/%s/discussion' % URI.encode(nickname), options)['entries']
|
218
|
+
end
|
219
|
+
|
220
|
+
# Gets an array of the most recent entries from friends of a user
|
221
|
+
# of a given +nickname+ (defaulted to the authenticated user).
|
222
|
+
def get_user_friend_entries(nickname = nil, options = nil)
|
223
|
+
nickname ||= @nickname
|
224
|
+
nickname or require_api_login
|
225
|
+
call_api('feed/user/%s/friends' % URI.encode(nickname), options)['entries']
|
226
|
+
end
|
227
|
+
|
228
|
+
# Gets an array of the most recent entries in a room of a given
|
229
|
+
# +nickname+.
|
230
|
+
def get_room_entries(nickname, options = nil)
|
231
|
+
call_api('feed/room/%s' % URI.encode(nickname), options)['entries']
|
232
|
+
end
|
233
|
+
|
234
|
+
# Gets an array of the entries the authenticated user would see on
|
235
|
+
# their rooms page.
|
236
|
+
def get_rooms_entries(options = nil)
|
237
|
+
call_api('feed/rooms', options)['entries']
|
238
|
+
end
|
239
|
+
|
240
|
+
# Gets an entry of a given +entryid+. An exception is raised when
|
241
|
+
# it fails.
|
242
|
+
def get_entry(entryid)
|
243
|
+
call_api('feed/entry/%s' % URI.encode(entryid))['entries'].first
|
244
|
+
end
|
245
|
+
|
246
|
+
# Gets an array of entries of given +entryids+. An exception is
|
247
|
+
# raised when it fails.
|
248
|
+
def get_entries(entryids)
|
249
|
+
call_api('feed/entry', 'entry_id' => entryids)['entries']
|
250
|
+
end
|
251
|
+
|
252
|
+
# Gets an array of entries that match a given +query+.
|
253
|
+
def search(query, options = nil)
|
254
|
+
new_options = { 'q' => query }
|
255
|
+
new_options.merge!(options) if options
|
256
|
+
call_api('feed/search', 'q' => new_options)['entries']
|
257
|
+
end
|
258
|
+
|
259
|
+
# Gets an array of entries that link to a given +url+.
|
260
|
+
def search_for_url(url, options = nil)
|
261
|
+
new_options = { 'url' => url }
|
262
|
+
new_options.merge!(options) if options
|
263
|
+
call_api('feed/url', new_options)['entries']
|
264
|
+
end
|
265
|
+
|
266
|
+
# Gets an array of entries that link to a given +domain+.
|
267
|
+
def search_for_domain(url, options = nil)
|
268
|
+
new_options = { 'url' => url }
|
269
|
+
new_options.merge!(options) if options
|
270
|
+
call_api('feed/domain', new_options)['entries']
|
271
|
+
end
|
272
|
+
|
273
|
+
# Publishes (shares) a given entry.
|
274
|
+
def add_entry(title, options = nil)
|
275
|
+
require_api_login
|
276
|
+
new_options = { 'title' => title }
|
277
|
+
if options
|
278
|
+
options.each { |key, value|
|
279
|
+
case key = key.to_s
|
280
|
+
when 'title', 'link', 'comment', 'room'
|
281
|
+
new_options[key] = value
|
282
|
+
when 'images'
|
283
|
+
value.each_with_index { |value, i|
|
284
|
+
if url = String.try_convert(value)
|
285
|
+
link = nil
|
286
|
+
else
|
287
|
+
if array = Array.try_convert(value)
|
288
|
+
value1, value2 = *array
|
289
|
+
elsif hash = Hash.try_convert(value)
|
290
|
+
value1, value2 = *hash.values_at('url', 'link')
|
291
|
+
else
|
292
|
+
raise TypeError, "Each image must be specified by <image URL>, [<image URL>, <link URL>], or {'url' => <image URL>, 'link' => <link URL>}."
|
293
|
+
end
|
294
|
+
url = String.try_convert(value1) or
|
295
|
+
raise TypeError, "can't convert #{value1.class} into String"
|
296
|
+
link = String.try_convert(value2) or
|
297
|
+
raise TypeError, "can't convert #{value2.class} into String"
|
298
|
+
end
|
299
|
+
new_options['image%d_url' % i] = url
|
300
|
+
new_options['image%d_link' % i] = link if link
|
301
|
+
}
|
302
|
+
when 'audios'
|
303
|
+
value.each_with_index { |value, i|
|
304
|
+
if url = String.try_convert(value)
|
305
|
+
link = nil
|
306
|
+
else
|
307
|
+
if array = Array.try_convert(value)
|
308
|
+
value1, value2 = *array
|
309
|
+
elsif hash = Hash.try_convert(value)
|
310
|
+
value1, value2 = *hash.values_at('url', 'link')
|
311
|
+
else
|
312
|
+
raise TypeError, "Each audio must be specified by <audio URL>, [<audio URL>, <link URL>], or {'url' => <audio URL>, 'link' => <link URL>}."
|
313
|
+
end
|
314
|
+
url = String.try_convert(value1) or
|
315
|
+
raise TypeError, "can't convert #{value1.class} into String"
|
316
|
+
link = String.try_convert(value2) or
|
317
|
+
raise TypeError, "can't convert #{value2.class} into String"
|
318
|
+
end
|
319
|
+
new_options['audio%d_url' % i] = url
|
320
|
+
new_options['audio%d_link' % i] = link if link
|
321
|
+
}
|
322
|
+
when 'files'
|
323
|
+
value.each_with_index { |value, i|
|
324
|
+
if file = IO.try_convert(value)
|
325
|
+
link = nil
|
326
|
+
else
|
327
|
+
if array = Array.try_convert(value)
|
328
|
+
value1, value2 = *array
|
329
|
+
elsif hash = Hash.try_convert(value)
|
330
|
+
value1, value2 = *hash.values_at('file', 'link')
|
331
|
+
else
|
332
|
+
raise TypeError, "Each file must be specified by <file IO>, [<file IO>, <link URL>], or {'file' => <file IO>, 'link' => <link URL>}."
|
333
|
+
end
|
334
|
+
file = IO.try_convert(value1) or
|
335
|
+
raise TypeError, "can't convert #{value1.class} into IO"
|
336
|
+
link = String.try_convert(value2) or
|
337
|
+
raise TypeError, "can't convert #{value2.class} into String"
|
338
|
+
end
|
339
|
+
new_options['file%d' % i] = file
|
340
|
+
new_options['file%d_link' % i] = link if link
|
341
|
+
}
|
342
|
+
end
|
343
|
+
}
|
344
|
+
end
|
345
|
+
call_api('share', nil, new_options)['entries'].first
|
346
|
+
end
|
347
|
+
|
348
|
+
alias publish add_entry
|
349
|
+
alias share add_entry
|
350
|
+
|
351
|
+
# Adds a comment to a given entry.
|
352
|
+
def add_comment(entryid, body)
|
353
|
+
require_api_login
|
354
|
+
call_api('comment', nil, {
|
355
|
+
'entry' => entryid,
|
356
|
+
'body' => body,
|
357
|
+
})
|
358
|
+
end
|
359
|
+
|
360
|
+
# Edits a given comment.
|
361
|
+
def edit_comment(entryid, commentid, body)
|
362
|
+
require_api_login
|
363
|
+
call_api('comment', nil, {
|
364
|
+
'entry' => entryid,
|
365
|
+
'comment' => commentid,
|
366
|
+
'body' => body,
|
367
|
+
})
|
368
|
+
end
|
369
|
+
|
370
|
+
# Deletes a given comment.
|
371
|
+
def delete_comment(entryid, commentid)
|
372
|
+
require_api_login
|
373
|
+
call_api('comment/delete', nil, {
|
374
|
+
'entry' => entryid,
|
375
|
+
'comment' => commentid,
|
376
|
+
})
|
377
|
+
end
|
378
|
+
|
379
|
+
# Undeletes a given comment that is already deleted.
|
380
|
+
def undelete_comment(entryid, commentid)
|
381
|
+
require_api_login
|
382
|
+
call_api('comment/delete', nil, {
|
383
|
+
'entry' => entryid,
|
384
|
+
'comment' => commentid,
|
385
|
+
'undelete' => 'on',
|
386
|
+
})
|
387
|
+
end
|
388
|
+
|
389
|
+
# Adds a "like" to a given entry.
|
390
|
+
def add_like(entryid)
|
391
|
+
require_api_login
|
392
|
+
call_api('like', nil, {
|
393
|
+
'entry' => entryid,
|
394
|
+
})
|
395
|
+
end
|
396
|
+
|
397
|
+
# Deletes an existing "like" from a given entry.
|
398
|
+
def delete_like(entryid)
|
399
|
+
require_api_login
|
400
|
+
call_api('like/delete', nil, {
|
401
|
+
'entry' => entryid,
|
402
|
+
})
|
403
|
+
end
|
404
|
+
|
405
|
+
# Deletes an existing entry of a given +entryid+.
|
406
|
+
def delete_entry(entryid)
|
407
|
+
require_api_login
|
408
|
+
call_api('entry/delete', nil, {
|
409
|
+
'entry' => entryid,
|
410
|
+
})
|
411
|
+
end
|
412
|
+
|
413
|
+
# Undeletes a given entry that is already deleted.
|
414
|
+
def undelete_entry(entryid)
|
415
|
+
require_api_login
|
416
|
+
call_api('entry/delete', nil, {
|
417
|
+
'entry' => entryid,
|
418
|
+
'undelete' => 'on',
|
419
|
+
})
|
420
|
+
end
|
421
|
+
|
422
|
+
# Hides an existing entry of a given +entryid+.
|
423
|
+
def hide_entry(entryid)
|
424
|
+
require_api_login
|
425
|
+
call_api('entry/hide', nil, {
|
426
|
+
'entry' => entryid,
|
427
|
+
})
|
428
|
+
end
|
429
|
+
|
430
|
+
# Unhides a given entry that is already hidden.
|
431
|
+
def unhide_entry(entryid)
|
432
|
+
require_api_login
|
433
|
+
call_api('entry/hide', nil, {
|
434
|
+
'entry' => entryid,
|
435
|
+
'unhide' => 'on',
|
436
|
+
})
|
437
|
+
end
|
438
|
+
|
439
|
+
# Gets a picture of a user of a given +nickname+ (defaulted to the
|
440
|
+
# authenticated user) in blob. Size can be 'small' (default),
|
441
|
+
# 'medium' or 'large',
|
442
|
+
def get_picture(nickname = nil, size = 'small')
|
443
|
+
nickname ||= @nickname
|
444
|
+
nickname or require_api_login
|
445
|
+
call_api('/%s/picture' % URI.escape(nickname), { 'size' => size }, nil, true)
|
446
|
+
end
|
447
|
+
|
448
|
+
# Gets a picture of a room of a given +nickname+ in blob. Size
|
449
|
+
# can be 'small' (default), 'medium' or 'large',
|
450
|
+
def get_room_picture(nickname, size = 'small')
|
451
|
+
call_api('/rooms/%s/picture' % URI.escape(nickname), { 'size' => size }, nil, true)
|
452
|
+
end
|
453
|
+
|
454
|
+
# Gets profile information of a room of a given +nickname+ in
|
455
|
+
# hash.
|
456
|
+
def get_room_profile(nickname)
|
457
|
+
call_api('room/%s/profile' % URI.encode(nickname))
|
458
|
+
end
|
459
|
+
|
460
|
+
# Gets profile information of the authenticated user's list of a
|
461
|
+
# given +nickname+ in hash.
|
462
|
+
def get_list_profile(nickname)
|
463
|
+
call_api('list/%s/profile' % URI.encode(nickname))
|
464
|
+
end
|
465
|
+
|
466
|
+
# Subscribes to a user of a given +nickname+ and returns a status
|
467
|
+
# string.
|
468
|
+
def subscribe_to_user(nickname)
|
469
|
+
call_subscription_api('user/%s/subscribe' % URI.encode(nickname))['status']
|
470
|
+
end
|
471
|
+
|
472
|
+
# Unsubscribes from a user of a given +nickname+ and returns a
|
473
|
+
# status string.
|
474
|
+
def unsubscribe_from_user(nickname)
|
475
|
+
call_subscription_api('user/%s/subscribe?unsubscribe=1' % URI.encode(nickname))['status']
|
476
|
+
end
|
477
|
+
|
478
|
+
# Subscribes to a room of a given +nickname+ and returns a status
|
479
|
+
# string.
|
480
|
+
def subscribe_to_room(nickname)
|
481
|
+
call_subscription_api('room/%s/subscribe' % URI.encode(nickname))['status']
|
482
|
+
end
|
483
|
+
|
484
|
+
# Unsubscribes from a room of a given +nickname+ and returns a
|
485
|
+
# status string.
|
486
|
+
def unsubscribe_from_room(nickname)
|
487
|
+
call_subscription_api('room/%s/subscribe?unsubscribe=1' % URI.encode(nickname))['status']
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: friendfeed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akinori MUSHA
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-18 00:00:00 +09:00
|
13
13
|
default_executable: tw2ff
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- lib/friendfeed.rb
|
59
59
|
- lib/friendfeed/compat.rb
|
60
60
|
- lib/friendfeed/unofficial.rb
|
61
|
+
- lib/friendfeed/v1.rb
|
61
62
|
- test/friendfeed_test.rb
|
62
63
|
- test/test_helper.rb
|
63
64
|
has_rdoc: true
|