flickr 1.0.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/Rakefile +36 -0
- data/flickr.rb +491 -0
- data/index.html +129 -0
- data/test_flickr.rb +173 -0
- metadata +51 -0
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
task :default => [ :test, :gem, :rdoc ]
|
8
|
+
|
9
|
+
Rake::TestTask.new("test") { |t|
|
10
|
+
t.test_files = FileList['test*.rb']
|
11
|
+
}
|
12
|
+
|
13
|
+
Rake::RDocTask.new { |rdoc|
|
14
|
+
rdoc.rdoc_dir = 'doc'
|
15
|
+
rdoc.rdoc_files.include('flickr.rb')
|
16
|
+
}
|
17
|
+
|
18
|
+
spec = Gem::Specification.new do |s|
|
19
|
+
s.add_dependency('xml-simple', '>= 1.0.7')
|
20
|
+
s.name = 'flickr'
|
21
|
+
s.version = "1.0.0"
|
22
|
+
s.platform = Gem::Platform::RUBY
|
23
|
+
s.summary = "An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond."
|
24
|
+
s.requirements << 'Flickr developers API key'
|
25
|
+
s.files = Dir.glob("*").delete_if { |item| item.include?("svn") }
|
26
|
+
s.require_path = '.'
|
27
|
+
s.autorequire = 'flickr'
|
28
|
+
s.author = "Scott Raymond"
|
29
|
+
s.email = "sco@redgreenblu.com"
|
30
|
+
s.rubyforge_project = "flickr"
|
31
|
+
s.homepage = "http://redgreenblu.com/flickr/"
|
32
|
+
end
|
33
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
34
|
+
pkg.need_zip = true
|
35
|
+
pkg.need_tar = true
|
36
|
+
end
|
data/flickr.rb
ADDED
@@ -0,0 +1,491 @@
|
|
1
|
+
# = Flickr
|
2
|
+
# An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond.
|
3
|
+
#
|
4
|
+
# Author:: Scott Raymond <sco@redgreenblu.com>
|
5
|
+
# Copyright:: Copyright (c) 2005 Scott Raymond <sco@redgreenblu.com>
|
6
|
+
# License:: MIT <http://www.opensource.org/licenses/mit-license.php>
|
7
|
+
#
|
8
|
+
# USAGE:
|
9
|
+
# require 'flickr'
|
10
|
+
# flickr = Flickr.new # create a flickr client
|
11
|
+
# user = flickr.users('sco@scottraymond.net') # lookup a user
|
12
|
+
# user.getInfo.name # get the user's name
|
13
|
+
# user.location # and location
|
14
|
+
# user.photos # grab their collection of Photo objects...
|
15
|
+
# user.groups # ...the groups they're in...
|
16
|
+
# user.contacts # ...their contacts...
|
17
|
+
# user.favorites # ...favorite photos...
|
18
|
+
# user.photosets # ...their photo sets...
|
19
|
+
# user.tags # ...and their tags
|
20
|
+
# recentphotos = flickr.photos # get the 100 most recent public photos
|
21
|
+
# photo = recent.first # or very most recent one
|
22
|
+
# photo.getInfo.url # see its URL,
|
23
|
+
# photo.title # title,
|
24
|
+
# photo.description # and description,
|
25
|
+
# photo.owner # and its owner.
|
26
|
+
# File.open(photo.filename, 'w') do |file|
|
27
|
+
# file.puts p.file # save the photo to a local file
|
28
|
+
# end
|
29
|
+
# flickr.photos.each do |p| # get the last 100 public photos...
|
30
|
+
# File.open(p.filename, 'w') do |f|
|
31
|
+
# f.puts p.file('Square') # ...and save a local copy of their square thumbnail
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
|
35
|
+
# TODO:
|
36
|
+
# - convert dates to ruby Dates
|
37
|
+
# - investigate xmlsimple caching
|
38
|
+
# - make to_s methods automatic?
|
39
|
+
|
40
|
+
# - complete tests
|
41
|
+
# - in tests, implement a MockFlickr object that has stored responses. automate the getting of the responses?
|
42
|
+
|
43
|
+
# - test on a few platforms
|
44
|
+
# - seek feedback from somebody
|
45
|
+
# - make a kickass demo, including autocompleting-ajax photo lookup ala http://mir.aculo.us/images/autocomplete1.mov
|
46
|
+
|
47
|
+
require 'cgi'
|
48
|
+
require 'net/http'
|
49
|
+
require 'xmlsimple'
|
50
|
+
|
51
|
+
# Flickr client class. Requires an API key, and optionally takes an email and password for authentication
|
52
|
+
class Flickr
|
53
|
+
|
54
|
+
attr_accessor :user
|
55
|
+
|
56
|
+
# Replace this API key with your own (see http://www.flickr.com/services/api/misc.api_keys.html)
|
57
|
+
def initialize(api_key='86e18ef2a064ff2255845e029208d7f4', email=nil, password=nil)
|
58
|
+
@api_key = api_key
|
59
|
+
@host = 'http://flickr.com'
|
60
|
+
@api = '/services/rest'
|
61
|
+
login(email, password) if email and password
|
62
|
+
end
|
63
|
+
|
64
|
+
# Takes a Flickr API method name and set of parameters; returns an XmlSimple object with the response
|
65
|
+
def request(method, *params)
|
66
|
+
response = XmlSimple.xml_in(http_get(request_url(method, params)), { 'ForceArray' => false })
|
67
|
+
raise response['err']['msg'] if response['stat'] != 'ok'
|
68
|
+
response
|
69
|
+
end
|
70
|
+
|
71
|
+
# Takes a Flickr API method name and set of parameters; returns the correct URL for the REST API.
|
72
|
+
# If @email and @password are present, authentication information is included
|
73
|
+
def request_url(method, *params)
|
74
|
+
url = "#{@host}#{@api}/?api_key=#{@api_key}&method=flickr.#{method}"
|
75
|
+
params[0][0].each_key do |key| url += "&#{key}=" + CGI::escape(params[0][0][key]) end if params[0][0]
|
76
|
+
url += "&email=#{@email}&password=#{@password}" if @email and @password
|
77
|
+
url
|
78
|
+
end
|
79
|
+
|
80
|
+
# Does an HTTP GET on a given URL and returns the response body
|
81
|
+
def http_get(url)
|
82
|
+
Net::HTTP.get_response(URI.parse(url)).body.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
# Stores authentication credentials to use on all subsequent calls.
|
86
|
+
# If authentication succeeds, returns a User object
|
87
|
+
def login(email='', password='')
|
88
|
+
@email = email
|
89
|
+
@password = password
|
90
|
+
user = request('test.login')['user'] rescue fail
|
91
|
+
@user = User.new(user['id'])
|
92
|
+
end
|
93
|
+
|
94
|
+
# Implements flickr.urls.lookupGroup and flickr.urls.lookupUser
|
95
|
+
def find_by_url(url)
|
96
|
+
response = urls_lookupUser('url'=>url) rescue urls_lookupGroup('url'=>url) rescue nil
|
97
|
+
(response['user']) ? User.new(response['user']['id']) : Group.new(response['group']['id']) unless response.nil?
|
98
|
+
end
|
99
|
+
|
100
|
+
# Implements flickr.photos.getRecent and flickr.photos.search
|
101
|
+
def photos(*criteria)
|
102
|
+
photos = (criteria[0]) ? photos_search(criteria[0]) : photos_getRecent
|
103
|
+
photos['photos']['photo'].collect { |photo| Photo.new(photo['id']) }
|
104
|
+
end
|
105
|
+
|
106
|
+
# Gets public photos with a given tag
|
107
|
+
def tag(tag)
|
108
|
+
photos('tags'=>tag)
|
109
|
+
end
|
110
|
+
|
111
|
+
# Implements flickr.people.getOnlineList, flickr.people.findByEmail, and flickr.people.findByUsername
|
112
|
+
def users(lookup=nil)
|
113
|
+
if(lookup)
|
114
|
+
user = people_findByEmail('find_email'=>lookup)['user'] rescue people_findByUsername('username'=>lookup)['user']
|
115
|
+
return User.new(user['nsid'])
|
116
|
+
else
|
117
|
+
return people_getOnlineList['online']['user'].collect { |person| User.new(person['nsid']) }
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Implements flickr.groups.getActiveList
|
122
|
+
def groups
|
123
|
+
groups_getActiveList['activegroups']['group'].collect { |group| Group.new(group['nsid']) }
|
124
|
+
end
|
125
|
+
|
126
|
+
# Implements flickr.tags.getRelated
|
127
|
+
def related_tags(tag)
|
128
|
+
tags_getRelated('tag_id'=>tag)['tags']['tag']
|
129
|
+
end
|
130
|
+
|
131
|
+
# Implements flickr.photos.licenses.getInfo
|
132
|
+
def licenses
|
133
|
+
photos_licenses_getInfo['licenses']['license']
|
134
|
+
end
|
135
|
+
|
136
|
+
# Implements everything else.
|
137
|
+
# Any method not defined explicitly will be passed on to the Flickr API,
|
138
|
+
# and return an XmlSimple document. For example, Flickr#test_echo is not defined,
|
139
|
+
# so it will pass the call to the flickr.test.echo method.
|
140
|
+
# e.g., Flickr#test_echo['stat'] should == 'ok'
|
141
|
+
def method_missing(method_id, *params)
|
142
|
+
request(method_id.id2name.gsub(/_/, '.'), params[0])
|
143
|
+
end
|
144
|
+
|
145
|
+
# Todo:
|
146
|
+
# logged_in?
|
147
|
+
# if logged in:
|
148
|
+
# flickr.blogs.getList
|
149
|
+
# flickr.favorites.add
|
150
|
+
# flickr.favorites.remove
|
151
|
+
# flickr.groups.browse
|
152
|
+
# flickr.photos.getCounts
|
153
|
+
# flickr.photos.getNotInSet
|
154
|
+
# flickr.photos.getUntagged
|
155
|
+
# flickr.photosets.create
|
156
|
+
# flickr.photosets.orderSets
|
157
|
+
# flickr.tags.getListUserPopular
|
158
|
+
# flickr.test.login
|
159
|
+
# uploading
|
160
|
+
class User
|
161
|
+
|
162
|
+
attr_reader :client, :id, :name, :location, :photos_url, :url, :count, :firstdate, :firstdatetaken
|
163
|
+
|
164
|
+
def initialize(id=nil, username=nil, email=nil, password=nil)
|
165
|
+
@id = id
|
166
|
+
@username = username
|
167
|
+
@email = email
|
168
|
+
@password = password
|
169
|
+
@client = Flickr.new
|
170
|
+
@client.login(email, password) if email and password
|
171
|
+
end
|
172
|
+
|
173
|
+
def username
|
174
|
+
@username.nil? ? getInfo.username : @username
|
175
|
+
end
|
176
|
+
def name
|
177
|
+
@name.nil? ? getInfo.name : @name
|
178
|
+
end
|
179
|
+
def location
|
180
|
+
@location.nil? ? getInfo.location : @location
|
181
|
+
end
|
182
|
+
def count
|
183
|
+
@count.nil? ? getInfo.count : @count
|
184
|
+
end
|
185
|
+
def firstdate
|
186
|
+
@firstdate.nil? ? getInfo.firstdate : @firstdate
|
187
|
+
end
|
188
|
+
def firstdatetaken
|
189
|
+
@firstdatetaken.nil? ? getInfo.firstdatetaken : @firstdatetaken
|
190
|
+
end
|
191
|
+
def photos_url
|
192
|
+
@photos_url.nil? ? getInfo.photos_url : @photos_url
|
193
|
+
end
|
194
|
+
def url
|
195
|
+
@url.nil? ? getInfo.url : @url
|
196
|
+
end
|
197
|
+
|
198
|
+
# Implements flickr.people.getPublicGroups
|
199
|
+
def groups
|
200
|
+
@client.people_getPublicGroups('user_id'=>@id)['groups']['group'].collect { |group| Group.new(group['nsid']) }
|
201
|
+
end
|
202
|
+
|
203
|
+
# Implements flickr.people.getPublicPhotos
|
204
|
+
def photos
|
205
|
+
@client.people_getPublicPhotos('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id']) }
|
206
|
+
# what about non-public photos?
|
207
|
+
end
|
208
|
+
|
209
|
+
# Gets photos with a given tag
|
210
|
+
def tag(tag)
|
211
|
+
@client.photos('user_id'=>@id, 'tags'=>tag)
|
212
|
+
end
|
213
|
+
|
214
|
+
# Implements flickr.contacts.getPublicList and flickr.contacts.getList
|
215
|
+
def contacts
|
216
|
+
@client.contacts_getPublicList('user_id'=>@id)['contacts']['contact'].collect { |contact| User.new(contact['nsid']) }
|
217
|
+
#or
|
218
|
+
end
|
219
|
+
|
220
|
+
# Implements flickr.favorites.getPublicList and flickr.favorites.getList
|
221
|
+
def favorites
|
222
|
+
@client.favorites_getPublicList('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id']) }
|
223
|
+
#or
|
224
|
+
end
|
225
|
+
|
226
|
+
# Implements flickr.photosets.getList
|
227
|
+
def photosets
|
228
|
+
@client.photosets_getList('user_id'=>@id)['photosets']['photoset'].collect { |photoset| Photoset.new(photoset['id']) }
|
229
|
+
end
|
230
|
+
|
231
|
+
# Implements flickr.tags.getListUser
|
232
|
+
def tags
|
233
|
+
@client.tags_getListUser('user_id'=>@id)['who']['tags']['tag'].collect { |tag| tag }
|
234
|
+
end
|
235
|
+
|
236
|
+
# Implements flickr.photos.getContactsPublicPhotos and flickr.photos.getContactsPhotos
|
237
|
+
def contactsPhotos
|
238
|
+
@client.photos_getContactsPublicPhotos('user_id'=>@id)['photos']['photo'].collect { |photo| Photo.new(photo['id']) }
|
239
|
+
# or
|
240
|
+
#@client.photos_getContactsPhotos['photos']['photo'].collect { |photo| Photo.new(photo['id']) }
|
241
|
+
end
|
242
|
+
|
243
|
+
def to_s
|
244
|
+
@name
|
245
|
+
end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
# Implements flickr.people.getInfo, flickr.urls.getUserPhotos, and flickr.urls.getUserProfile
|
250
|
+
def getInfo
|
251
|
+
info = @client.people_getInfo('user_id'=>@id)['person']
|
252
|
+
@username = info['username']
|
253
|
+
@name = info['realname']
|
254
|
+
@location = info['location']
|
255
|
+
@count = info['photos']['count']
|
256
|
+
@firstdate = info['photos']['firstdate']
|
257
|
+
@firstdatetaken = info['photos']['firstdatetaken']
|
258
|
+
@photos_url = @client.urls_getUserPhotos('user_id'=>@id)['user']['url']
|
259
|
+
@url = @client.urls_getUserProfile('user_id'=>@id)['user']['url']
|
260
|
+
self
|
261
|
+
end
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
class Photo
|
266
|
+
|
267
|
+
attr_reader :id, :client
|
268
|
+
|
269
|
+
def initialize(id=nil)
|
270
|
+
@id = id
|
271
|
+
@client = Flickr.new
|
272
|
+
end
|
273
|
+
|
274
|
+
def title
|
275
|
+
@title.nil? ? getInfo.title : @title
|
276
|
+
end
|
277
|
+
|
278
|
+
def owner
|
279
|
+
@owner.nil? ? getInfo.owner : @owner
|
280
|
+
end
|
281
|
+
|
282
|
+
def server
|
283
|
+
@server.nil? ? getInfo.server : @server
|
284
|
+
end
|
285
|
+
|
286
|
+
def isfavorite
|
287
|
+
@isfavorite.nil? ? getInfo.isfavorite : @isfavorite
|
288
|
+
end
|
289
|
+
|
290
|
+
def license
|
291
|
+
@license.nil? ? getInfo.license : @license
|
292
|
+
end
|
293
|
+
|
294
|
+
def rotation
|
295
|
+
@rotation.nil? ? getInfo.rotation : @rotation
|
296
|
+
end
|
297
|
+
|
298
|
+
def description
|
299
|
+
@description.nil? ? getInfo.description : @description
|
300
|
+
end
|
301
|
+
|
302
|
+
def notes
|
303
|
+
@notes.nil? ? getInfo.notes : @notes
|
304
|
+
end
|
305
|
+
|
306
|
+
# Returns the URL for the photo page (default or any specified size)
|
307
|
+
def url(size='Medium')
|
308
|
+
if size=='Medium'
|
309
|
+
"http://flickr.com/photos/#{owner.username}/#{@id}"
|
310
|
+
else
|
311
|
+
sizes(size)['url']
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# Returns the URL for the image (default or any specified size)
|
316
|
+
def source(size='Medium')
|
317
|
+
sizes(size)['source']
|
318
|
+
end
|
319
|
+
|
320
|
+
# Returns the photo file data itself, in any specified size. Example: File.open(photo.title, 'w') { |f| f.puts photo.file }
|
321
|
+
def file(size='Medium')
|
322
|
+
Net::HTTP.get_response(URI.parse(source(size))).body
|
323
|
+
end
|
324
|
+
|
325
|
+
# Unique filename for the image, based on the Flickr NSID
|
326
|
+
def filename
|
327
|
+
"#{@id}.jpg"
|
328
|
+
end
|
329
|
+
|
330
|
+
# Implements flickr.photos.getContext
|
331
|
+
def context
|
332
|
+
context = @client.photos_getContext('photo_id'=>@id)
|
333
|
+
@previousPhoto = Photo.new(context['prevphoto']['id'])
|
334
|
+
@nextPhoto = Photo.new(context['nextphoto']['id'])
|
335
|
+
return [@previousPhoto, @nextPhoto]
|
336
|
+
end
|
337
|
+
|
338
|
+
# Implements flickr.photos.getExif
|
339
|
+
def exif
|
340
|
+
@client.photos_getExif('photo_id'=>@id)['photo']
|
341
|
+
end
|
342
|
+
|
343
|
+
# Implements flickr.photos.getPerms
|
344
|
+
def permissions
|
345
|
+
@client.photos_getPerms('photo_id'=>@id)['perms']
|
346
|
+
end
|
347
|
+
|
348
|
+
# Implements flickr.photos.getSizes
|
349
|
+
def sizes(size=nil)
|
350
|
+
sizes = @client.photos_getSizes('photo_id'=>@id)['sizes']['size']
|
351
|
+
sizes = sizes.find{|asize| asize['label']==size} if size
|
352
|
+
return sizes
|
353
|
+
end
|
354
|
+
|
355
|
+
# flickr.tags.getListPhoto
|
356
|
+
def tags
|
357
|
+
@client.tags_getListPhoto('photo_id'=>@id)['photo']['tags']
|
358
|
+
end
|
359
|
+
|
360
|
+
# Implements flickr.photos.notes.add
|
361
|
+
def add_note(note)
|
362
|
+
end
|
363
|
+
|
364
|
+
# Implements flickr.photos.setDates
|
365
|
+
def dates=(dates)
|
366
|
+
end
|
367
|
+
|
368
|
+
# Implements flickr.photos.setPerms
|
369
|
+
def perms=(perms)
|
370
|
+
end
|
371
|
+
|
372
|
+
# Implements flickr.photos.setTags
|
373
|
+
def tags=(tags)
|
374
|
+
end
|
375
|
+
|
376
|
+
# Implements flickr.photos.setMeta
|
377
|
+
def title=(title)
|
378
|
+
end
|
379
|
+
def description=(title)
|
380
|
+
end
|
381
|
+
|
382
|
+
# Implements flickr.photos.addTags
|
383
|
+
def add_tag(tag)
|
384
|
+
end
|
385
|
+
|
386
|
+
# Implements flickr.photos.removeTag
|
387
|
+
def remove_tag(tag)
|
388
|
+
end
|
389
|
+
|
390
|
+
# Implements flickr.photos.transform.rotate
|
391
|
+
def rotate
|
392
|
+
end
|
393
|
+
|
394
|
+
# Implements flickr.blogs.postPhoto
|
395
|
+
def postToBlog(blog_id, title='', description='')
|
396
|
+
@client.blogs_postPhoto('photo_id'=>@id, 'title'=>title, 'description'=>description)
|
397
|
+
end
|
398
|
+
|
399
|
+
# Implements flickr.photos.notes.delete
|
400
|
+
def deleteNote(note_id)
|
401
|
+
end
|
402
|
+
|
403
|
+
# Implements flickr.photos.notes.edit
|
404
|
+
def editNote(note_id)
|
405
|
+
end
|
406
|
+
|
407
|
+
# Converts the Photo to a string by returning its title
|
408
|
+
def to_s
|
409
|
+
getInfo.title
|
410
|
+
end
|
411
|
+
|
412
|
+
private
|
413
|
+
|
414
|
+
# Implements flickr.photos.getInfo
|
415
|
+
def getInfo
|
416
|
+
info = @client.photos_getInfo('photo_id'=>@id)['photo']
|
417
|
+
@title = info['title']
|
418
|
+
@owner = User.new(info['owner']['nsid'])
|
419
|
+
@server = info['server']
|
420
|
+
@isfavorite = info['isfavorite']
|
421
|
+
@license = info['license']
|
422
|
+
@rotation = info['rotation']
|
423
|
+
@description = info['description']
|
424
|
+
@notes = info['notes']['note']#.collect { |note| Note.new(note.id) }
|
425
|
+
self
|
426
|
+
end
|
427
|
+
|
428
|
+
end
|
429
|
+
|
430
|
+
# Todo:
|
431
|
+
# flickr.groups.pools.add
|
432
|
+
# flickr.groups.pools.getContext
|
433
|
+
# flickr.groups.pools.getGroups
|
434
|
+
# flickr.groups.pools.getPhotos
|
435
|
+
# flickr.groups.pools.remove
|
436
|
+
class Group
|
437
|
+
attr_reader :id, :client, :name, :members, :online, :privacy, :chatid, :chatcount, :url
|
438
|
+
|
439
|
+
def initialize(id=nil)
|
440
|
+
@id = id
|
441
|
+
@client = Flickr.new
|
442
|
+
end
|
443
|
+
|
444
|
+
# Implements flickr.groups.getInfo and flickr.urls.getGroup
|
445
|
+
# private, once we can call it as needed
|
446
|
+
def getInfo
|
447
|
+
info = @client.groups_getInfo('group_id'=>@id)['group']
|
448
|
+
@name = info['name']
|
449
|
+
@members = info['members']
|
450
|
+
@online = info['online']
|
451
|
+
@privacy = info['privacy']
|
452
|
+
@chatid = info['chatid']
|
453
|
+
@chatcount = info['chatcount']
|
454
|
+
@url = @client.urls_getGroup('group_id'=>@id)['group']['url']
|
455
|
+
self
|
456
|
+
end
|
457
|
+
|
458
|
+
end
|
459
|
+
|
460
|
+
# Todo:
|
461
|
+
# flickr.photosets.delete
|
462
|
+
# flickr.photosets.editMeta
|
463
|
+
# flickr.photosets.editPhotos
|
464
|
+
# flickr.photosets.getContext
|
465
|
+
# flickr.photosets.getInfo
|
466
|
+
# flickr.photosets.getPhotos
|
467
|
+
class Photoset
|
468
|
+
|
469
|
+
attr_reader :id, :client, :owner, :primary, :photos, :title, :description, :url
|
470
|
+
|
471
|
+
def initialize(id=nil)
|
472
|
+
@id = id
|
473
|
+
@client = Flickr.new
|
474
|
+
end
|
475
|
+
|
476
|
+
# Implements flickr.photosets.getInfo
|
477
|
+
# private, once we can call it as needed
|
478
|
+
def getInfo
|
479
|
+
info = @client.photosets_getInfo('photosets_id'=>@id)['photoset']
|
480
|
+
@owner = User.new(info['owner'])
|
481
|
+
@primary = info['primary']
|
482
|
+
@photos = info['photos']
|
483
|
+
@title = info['title']
|
484
|
+
@description = info['description']
|
485
|
+
@url = "http://www.flickr.com/photos/#{@owner.getInfo.username}/sets/#{@id}/"
|
486
|
+
self
|
487
|
+
end
|
488
|
+
|
489
|
+
end
|
490
|
+
|
491
|
+
end
|
data/index.html
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<title>Flickr.rb</title>
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
font-family: arial;
|
9
|
+
color: #222;
|
10
|
+
margin: 0;
|
11
|
+
padding: 1.5em;
|
12
|
+
font-size: 0.9em;
|
13
|
+
}
|
14
|
+
h1 {
|
15
|
+
margin: 0;
|
16
|
+
}
|
17
|
+
h1+p {
|
18
|
+
margin-top: 0;
|
19
|
+
}
|
20
|
+
div {
|
21
|
+
border-top: 1px solid #ccc;
|
22
|
+
}
|
23
|
+
h2 {
|
24
|
+
float: left;
|
25
|
+
text-transform: uppercase;
|
26
|
+
font-size: .8em;
|
27
|
+
color: #555;
|
28
|
+
margin-top: .8em;
|
29
|
+
}
|
30
|
+
div p {
|
31
|
+
margin-top: .8em;
|
32
|
+
margin-left: 9em;
|
33
|
+
}
|
34
|
+
div pre {
|
35
|
+
margin-left: 11em;
|
36
|
+
}
|
37
|
+
code {
|
38
|
+
background-color: #ddd;
|
39
|
+
padding: 0em;
|
40
|
+
}
|
41
|
+
code span {
|
42
|
+
color: #707;
|
43
|
+
}
|
44
|
+
</style>
|
45
|
+
</head>
|
46
|
+
<body>
|
47
|
+
<h1>Flickr.rb</h1>
|
48
|
+
<p><em>An insanely easy Ruby interface to the <a href="http://flickr.com/services/api/">Flickr</a> photo-sharing service. By Scott Raymond <<a href="mailto:sco@scottraymond.net">sco@redgreenblu.com</a>></em></p>
|
49
|
+
|
50
|
+
<div>
|
51
|
+
<h2>Get it</h2>
|
52
|
+
<p>via RubyGems: <code>gem install flickr</code><br/>
|
53
|
+
...or download the gem: <a href="pkg/flickr-1.0.0.gem">flickr-1.0.0.gem</a><br/>
|
54
|
+
...or just get the source by itself: <a href="flickr.rb">flickr.rb</a></p>
|
55
|
+
<p>You'll also need a <a href="http://www.flickr.com/services/api/misc.api_keys.html">Flickr API key</a>.</p>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<div>
|
59
|
+
<h2>Example</h2>
|
60
|
+
<p><pre><code>require 'flickr'
|
61
|
+
|
62
|
+
<span># basics</span>
|
63
|
+
flickr = Flickr.new <span># create a flickr client</span>
|
64
|
+
flickr.login(email, password) <span># log in for actions that require it</span>
|
65
|
+
flickr.users <span># get all users currently online</span>
|
66
|
+
flickr.photos <span># get the 100 most recent public photos</span>
|
67
|
+
flickr.tag('red') <span># search for photos tagged with 'red'</span>
|
68
|
+
flickr.groups <span># get all active public groups</span>
|
69
|
+
|
70
|
+
<span># working with users</span>
|
71
|
+
user = flickr.users('sco') <span># lookup a user by username</span>
|
72
|
+
user = flickr.users('sco@scottraymond.net') <span># or email</span>
|
73
|
+
user.name <span># get the user's real name</span>
|
74
|
+
user.location <span># and location</span>
|
75
|
+
user.photos <span># grab their collection of Photo objects...</span>
|
76
|
+
user.tag('red') <span># search their photos for the tag 'red'</span>
|
77
|
+
user.groups <span># ...the groups they're in...</span>
|
78
|
+
user.contacts <span># ...their contacts...</span>
|
79
|
+
user.favorites <span># ...favorite photos...</span>
|
80
|
+
user.photosets <span># ...their photo sets...</span>
|
81
|
+
user.tags <span># ...and their tags</span>
|
82
|
+
|
83
|
+
<span># working with photos</span>
|
84
|
+
photo = flickr.photos.first <span># get the most recent public photo</span>
|
85
|
+
photo.url <span># see the URL for the photo's page...</span>
|
86
|
+
photo.url('Original') <span># as well as for its various sizes</span>
|
87
|
+
photo.source <span># see the URL for the JPEG itself...</span>
|
88
|
+
photo.source('Small') <span># as well as for its various sizes</span>
|
89
|
+
photo.title <span># get its title,</span>
|
90
|
+
photo.description <span># description,</span>
|
91
|
+
photo.owner <span># owner,</span>
|
92
|
+
photo.owner.name <span># and its owner's name, etc.</span>
|
93
|
+
|
94
|
+
<span># downloading files</span>
|
95
|
+
File.open(photo.filename, 'w') do |file|
|
96
|
+
file.puts photo.file <span># save the photo to a local file</span>
|
97
|
+
end
|
98
|
+
flickr.photos.each do |photo| <span># get the last 100 public photos...</span>
|
99
|
+
File.open(photo.filename, 'w') do |file|
|
100
|
+
file.puts photo.file('Square') <span># ...and save a local copy of their square thumbnail</span>
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
<span># ...and so much more. see the docs for full details.</span>
|
105
|
+
|
106
|
+
</code></pre></p>
|
107
|
+
</div>
|
108
|
+
|
109
|
+
<div>
|
110
|
+
<h2>Documentation</h2>
|
111
|
+
<p><a href="doc/">Rdoc Documentation</a><br/><small>Also see: <a href="http://www.flickr.com/services/api/">Original Flickr API reference</a></small></p>
|
112
|
+
</div>
|
113
|
+
|
114
|
+
<div>
|
115
|
+
<h2>License</h2>
|
116
|
+
<p><a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>. Attribution and contribution encouraged.</p>
|
117
|
+
</div>
|
118
|
+
|
119
|
+
<div>
|
120
|
+
<h2>Thanks</h2>
|
121
|
+
<p>
|
122
|
+
<strong>Maik Schmidt</strong> for <a href="http://www.maik-schmidt.de/xml-simple.html">XmlSimple</a>,
|
123
|
+
<strong>Ludicorp</strong> for <a href="http://www.flickr.com/">Flickr</a>,
|
124
|
+
and <strong>Premshee Pillai</strong> for <a href="http://premshree.seacrow.com/code/ruby/flickr-ruby">Flickr-ruby</a>.
|
125
|
+
</p>
|
126
|
+
</div>
|
127
|
+
|
128
|
+
</body>
|
129
|
+
</html>
|
data/test_flickr.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'flickr'
|
2
|
+
require 'test/unit'
|
3
|
+
#require 'stringio'
|
4
|
+
|
5
|
+
class MockFlickr < Flickr
|
6
|
+
#@@data = eval(DATA.read)
|
7
|
+
#def _get_response(url)
|
8
|
+
# raise "no data for #{url.inspect}" unless @@data.has_key? url
|
9
|
+
# return REXML::Document.new(@@data[url])
|
10
|
+
#end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestFlickr < Test::Unit::TestCase
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@api_key = '86e18ef2a064ff2255845e029208d7f4'
|
17
|
+
@email = 'sco@redgreenblu.com'
|
18
|
+
@password = 'flickr.rb'
|
19
|
+
@username = 'flickr.rb'
|
20
|
+
@user_id = '35034359890@N01'
|
21
|
+
@photo_id = '8649502'
|
22
|
+
@tag = 'onetag'
|
23
|
+
@tags = 'onetag twotag'
|
24
|
+
@tag_id = '27359619'
|
25
|
+
@date_posted = '2005-01-01 16:01:26'
|
26
|
+
@dates = '1093566950'
|
27
|
+
@group_id = '37718676860@N01'
|
28
|
+
@group_url = 'http://flickr.com/groups/kansascity/'
|
29
|
+
@user_url = 'http://flickr.com/photos/sco/'
|
30
|
+
@title = 'New Set'
|
31
|
+
@f = MockFlickr.new
|
32
|
+
@f.login(@email, @password)
|
33
|
+
@u = @f.users(@email)
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
##### DIRECT MODE
|
38
|
+
|
39
|
+
def test_test_echo
|
40
|
+
assert_equal @f.test_echo['stat'], 'ok'
|
41
|
+
end
|
42
|
+
def test_test_login
|
43
|
+
assert_equal @f.test_login['stat'], 'ok'
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
##### BASICS
|
48
|
+
|
49
|
+
def test_request
|
50
|
+
assert_equal @f.request('test.echo')['stat'], 'ok'
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_request_url
|
54
|
+
assert_equal "http://flickr.com/services/rest/?api_key=#{@api_key}&method=flickr.test.echo&foo=bar&email=#{@email}&password=#{@password}", @f.request_url('test.echo', ['foo'=>'bar'])
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_login
|
58
|
+
assert_equal @username, @f.user.getInfo.username
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_find_by_url
|
62
|
+
assert_equal @group_id, @f.find_by_url(@group_url).getInfo.id # find group by URL
|
63
|
+
assert_equal @user_id, @f.find_by_url(@user_url).getInfo.id # find user by URL
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_photos
|
67
|
+
assert_equal 100, @f.photos.size # find recent
|
68
|
+
assert_equal @user_id, @f.photos('user_id'=>@user_id).first.getInfo.owner.id # search by user_id
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_users
|
72
|
+
assert_equal @username, @f.users(@email).getInfo.username # find by email
|
73
|
+
assert_equal @username, @f.users(@username).getInfo.username # find by username
|
74
|
+
assert_kind_of Flickr::User, @f.users.first # find all online users
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_groups
|
78
|
+
assert_kind_of Flickr::Group, @f.groups.first # find all active groups
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_licenses
|
82
|
+
assert_kind_of Array, @f.licenses # find all licenses
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
##### USER
|
87
|
+
|
88
|
+
def test_getInfo
|
89
|
+
@u.getInfo
|
90
|
+
assert_equal @username, @u.username
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_groups
|
94
|
+
assert_kind_of Flickr::Group, @u.groups.first # public groups
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_photos
|
98
|
+
assert_kind_of Flickr::Photo, @u.photos.first # public photos
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_contacts
|
102
|
+
assert_kind_of Flickr::User, @u.contacts.first # public contacts
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_favorites
|
106
|
+
assert_kind_of Flickr::Photo, @u.favorites.first # public favorites
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_photosets
|
110
|
+
assert_kind_of Flickr::Photoset, @u.photosets.first # public photosets
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_tags
|
114
|
+
assert_kind_of Array, @u.tags # tags
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_contactsPhotos
|
118
|
+
assert_kind_of Flickr::Photo, @u.contactsPhotos.first # contacts' favorites
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
##### PHOTO
|
123
|
+
|
124
|
+
def test_getInfo
|
125
|
+
@p.getInfo
|
126
|
+
assert_equal @photo_id, @p.id
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
##### PHOTOSETS
|
131
|
+
|
132
|
+
#def setup
|
133
|
+
# super
|
134
|
+
# @photoset = @f.photosets_create('title'=>@title, 'primary_photo_id'=>@photo_id)
|
135
|
+
# @photoset_id = @photoset['photoset']['id']
|
136
|
+
#end
|
137
|
+
#def teardown
|
138
|
+
# @f.photosets_delete('photoset_id'=>@photoset_id)
|
139
|
+
#end
|
140
|
+
|
141
|
+
def test_photosets_editMeta
|
142
|
+
assert_equal @f.photosets_editMeta('photoset_id'=>@photoset_id, 'title'=>@title)['stat'], 'ok'
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_photosets_editPhotos
|
146
|
+
assert_equal @f.photosets_editPhotos('photoset_id'=>@photoset_id, 'primary_photo_id'=>@photo_id, 'photo_ids'=>@photo_id)['stat'], 'ok'
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_photosets_getContext
|
150
|
+
assert_equal @f.photosets_getContext('photoset_id'=>@photoset_id, 'photo_id'=>@photo_id)['stat'], 'ok'
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_photosets_getContext
|
154
|
+
assert_equal @f.photosets_getContext('photoset_id'=>@photoset_id, 'photo_id'=>@photo_id)['stat'], 'ok'
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_photosets_getInfo
|
158
|
+
assert_equal @f.photosets_getInfo('photoset_id'=>@photoset_id)['stat'], 'ok'
|
159
|
+
end
|
160
|
+
|
161
|
+
def test_photosets_getList
|
162
|
+
assert_equal @f.photosets_getList['stat'], 'ok'
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_photosets_getPhotos
|
166
|
+
assert_equal @f.photosets_getPhotos('photoset_id'=>@photoset_id)['stat'], 'ok'
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_photosets_orderSets
|
170
|
+
assert_equal @f.photosets_orderSets('photoset_ids'=>@photoset_id)['stat'], 'ok'
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
metadata
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.1
|
3
|
+
specification_version: 1
|
4
|
+
name: flickr
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2005-04-19
|
8
|
+
summary: An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond.
|
9
|
+
require_paths:
|
10
|
+
- "."
|
11
|
+
author: Scott Raymond
|
12
|
+
email: sco@redgreenblu.com
|
13
|
+
homepage: http://redgreenblu.com/flickr/
|
14
|
+
rubyforge_project: flickr
|
15
|
+
description:
|
16
|
+
autorequire: flickr
|
17
|
+
default_executable:
|
18
|
+
bindir: bin
|
19
|
+
has_rdoc: false
|
20
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
+
requirements:
|
22
|
+
-
|
23
|
+
- ">"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: 0.0.0
|
26
|
+
version:
|
27
|
+
platform: ruby
|
28
|
+
files:
|
29
|
+
- flickr.rb
|
30
|
+
- index.html
|
31
|
+
- pkg
|
32
|
+
- Rakefile
|
33
|
+
- test_flickr.rb
|
34
|
+
test_files: []
|
35
|
+
rdoc_options: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
executables: []
|
38
|
+
extensions: []
|
39
|
+
requirements:
|
40
|
+
- Flickr developers API key
|
41
|
+
dependencies:
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: xml-simple
|
44
|
+
version_requirement:
|
45
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
46
|
+
requirements:
|
47
|
+
-
|
48
|
+
- ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 1.0.7
|
51
|
+
version:
|