acts_as_unvlogable 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,713 @@
1
+ # included here to skip the gem dependency and modified to manage video capabilities.
2
+ # this is the updated version from http://github.com/ctagg/flickr/tree/master/lib/flickr.rb
3
+
4
+ # = Flickr
5
+ # An insanely easy interface to the Flickr photo-sharing service. By Scott Raymond.
6
+ #
7
+ # Author:: Scott Raymond <sco@redgreenblu.com>
8
+ # Copyright:: Copyright (c) 2005 Scott Raymond <sco@redgreenblu.com>. Additional content by Patrick Plattes and Chris Taggart (http://pushrod.wordpress.com)
9
+ # License:: MIT <http://www.opensource.org/licenses/mit-license.php>
10
+ #
11
+ # BASIC USAGE:
12
+ # require 'flickr'
13
+ # flickr = Flickr.new('some_flickr_api_key') # create a flickr client (get an API key from http://www.flickr.com/services/api/)
14
+ # user = flickr.users('sco@scottraymond.net') # lookup a user
15
+ # user.name # get the user's name
16
+ # user.location # and location
17
+ # user.photos # grab their collection of Photo objects...
18
+ # user.groups # ...the groups they're in...
19
+ # user.contacts # ...their contacts...
20
+ # user.favorites # ...favorite photos...
21
+ # user.photosets # ...their photo sets...
22
+ # user.tags # ...and their tags
23
+ # recentphotos = flickr.photos # get the 100 most recent public photos
24
+ # photo = recentphotos.first # or very most recent one
25
+ # photo.url # see its URL,
26
+ # photo.title # title,
27
+ # photo.description # and description,
28
+ # photo.owner # and its owner.
29
+ # File.open(photo.filename, 'w') do |file|
30
+ # file.puts p.file # save the photo to a local file
31
+ # end
32
+ # flickr.photos.each do |p| # get the last 100 public photos...
33
+ # File.open(p.filename, 'w') do |f|
34
+ # f.puts p.file('Square') # ...and save a local copy of their square thumbnail
35
+ # end
36
+ # end
37
+
38
+
39
+ require 'cgi'
40
+ require 'net/http'
41
+ require 'xmlsimple'
42
+ require 'digest/md5'
43
+
44
+ # Flickr client class. Requires an API key
45
+ class Flickr
46
+ attr_reader :api_key, :auth_token
47
+ attr_accessor :user
48
+
49
+ HOST_URL = 'http://flickr.com'
50
+ API_PATH = '/services/rest'
51
+
52
+ # Flickr, annoyingly, uses a number of representations to specify the size
53
+ # of a photo, depending on the context. It gives a label such a "Small" or
54
+ # "Medium" to a size of photo, when returning all possible sizes. However,
55
+ # when generating the uri for the page that features that size of photo, or
56
+ # the source url for the image itself it uses a single letter. Bizarrely,
57
+ # these letters are different depending on whether you want the Flickr page
58
+ # for the photo or the source uri -- e.g. a "Small" photo (240 pixels on its
59
+ # longest side) may be viewed at
60
+ # "http://www.flickr.com/photos/sco/2397458775/sizes/s/"
61
+ # but its source is at
62
+ # "http://farm4.static.flickr.com/3118/2397458775_2ec2ddc324_m.jpg".
63
+ # The VALID_SIZES hash associates the correct letter with a label
64
+ VALID_SIZES = { "Square" => ["s", "sq"],
65
+ "Thumbnail" => ["t", "t"],
66
+ "Small" => ["m", "s"],
67
+ "Medium" => [nil, "m"],
68
+ "Large" => ["b", "l"]
69
+ }
70
+
71
+ # To use the Flickr API you need an api key
72
+ # (see http://www.flickr.com/services/api/misc.api_keys.html), and the flickr
73
+ # client object shuld be initialized with this. You'll also need a shared
74
+ # secret code if you want to use authentication (e.g. to get a user's
75
+ # private photos)
76
+ # There are two ways to initialize the Flickr client. The preferred way is with
77
+ # a hash of params, e.g. 'api_key' => 'your_api_key', 'shared_secret' =>
78
+ # 'shared_secret_code'. The older (deprecated) way is to pass an ordered series of
79
+ # arguments. This is provided for continuity only, as several of the arguments
80
+ # are no longer usable ('email', 'password')
81
+ def initialize(api_key_or_params=nil, email=nil, password=nil, shared_secret=nil)
82
+ @host = HOST_URL
83
+ @api = API_PATH
84
+ if api_key_or_params.is_a?(Hash)
85
+ @api_key = api_key_or_params['api_key']
86
+ @shared_secret = api_key_or_params['shared_secret']
87
+ @auth_token = api_key_or_params['auth_token']
88
+ else
89
+ @api_key = api_key_or_params
90
+ @shared_secret = shared_secret
91
+ login(email, password) if email and password
92
+ end
93
+ end
94
+
95
+ # Gets authentication token given a Flickr frob, which is returned when user
96
+ # allows access to their account for the application with the api_key which
97
+ # made the request
98
+ def get_token_from(frob)
99
+ auth_response = request("auth.getToken", :frob => frob)['auth']
100
+ @auth_token = auth_response['token']
101
+ @user = User.new( 'id' => auth_response['user']['nsid'],
102
+ 'username' => auth_response['user']['username'],
103
+ 'name' => auth_response['user']['fullname'],
104
+ 'client' => self)
105
+ @auth_token
106
+ end
107
+
108
+ # Stores authentication credentials to use on all subsequent calls.
109
+ # If authentication succeeds, returns a User object.
110
+ # NB This call is no longer in API and will result in an error if called
111
+ def login(email='', password='')
112
+ @email = email
113
+ @password = password
114
+ user = request('test.login')['user'] rescue fail
115
+ @user = User.new(user['id'], nil, nil, nil, @api_key)
116
+ end
117
+
118
+ # Implements flickr.urls.lookupGroup and flickr.urls.lookupUser
119
+ def find_by_url(url)
120
+ response = urls_lookupUser('url'=>url) rescue urls_lookupGroup('url'=>url) rescue nil
121
+ (response['user']) ? User.new(response['user']['id'], nil, nil, nil, @api_key) : Group.new(response['group']['id'], @api_key) unless response.nil?
122
+ end
123
+
124
+ # Implements flickr.photos.getRecent and flickr.photos.search
125
+ def photos(*criteria)
126
+ criteria ? photos_search(*criteria) : recent
127
+ end
128
+
129
+ # flickr.photos.getRecent
130
+ # 100 newest photos from everyone
131
+ def recent
132
+ photos_request('photos.getRecent')
133
+ end
134
+
135
+ def photos_search(params={})
136
+ photos_request('photos.search', params)
137
+ end
138
+ alias_method :search, :photos_search
139
+
140
+ # Gets public photos with a given tag
141
+ def tag(tag)
142
+ photos('tags'=>tag)
143
+ end
144
+
145
+ # Implements flickr.people.findByEmail and flickr.people.findByUsername.
146
+ def users(lookup=nil)
147
+ user = people_findByEmail('find_email'=>lookup)['user'] rescue people_findByUsername('username'=>lookup)['user']
148
+ return User.new("id" => user["nsid"], "username" => user["username"], "client" => self)
149
+ end
150
+
151
+ # Implements flickr.groups.search
152
+ def groups(group_name, options={})
153
+ collection = groups_search({"text" => group_name}.merge(options))['groups']['group']
154
+ collection = [collection] if collection.is_a? Hash
155
+
156
+ collection.collect { |group| Group.new( "id" => group['nsid'],
157
+ "name" => group['name'],
158
+ "eighteenplus" => group['eighteenplus'],
159
+ "client" => self) }
160
+ end
161
+
162
+ # Implements flickr.tags.getRelated
163
+ def related_tags(tag)
164
+ tags_getRelated('tag'=>tag)['tags']['tag']
165
+ end
166
+
167
+ # Implements flickr.photos.licenses.getInfo
168
+ def licenses
169
+ photos_licenses_getInfo['licenses']['license']
170
+ end
171
+
172
+ # Returns url for user to login in to Flickr to authenticate app for a user
173
+ def login_url(perms)
174
+ "http://flickr.com/services/auth/?api_key=#{@api_key}&perms=#{perms}&api_sig=#{signature_from('api_key'=>@api_key, 'perms' => perms)}"
175
+ end
176
+
177
+ # Implements everything else.
178
+ # Any method not defined explicitly will be passed on to the Flickr API,
179
+ # and return an XmlSimple document. For example, Flickr#test_echo is not
180
+ # defined, so it will pass the call to the flickr.test.echo method.
181
+ def method_missing(method_id, params={})
182
+ request(method_id.id2name.gsub(/_/, '.'), params)
183
+ end
184
+
185
+ # Does an HTTP GET on a given URL and returns the response body
186
+ def http_get(url)
187
+ Net::HTTP.get_response(URI.parse(url)).body.to_s
188
+ end
189
+
190
+ # Takes a Flickr API method name and set of parameters; returns an XmlSimple object with the response
191
+ def request(method, params={})
192
+ url = request_url(method, params)
193
+ response = XmlSimple.xml_in(open(url), { 'ForceArray' => false })
194
+ raise response['err']['msg'] if response['stat'] != 'ok'
195
+ response
196
+ end
197
+
198
+ # acts like request but returns a PhotoCollection (a list of Photo objects)
199
+ def photos_request(method, params={})
200
+ photos = request(method, params)
201
+ PhotoCollection.new(photos, @api_key)
202
+ end
203
+
204
+ # Builds url for Flickr API REST request from given the flickr method name
205
+ # (exclusing the 'flickr.' that begins each method call) and params (where
206
+ # applicable) which should be supplied as a Hash (e.g 'user_id' => "foo123")
207
+ def request_url(method, params={})
208
+ method = 'flickr.' + method
209
+ url = "#{@host}#{@api}/?api_key=#{@api_key}&method=#{method}"
210
+ params.merge!('api_key' => @api_key, 'method' => method, 'auth_token' => @auth_token)
211
+ signature = signature_from(params)
212
+
213
+ url = "#{@host}#{@api}/?" + params.merge('api_sig' => signature).collect { |k,v| "#{k}=" + CGI::escape(v.to_s) unless v.nil? }.compact.join("&")
214
+ end
215
+
216
+ def signature_from(params={})
217
+ return unless @shared_secret # don't both getting signature if no shared_secret
218
+ request_str = params.reject {|k,v| v.nil?}.collect {|p| "#{p[0].to_s}#{p[1]}"}.sort.join # build key value pairs, sort in alpha order then join them, ignoring those with nil value
219
+ return Digest::MD5.hexdigest("#{@shared_secret}#{request_str}")
220
+ end
221
+
222
+ # A collection of photos is returned as a PhotoCollection, a subclass of Array.
223
+ # This allows us to retain the pagination info returned by Flickr and make it
224
+ # accessible in a friendly way
225
+ class PhotoCollection < Array
226
+ attr_reader :page, :pages, :perpage, :total
227
+
228
+ # builds a PhotoCollection from given params, such as those returned from
229
+ # photos.search API call
230
+ def initialize(photos_api_response={}, api_key=nil)
231
+ [ "page", "pages", "perpage", "total" ].each { |i| instance_variable_set("@#{i}", photos_api_response["photos"][i])}
232
+ collection = photos_api_response['photos']['photo'] || []
233
+ collection = [collection] if collection.is_a? Hash
234
+ collection.each { |photo| self << Photo.new(photo.delete('id'), api_key, photo) }
235
+ end
236
+ end
237
+
238
+ # Todo:
239
+ # logged_in?
240
+ # if logged in:
241
+ # flickr.blogs.getList
242
+ # flickr.favorites.add
243
+ # flickr.favorites.remove
244
+ # flickr.groups.browse
245
+ # flickr.photos.getCounts
246
+ # flickr.photos.getNotInSet
247
+ # flickr.photos.getUntagged
248
+ # flickr.photosets.create
249
+ # flickr.photosets.orderSets
250
+ # flickr.tags.getListUserPopular
251
+ # flickr.test.login
252
+ # uploading
253
+ class User
254
+
255
+ attr_reader :client, :id, :name, :location, :photos_url, :url, :count, :firstdate, :firstdatetaken
256
+
257
+ # A Flickr::User can be instantiated in two ways. The old (deprecated)
258
+ # method is with an ordered series of values. The new method is with a
259
+ # params Hash, which is easier when a variable number of params are
260
+ # supplied, which is the case here, and also avoids having to constantly
261
+ # supply nil values for the email and password, which are now irrelevant
262
+ # as authentication is no longer done this way.
263
+ # An associated flickr client will also be generated if an api key is
264
+ # passed among the arguments or in the params hash. Alternatively, and
265
+ # most likely, an existing client object may be passed in the params hash
266
+ # (e.g. 'client' => some_existing_flickr_client_object), and this is
267
+ # what happends when users are initlialized as the result of a method
268
+ # called on the flickr client (e.g. flickr.users)
269
+ def initialize(id_or_params_hash=nil, username=nil, email=nil, password=nil, api_key=nil)
270
+ if id_or_params_hash.is_a?(Hash)
271
+ id_or_params_hash.each { |k,v| self.instance_variable_set("@#{k}", v) } # convert extra_params into instance variables
272
+ else
273
+ @id = id_or_params_hash
274
+ @username = username
275
+ @email = email
276
+ @password = password
277
+ @api_key = api_key
278
+ end
279
+ @client ||= Flickr.new('api_key' => @api_key, 'shared_secret' => @shared_secret, 'auth_token' => @auth_token) if @api_key
280
+ @client.login(@email, @password) if @email and @password # this is now irrelevant as Flickr API no longer supports authentication this way
281
+ end
282
+
283
+ def username
284
+ @username.nil? ? getInfo.username : @username
285
+ end
286
+ def name
287
+ @name.nil? ? getInfo.name : @name
288
+ end
289
+ def location
290
+ @location.nil? ? getInfo.location : @location
291
+ end
292
+ def count
293
+ @count.nil? ? getInfo.count : @count
294
+ end
295
+ def firstdate
296
+ @firstdate.nil? ? getInfo.firstdate : @firstdate
297
+ end
298
+ def firstdatetaken
299
+ @firstdatetaken.nil? ? getInfo.firstdatetaken : @firstdatetaken
300
+ end
301
+
302
+ # Builds url for user's photos page as per
303
+ # http://www.flickr.com/services/api/misc.urls.html
304
+ def photos_url
305
+ "http://www.flickr.com/photos/#{id}/"
306
+ end
307
+
308
+ # Builds url for user's profile page as per
309
+ # http://www.flickr.com/services/api/misc.urls.html
310
+ def url
311
+ "http://www.flickr.com/people/#{id}/"
312
+ end
313
+
314
+ def pretty_url
315
+ @pretty_url ||= @client.urls_getUserProfile('user_id'=>@id)['user']['url']
316
+ end
317
+
318
+ # Implements flickr.people.getPublicGroups
319
+ def groups
320
+ collection = @client.people_getPublicGroups('user_id'=>@id)['groups']['group']
321
+ collection = [collection] if collection.is_a? Hash
322
+ collection.collect { |group| Group.new( "id" => group['nsid'],
323
+ "name" => group['name'],
324
+ "eighteenplus" => group['eighteenplus'],
325
+ "client" => @client) }
326
+ end
327
+
328
+ # Implements flickr.people.getPublicPhotos. Options hash allows you to add
329
+ # extra restrictions as per flickr.people.getPublicPhotos docs, e.g.
330
+ # user.photos('per_page' => '25', 'extras' => 'date_taken')
331
+ def photos(options={})
332
+ @client.photos_request('people.getPublicPhotos', {'user_id' => @id}.merge(options))
333
+ # what about non-public photos?
334
+ end
335
+
336
+ # Gets photos with a given tag
337
+ def tag(tag)
338
+ @client.photos('user_id'=>@id, 'tags'=>tag)
339
+ end
340
+
341
+ # Implements flickr.contacts.getPublicList and flickr.contacts.getList
342
+ def contacts
343
+ @client.contacts_getPublicList('user_id'=>@id)['contacts']['contact'].collect { |contact| User.new(contact['nsid'], contact['username'], nil, nil, @api_key) }
344
+ #or
345
+ end
346
+
347
+ # Implements flickr.favorites.getPublicList
348
+ def favorites
349
+ @client.photos_request('favorites.getPublicList', 'user_id' => @id)
350
+ end
351
+
352
+ # Implements flickr.photosets.getList
353
+ def photosets
354
+ @client.photosets_getList('user_id'=>@id)['photosets']['photoset'].collect { |photoset| Photoset.new(photoset['id'], @api_key) }
355
+ end
356
+
357
+ # Implements flickr.tags.getListUser
358
+ def tags
359
+ @client.tags_getListUser('user_id'=>@id)['who']['tags']['tag'].collect { |tag| tag }
360
+ end
361
+
362
+ # Implements flickr.photos.getContactsPublicPhotos and flickr.photos.getContactsPhotos
363
+ def contactsPhotos
364
+ @client.photos_request('photos.getContactsPublicPhotos', 'user_id' => @id)
365
+ end
366
+
367
+ def to_s
368
+ @name
369
+ end
370
+
371
+
372
+
373
+ private
374
+
375
+ # Implements flickr.people.getInfo, flickr.urls.getUserPhotos, and flickr.urls.getUserProfile
376
+ def getInfo
377
+ info = @client.people_getInfo('user_id'=>@id)['person']
378
+ @username = info['username']
379
+ @name = info['realname']
380
+ @location = info['location']
381
+ @count = info['photos']['count']
382
+ @firstdate = info['photos']['firstdate']
383
+ @firstdatetaken = info['photos']['firstdatetaken']
384
+ self
385
+ end
386
+
387
+ end
388
+
389
+ class Photo
390
+
391
+ attr_reader :id, :client, :title
392
+
393
+ def initialize(id=nil, api_key=nil, extra_params={})
394
+ @id = id
395
+ @api_key = api_key
396
+ extra_params.each { |k,v| self.instance_variable_set("@#{k}", v) } # convert extra_params into instance variables
397
+ @client = Flickr.new @api_key
398
+ end
399
+
400
+ # Allows access to all photos instance variables through hash like
401
+ # interface, e.g. photo["datetaken"] returns @datetaken instance
402
+ # variable. Useful for accessing any weird and wonderful parameter
403
+ # that may have been returned by Flickr when finding the photo,
404
+ # e.g. those returned by the extras argument in
405
+ # flickr.people.getPublicPhotos
406
+ def [](param_name)
407
+ instance_variable_get("@#{param_name}")
408
+ end
409
+
410
+ def title
411
+ @title.nil? ? getInfo("title") : @title
412
+ end
413
+
414
+ # Returns the owner of the photo as a Flickr::User. If we have no info
415
+ # about the owner, we make an API call to get it. If we already have
416
+ # the owner's id, create a user based on that. Either way, we cache the
417
+ # result so we don't need to check again
418
+ def owner
419
+ case @owner
420
+ when Flickr::User
421
+ @owner
422
+ when String
423
+ @owner = Flickr::User.new(@owner, nil, nil, nil, @api_key)
424
+ else
425
+ getInfo("owner")
426
+ end
427
+ end
428
+
429
+ def server
430
+ @server.nil? ? getInfo("server") : @server
431
+ end
432
+
433
+ def isfavorite
434
+ @isfavorite.nil? ? getInfo("isfavorite") : @isfavorite
435
+ end
436
+
437
+ def license
438
+ @license.nil? ? getInfo("license") : @license
439
+ end
440
+
441
+ def rotation
442
+ @rotation.nil? ? getInfo("rotation") : @rotation
443
+ end
444
+
445
+ def description
446
+ @description || getInfo("description")
447
+ end
448
+
449
+ def notes
450
+ @notes.nil? ? getInfo("notes") : @notes
451
+ end
452
+
453
+ # Returns the URL for the photo size page
454
+ # defaults to 'Medium'
455
+ # other valid sizes are in the VALID_SIZES hash
456
+ def size_url(size='Medium')
457
+ uri_for_photo_from_self(size) || sizes(size)['url']
458
+ end
459
+
460
+ # converts string or symbol size to a capitalized string
461
+ def normalize_size(size)
462
+ size ? size.to_s.capitalize : size
463
+ end
464
+
465
+ # the URL for the main photo page
466
+ # if getInfo has already been called, this will return the pretty url
467
+ #
468
+ # for historical reasons, an optional size can be given
469
+ # 'Medium' returns the regular url; any other size returns a size page
470
+ # use size_url instead
471
+ def url(size = nil)
472
+ if normalize_size(size) != 'Medium'
473
+ size_url(size)
474
+ else
475
+ @url || uri_for_photo_from_self
476
+ end
477
+ end
478
+
479
+ # the 'pretty' url for a photo
480
+ # (if the user has set up a custom name)
481
+ # eg, http://flickr.com/photos/granth/2584402507/ instead of
482
+ # http://flickr.com/photos/23386158@N00/2584402507/
483
+ def pretty_url
484
+ @url || getInfo("pretty_url")
485
+ end
486
+
487
+ # Returns the URL for the image (default or any specified size)
488
+ def source(size='Medium')
489
+ image_source_uri_from_self(size) || sizes(size)['source']
490
+ end
491
+
492
+ # Returns the photo file data itself, in any specified size. Example: File.open(photo.title, 'w') { |f| f.puts photo.file }
493
+ def file(size='Medium')
494
+ Net::HTTP.get_response(URI.parse(source(size))).body
495
+ end
496
+
497
+ # Unique filename for the image, based on the Flickr NSID
498
+ def filename
499
+ "#{@id}.jpg"
500
+ end
501
+
502
+ # Implements flickr.photos.getContext
503
+ def context
504
+ context = @client.photos_getContext('photo_id'=>@id)
505
+ @previousPhoto = Photo.new(context['prevphoto'].delete('id'), @api_key, context['prevphoto']) if context['prevphoto']['id']!='0'
506
+ @nextPhoto = Photo.new(context['nextphoto'].delete('id'), @api_key, context['nextphoto']) if context['nextphoto']['id']!='0'
507
+ return [@previousPhoto, @nextPhoto]
508
+ end
509
+
510
+ # Implements flickr.photos.getExif
511
+ def exif
512
+ @client.photos_getExif('photo_id'=>@id)['photo']
513
+ end
514
+
515
+ # Implements flickr.photos.getPerms
516
+ def permissions
517
+ @client.photos_getPerms('photo_id'=>@id)['perms']
518
+ end
519
+
520
+ # Implements flickr.photos.getSizes
521
+ def sizes(size=nil)
522
+ size = normalize_size(size)
523
+ sizes = @client.photos_getSizes('photo_id'=>@id)['sizes']['size']
524
+ sizes = sizes.find{|asize| asize['label']==size} if size
525
+ return sizes
526
+ end
527
+
528
+ # flickr.tags.getListPhoto
529
+ def tags
530
+ @client.tags_getListPhoto('photo_id'=>@id)['photo']['tags']
531
+ end
532
+
533
+ # Implements flickr.photos.notes.add
534
+ def add_note(note)
535
+ end
536
+
537
+ # Implements flickr.photos.setDates
538
+ def dates=(dates)
539
+ end
540
+
541
+ # Implements flickr.photos.setPerms
542
+ def perms=(perms)
543
+ end
544
+
545
+ # Implements flickr.photos.setTags
546
+ def tags=(tags)
547
+ end
548
+
549
+ # Implements flickr.photos.setMeta
550
+ def title=(title)
551
+ end
552
+ def description=(title)
553
+ end
554
+
555
+ # Implements flickr.photos.addTags
556
+ def add_tag(tag)
557
+ end
558
+
559
+ # Implements flickr.photos.removeTag
560
+ def remove_tag(tag)
561
+ end
562
+
563
+ # Implements flickr.photos.transform.rotate
564
+ def rotate
565
+ end
566
+
567
+ # Implements flickr.blogs.postPhoto
568
+ def postToBlog(blog_id, title='', description='')
569
+ @client.blogs_postPhoto('photo_id'=>@id, 'title'=>title, 'description'=>description)
570
+ end
571
+
572
+ # Implements flickr.photos.notes.delete
573
+ def deleteNote(note_id)
574
+ end
575
+
576
+ # Implements flickr.photos.notes.edit
577
+ def editNote(note_id)
578
+ end
579
+
580
+ # Converts the Photo to a string by returning its title
581
+ def to_s
582
+ title
583
+ end
584
+
585
+
586
+ # unvlog
587
+ def media
588
+ @media || getInfo("media")
589
+ end
590
+
591
+ def secret
592
+ @secret || getInfo("secret")
593
+ end
594
+
595
+
596
+ private
597
+
598
+ # Implements flickr.photos.getInfo
599
+ def getInfo(attrib="")
600
+ return instance_variable_get("@#{attrib}") if @got_info
601
+ info = @client.photos_getInfo('photo_id'=>@id)['photo']
602
+ @got_info = true
603
+ info.each { |k,v| instance_variable_set("@#{k}", v)}
604
+ @media = info['media']
605
+ @secret = info['secret']
606
+ @owner = User.new(info['owner']['nsid'], info['owner']['username'], nil, nil, @api_key)
607
+ @tags = info['tags']['tag']
608
+ @notes = info['notes']['note']#.collect { |note| Note.new(note.id) }
609
+ @url = info['urls']['url']['content'] # assumes only one url
610
+ instance_variable_get("@#{attrib}")
611
+ end
612
+
613
+ # Builds source uri of image from params (often returned from other
614
+ # methods, e.g. User#photos). As specified at:
615
+ # http://www.flickr.com/services/api/misc.urls.html. If size is given
616
+ # should be one the keys in the VALID_SIZES hash, i.e.
617
+ # "Square", "Thumbnail", "Medium", "Large", "Original", "Small" (These
618
+ # are the values returned by flickr.photos.getSizes).
619
+ # If no size is given the uri for "Medium"-size image, i.e. with width
620
+ # of 500 is returned
621
+ # TODO: Handle "Original" size
622
+ def image_source_uri_from_self(size=nil)
623
+ return unless @farm&&@server&&@id&&@secret
624
+ s_size = VALID_SIZES[normalize_size(size)] # get the short letters array corresponding to the size
625
+ s_size = s_size&&s_size[0] # the first element of this array is used to build the source uri
626
+ if s_size.nil?
627
+ "http://farm#{@farm}.static.flickr.com/#{@server}/#{@id}_#{@secret}.jpg"
628
+ else
629
+ "http://farm#{@farm}.static.flickr.com/#{@server}/#{@id}_#{@secret}_#{s_size}.jpg"
630
+ end
631
+ end
632
+
633
+ # Builds uri of Flickr page for photo. By default returns the main
634
+ # page for the photo, but if passed a size will return the simplified
635
+ # flickr page featuring the given size of the photo
636
+ # TODO: Handle "Original" size
637
+ def uri_for_photo_from_self(size=nil)
638
+ return unless @owner&&@id
639
+ size = normalize_size(size)
640
+ s_size = VALID_SIZES[size] # get the short letters array corresponding to the size
641
+ s_size = s_size&&s_size[1] # the second element of this array is used to build the uri of the flickr page for this size
642
+ "http://www.flickr.com/photos/#{owner.id}/#{@id}" + (s_size ? "/sizes/#{s_size}/" : "")
643
+ end
644
+ end
645
+
646
+ # Todo:
647
+ # flickr.groups.pools.add
648
+ # flickr.groups.pools.getContext
649
+ # flickr.groups.pools.getGroups
650
+ # flickr.groups.pools.getPhotos
651
+ # flickr.groups.pools.remove
652
+ class Group
653
+ attr_reader :id, :client, :description, :name, :eighteenplus, :members, :online, :privacy, :url#, :chatid, :chatcount
654
+
655
+ def initialize(id_or_params_hash=nil, api_key=nil)
656
+ if id_or_params_hash.is_a?(Hash)
657
+ id_or_params_hash.each { |k,v| self.instance_variable_set("@#{k}", v) } # convert extra_params into instance variables
658
+ else
659
+ @id = id_or_params_hash
660
+ @api_key = api_key
661
+ @client = Flickr.new @api_key
662
+ end
663
+ end
664
+
665
+ # Implements flickr.groups.getInfo and flickr.urls.getGroup
666
+ # private, once we can call it as needed
667
+ def getInfo
668
+ info = @client.groups_getInfo('group_id'=>@id)['group']
669
+ @name = info['name']
670
+ @members = info['members']
671
+ @online = info['online']
672
+ @privacy = info['privacy']
673
+ # @chatid = info['chatid']
674
+ # @chatcount = info['chatcount']
675
+ @url = @client.urls_getGroup('group_id'=>@id)['group']['url']
676
+ self
677
+ end
678
+
679
+ end
680
+
681
+ # Todo:
682
+ # flickr.photosets.delete
683
+ # flickr.photosets.editMeta
684
+ # flickr.photosets.editPhotos
685
+ # flickr.photosets.getContext
686
+ # flickr.photosets.getInfo
687
+ # flickr.photosets.getPhotos
688
+ class Photoset
689
+
690
+ attr_reader :id, :client, :owner, :primary, :photos, :title, :description, :url
691
+
692
+ def initialize(id=nil, api_key=nil)
693
+ @id = id
694
+ @api_key = api_key
695
+ @client = Flickr.new @api_key
696
+ end
697
+
698
+ # Implements flickr.photosets.getInfo
699
+ # private, once we can call it as needed
700
+ def getInfo
701
+ info = @client.photosets_getInfo('photoset_id'=>@id)['photoset']
702
+ @owner = User.new(info['owner'], nil, nil, nil, @api_key)
703
+ @primary = info['primary']
704
+ @photos = info['photos']
705
+ @title = info['title']
706
+ @description = info['description']
707
+ @url = "http://www.flickr.com/photos/#{@owner.getInfo.username}/sets/#{@id}/"
708
+ self
709
+ end
710
+
711
+ end
712
+
713
+ end