flickr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/Rakefile +36 -0
  2. data/flickr.rb +491 -0
  3. data/index.html +129 -0
  4. data/test_flickr.rb +173 -0
  5. metadata +51 -0
@@ -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
@@ -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
@@ -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 &lt;<a href="mailto:sco@scottraymond.net">sco@redgreenblu.com</a>&gt;</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>
@@ -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: