flickr-objects 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.md +167 -0
  2. data/lib/flickr/api/flickr.rb +40 -0
  3. data/lib/flickr/api/media.rb +63 -0
  4. data/lib/flickr/api/person.rb +70 -0
  5. data/lib/flickr/api/photo.rb +11 -0
  6. data/lib/flickr/api/set.rb +70 -0
  7. data/lib/flickr/api/video.rb +11 -0
  8. data/lib/flickr/api.rb +50 -0
  9. data/lib/flickr/api_caller.rb +95 -0
  10. data/lib/flickr/client/methods_client.rb +22 -0
  11. data/lib/flickr/client/middleware/retry.rb +38 -0
  12. data/lib/flickr/client/middleware.rb +42 -0
  13. data/lib/flickr/client/upload_client.rb +75 -0
  14. data/lib/flickr/client.rb +57 -0
  15. data/lib/flickr/configuration.rb +23 -0
  16. data/lib/flickr/helpers/base_58.rb +15 -0
  17. data/lib/flickr/helpers/boolean.rb +4 -0
  18. data/lib/flickr/helpers/core_ext.rb +5 -0
  19. data/lib/flickr/helpers/inheritable_attr_accessor.rb +18 -0
  20. data/lib/flickr/object/attribute/converter.rb +49 -0
  21. data/lib/flickr/object/attribute/finder.rb +32 -0
  22. data/lib/flickr/object/attribute.rb +45 -0
  23. data/lib/flickr/object.rb +39 -0
  24. data/lib/flickr/objects/attribute_values/collection.rb +10 -0
  25. data/lib/flickr/objects/attribute_values/location.rb +14 -0
  26. data/lib/flickr/objects/attribute_values/media.rb +70 -0
  27. data/lib/flickr/objects/attribute_values/note.rb +11 -0
  28. data/lib/flickr/objects/attribute_values/permissions.rb +12 -0
  29. data/lib/flickr/objects/attribute_values/person.rb +23 -0
  30. data/lib/flickr/objects/attribute_values/photo.rb +19 -0
  31. data/lib/flickr/objects/attribute_values/set.rb +21 -0
  32. data/lib/flickr/objects/attribute_values/tag.rb +9 -0
  33. data/lib/flickr/objects/attribute_values/upload_ticket.rb +11 -0
  34. data/lib/flickr/objects/attribute_values/video.rb +27 -0
  35. data/lib/flickr/objects/attribute_values/visibility.rb +10 -0
  36. data/lib/flickr/objects/collection.rb +58 -0
  37. data/lib/flickr/objects/location.rb +26 -0
  38. data/lib/flickr/objects/media.rb +74 -0
  39. data/lib/flickr/objects/note.rb +14 -0
  40. data/lib/flickr/objects/permissions.rb +14 -0
  41. data/lib/flickr/objects/person.rb +42 -0
  42. data/lib/flickr/objects/photo.rb +48 -0
  43. data/lib/flickr/objects/set.rb +33 -0
  44. data/lib/flickr/objects/tag.rb +17 -0
  45. data/lib/flickr/objects/upload_ticket.rb +18 -0
  46. data/lib/flickr/objects/video.rb +24 -0
  47. data/lib/flickr/objects/visibility.rb +12 -0
  48. data/lib/flickr/objects.rb +28 -0
  49. data/lib/flickr/version.rb +3 -0
  50. data/lib/flickr-objects.rb +2 -0
  51. data/lib/flickr.rb +21 -0
  52. metadata +212 -0
data/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # Flickr Objects
2
+
3
+ This gem is an object-oriented wrapper for the [Flickr API](http://flickr.com/api).
4
+ To see its capability, take a look at this nice demonstration:
5
+
6
+ [http://janko-m.github.com/flickr-objects/](http://janko-m.github.com/flickr-objects/)
7
+
8
+ ## Installation and setup
9
+
10
+ Add it to your `Gemfile`, and run `bundle install`.
11
+
12
+ ```ruby
13
+ gem "flickr-objects"
14
+ ```
15
+
16
+ Now create an initializer where you set your Flickr credentials.
17
+
18
+ ```ruby
19
+ Flickr.configure do |config|
20
+ config.api_key = "API_KEY"
21
+ config.shared_secret = "SHARED_SECRET"
22
+ end
23
+ ```
24
+
25
+ If you don't have your API key and shared secret yet, you can apply for them
26
+ [here](http://www.flickr.com/services/apps/create/apply).
27
+
28
+ ## Usage
29
+
30
+ Let's start with a general example.
31
+
32
+ ```ruby
33
+ person_id = "78733179@N04"
34
+ person = Flickr.people.find(preson_id)
35
+ photos = person.get_public_photos #=> API request
36
+
37
+ photo = photos.first
38
+ photo.id #=> "231233252"
39
+ photo.title #=> "My cat"
40
+ photo.visibility.public? #=> true
41
+ photo.description #=> nil
42
+ photo.get_info! # makes an API request
43
+ photo.description #=> "He's trying to catch a fly"
44
+ ```
45
+
46
+ So, we've seen 2 API requests here:
47
+
48
+ - `person.get_public_photos` (`Flickr::Person#get_public_photos`)
49
+ - `photo.get_info!` (`Flickr::Photo#get_info!`)
50
+
51
+ They correspond to the API methods listed on Flickr's official [API page](http://flickr.com/api).
52
+ `Flickr::Person#get_public_photos` corresponds to `flickr.people.getPublicPhotos`, and
53
+ `Flickr::Photo#get_info!` corresponds to `flickr.photos.getInfo`.
54
+
55
+ Let's say you want to call Flickr's `flickr.photosets.getList`. To find out how to call it,
56
+ you can use `Flickr.api_methods` in the console. This method acts like a
57
+ documentation for API methods. So, for example:
58
+
59
+ ```ruby
60
+ Flickr.api_methods["flickr.photosets.getList"] #=> ["Flickr::Person#get_sets"]
61
+ ```
62
+
63
+ Now you found out that it corresponds to `Flickr::Person#get_sets`, which means
64
+ you can call it like this:
65
+
66
+ ```ruby
67
+ sets = Flickr.people.find(person_id).get_sets
68
+ sets.first.id #=> "12312324"
69
+ ```
70
+
71
+ ## Sizes
72
+
73
+ ```ruby
74
+ person = Flickr.person.find(person_id)
75
+ photo = person.get_public_photos(sizes: :all).first
76
+
77
+ photo.small!(320)
78
+ photo.source_url #=> "http://farm9.staticflickr.com/8191/8130464513_780e01decd_n.jpg"
79
+ photo.width #=> 320
80
+ photo.height #=> 280
81
+
82
+ photo.medium!(500)
83
+ photo.width #=> 500
84
+ ```
85
+
86
+ ## Authenticated requests
87
+
88
+ If you need to make authenticated API requests (which you'll often want), you can create a kind
89
+ of a instance, assigning to it user's access token. That instance then has the same interface as `Flickr`.
90
+
91
+ ```ruby
92
+ flickr = Flickr.new("ACCESS_TOKEN_KEY", "ACCESS_TOKEN_SECRET")
93
+
94
+ flickr.test_login #=> {"id" => "78733179@N04", "username" => ...}
95
+ flickr.people.find(person_id).get_public_photos
96
+ # ...
97
+ ```
98
+
99
+ If you're in a Rails application, probably the best solution for authenticating
100
+ users through Flickr (thus obtaining their access tokens) is the
101
+ [omniauth-flickr](https://github.com/timbreitkreutz/omniauth-flickr) gem.
102
+ Another (more lightweight) solution would be [flickr-login](https://github.com/janko-m/flickr-login).
103
+
104
+ You can also assign the access token globally in your configuration.
105
+
106
+ ```ruby
107
+ Flickr.configure do |config|
108
+ config.api_key = "API_KEY"
109
+ config.shared_secret = "SHARED_SECRET"
110
+ config.access_token_key = "ACCESS_TOKEN_KEY"
111
+ config.access_token_secret = "ACCESS_TOKEN_SECRET"
112
+ end
113
+ ```
114
+
115
+ This is useful if you're, for example, using Flickr as a photo storage in your
116
+ application, and that access token is actually yours.
117
+
118
+
119
+ ## Upload
120
+
121
+ ```ruby
122
+ photo_id = Flickr.upload("/path/to/photo.jpg", title: "Dandelions")
123
+ photo = Flickr.photos.find(photo_id).get_info!
124
+ photo.title #=> "Dandelions"
125
+ ```
126
+
127
+ You can also upload asynchronously, which will return the upload ticket, which
128
+ you can then use to check when the upload has finished.
129
+
130
+ ```ruby
131
+ ticket_id = Flickr.upload("/path/to/photo.jpg", title: "Dandelions", ansync: true)
132
+ ticket = Flickr.check_upload_tickets(ticket_id).first
133
+ ticket.complete? #=> false
134
+
135
+ sleep 1
136
+
137
+ ticket = Flickr.check_upload_tickets(ticked_id).first
138
+ ticket.complete? #=> true
139
+ ticket.photo.id #=> "232594385"
140
+ ```
141
+
142
+ ## Attributes
143
+
144
+ For the list of attributes that Flickr objects have, the best place to look at
145
+ is the source code. For example, list of common attributes that `Flickr::Photo`
146
+ and `Flickr::Video` have can be found in `lib/flickr/objects/media.rb`.
147
+
148
+ ![Flickr::Media](http://farm9.staticflickr.com/8195/8133340670_38c60aaca7.jpg)
149
+
150
+ As you can see, it is very readable ;)
151
+
152
+ ## Few words
153
+
154
+ Most of the API methods are not covered yet (because they are so many for one
155
+ person). All the most important API methods should be implemented, so a person
156
+ with normal demands should have everything he needs. If you feel like some API
157
+ methods should have higher priority to be covered, feel free to post it in
158
+ issues, and I will try to get it covered in the next version. Pull requests are
159
+ also very welcome :)
160
+
161
+ ## Social
162
+
163
+ You can follow me on Twitter, I'm [@m_janko](https://twitter.com/m_janko).
164
+
165
+ ## License
166
+
167
+ This project is released under the [MIT license](https://github.com/janko-m/flickr-objects/blob/master/LICENSE).
@@ -0,0 +1,40 @@
1
+ class Flickr
2
+ api_methods = proc do
3
+ def upload(media, params = {})
4
+ response = upload_client.upload(media, params)
5
+ params[:async] == 1 ? response["ticketid"] : response["photoid"]
6
+ end
7
+
8
+ def replace(media, id, params = {})
9
+ response = upload_client.replace(media, id, params)
10
+ params[:async] == 1 ? response["ticketid"] : response["photoid"]
11
+ end
12
+
13
+ def check_upload_tickets(tickets, params = {})
14
+ response = client.get flickr_method(__method__), params.merge(tickets: tickets.to_s)
15
+ Collection.new(response["uploader"].delete("ticket"), UploadTicket, response["uploader"], client)
16
+ end
17
+ api_method :check_upload_tickets, "flickr.photos.upload.checkTickets"
18
+
19
+ def test_login(params = {})
20
+ client.get flickr_method(__method__), params
21
+ end
22
+ api_method :test_login, "flickr.test.login"
23
+
24
+ def test_echo(params = {})
25
+ client.get flickr_method(__method__), params
26
+ end
27
+ api_method :test_echo, "flickr.test.echo"
28
+
29
+ def test_null(params = {})
30
+ client.get flickr_method(__method__), params
31
+ end
32
+ api_method :test_null, "flickr.test.null"
33
+ end
34
+
35
+ def self.api_method(*args) class_api_method(*args) end
36
+ instance_eval(&api_methods)
37
+
38
+ def self.api_method(*args) instance_api_method(*args) end
39
+ class_eval(&api_methods)
40
+ end
@@ -0,0 +1,63 @@
1
+ class Flickr
2
+ class Media < Object
3
+ def add_tags(tags, params = {})
4
+ client.post flickr_method(__method__), params.merge(photo_id: id, tags: tags)
5
+ tags
6
+ end
7
+ instance_api_method :add_tags, "flickr.photos.addTags"
8
+
9
+ def delete(params = {})
10
+ client.post flickr_method(__method__), params.merge(photo_id: id)
11
+ self
12
+ end
13
+ instance_api_method :delete, "flickr.photos.delete"
14
+
15
+ def self.get_from_contacts(params = {})
16
+ response = client.get flickr_method(__method__), handle_extras(params)
17
+ Collection.new(response["photos"].delete("photo"), Media, response["photos"], client)
18
+ end
19
+ class_api_method :get_from_contacts, "flickr.photos.getContactsPhotos"
20
+
21
+ def get_info!(params = {})
22
+ response = client.get flickr_method(__method__), params.merge(photo_id: id)
23
+ @hash.update(response["photo"])
24
+ self
25
+ end
26
+ instance_api_method :get_info!, "flickr.photos.getInfo"
27
+
28
+ def get_sizes!(params = {})
29
+ response = client.get flickr_method(__method__), params.merge(photo_id: id)
30
+ @hash.update(response["sizes"])
31
+ self
32
+ end
33
+ instance_api_method :get_sizes!, "flickr.photos.getSizes"
34
+
35
+ def remove_tag(tag_id, params = {})
36
+ client.post flickr_method(__method__), params.merge(photo_id: id, tag_id: tag_id)
37
+ tag_id
38
+ end
39
+ instance_api_method :remove_tag, "flickr.photos.removeTag"
40
+
41
+ def self.search(params = {})
42
+ response = client.get flickr_method(__method__), handle_extras(params)
43
+ Collection.new(response["photos"].delete("photo"), self, response["photos"], client)
44
+ end
45
+ class_api_method :search, "flickr.photos.search"
46
+
47
+ def set_content_type(content_type, params = {})
48
+ client.post flickr_method(__method__), params.merge(photo_id: id, content_type: content_type)
49
+ content_type
50
+ end
51
+ instance_api_method :set_content_type, "flickr.photos.setContentType"
52
+ alias content_type= set_content_type
53
+ instance_api_method :content_type=, "flickr.photos.setContentType"
54
+
55
+ def set_tags(tags, params = {})
56
+ client.post flickr_method(__method__), params.merge(photo_id: id, tags: tags)
57
+ tags
58
+ end
59
+ instance_api_method :set_tags, "flickr.photos.setTags"
60
+ alias tags= set_tags
61
+ instance_api_method :tags=, "flickr.photos.setTags"
62
+ end
63
+ end
@@ -0,0 +1,70 @@
1
+ class Flickr
2
+ class Person < Object
3
+ def self.find_by_email(email, params = {})
4
+ response = client.get flickr_method(__method__), params.merge(find_email: email)
5
+ new(response["user"], client)
6
+ end
7
+ class_api_method :find_by_email, "flickr.people.findByEmail"
8
+
9
+ def self.find_by_username(username, params = {})
10
+ response = client.get flickr_method(__method__), params.merge(username: username)
11
+ new(response["user"], client)
12
+ end
13
+ class_api_method :find_by_username, "flickr.people.findByUsername"
14
+
15
+ def get_info!(params = {})
16
+ response = client.get flickr_method(__method__), params.merge(user_id: id)
17
+ @hash.update(response["person"])
18
+ self
19
+ end
20
+ instance_api_method :get_info!, "flickr.people.getInfo"
21
+
22
+ def get_photos(params = {})
23
+ get_media(params).select { |object| object.is_a?(Flickr::Photo) }
24
+ end
25
+ instance_api_method :get_photos, "flickr.people.getPhotos"
26
+ def get_videos(params = {})
27
+ get_media(params).select { |object| object.is_a?(Flickr::Video) }
28
+ end
29
+ instance_api_method :get_videos, "flickr.people.getPhotos"
30
+ def get_media(params = {})
31
+ response = client.get flickr_method(__method__), handle_extras(params.merge(user_id: id))
32
+ Collection.new(response["photos"].delete("photo"), Media, response["photos"], client)
33
+ end
34
+ instance_api_method :get_media, "flickr.people.getPhotos"
35
+
36
+ def get_public_photos(params = {})
37
+ get_public_media(params).select { |object| object.is_a?(Flickr::Photo) }
38
+ end
39
+ instance_api_method :get_public_photos, "flickr.people.getPublicPhotos"
40
+ def get_public_videos(params = {})
41
+ get_public_media(params).select { |object| object.is_a?(Flickr::Video) }
42
+ end
43
+ instance_api_method :get_public_videos, "flickr.people.getPublicPhotos"
44
+ def get_public_media(params = {})
45
+ response = client.get flickr_method(__method__), handle_extras(params.merge(user_id: id))
46
+ Collection.new(response["photos"].delete("photo"), Media, response["photos"], client)
47
+ end
48
+ instance_api_method :get_public_media, "flickr.people.getPublicPhotos"
49
+
50
+ def get_public_photos_from_contacts(params = {})
51
+ get_public_media_from_contacts(params).select {|object| object.is_a?(Flickr::Photo) }
52
+ end
53
+ instance_api_method :get_public_photos_from_contacts, "flickr.photos.getContactsPublicPhotos"
54
+ def get_public_videos_from_contacts(params = {})
55
+ get_public_media_from_contacts(params).select {|object| object.is_a?(Flickr::Video) }
56
+ end
57
+ instance_api_method :get_public_videos_from_contacts, "flickr.photos.getContactsPublicPhotos"
58
+ def get_public_media_from_contacts(params = {})
59
+ response = client.get flickr_method(__method__), handle_extras(params.merge(user_id: id))
60
+ Collection.new(response["photos"].delete("photo"), Media, response["photos"], client)
61
+ end
62
+ instance_api_method :get_public_media_from_contacts, "flickr.photos.getContactsPublicPhotos"
63
+
64
+ def get_sets(params = {})
65
+ response = client.get flickr_method(__method__), params.merge(user_id: id)
66
+ Collection.new(response["photosets"].delete("photoset"), Set, response["photosets"], client)
67
+ end
68
+ instance_api_method :get_sets, "flickr.photosets.getList"
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ class Flickr
2
+ class Photo < Media
3
+ def self.get_from_contacts(params = {})
4
+ super(params).select { |media| media.is_a?(self) }
5
+ end
6
+
7
+ def self.search(params = {})
8
+ super(params.merge(media: "photos"))
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ class Flickr
2
+ class Set < Object
3
+ def add_photo(media_id, params = {})
4
+ client.post flickr_method(__method__), params.merge(photoset_id: id, photo_id: media_id)
5
+ end
6
+ instance_api_method :add_photo, "flickr.photosets.addPhoto"
7
+ alias add_video add_photo
8
+ instance_api_method :add_video, "flickr.photosets.addPhoto"
9
+ alias add_media add_photo
10
+ instance_api_method :add_media, "flickr.photosets.addPhoto"
11
+
12
+ def self.create(params = {})
13
+ response = client.post flickr_method(__method__), params
14
+ new(response["photoset"], client)
15
+ end
16
+ class_api_method :create, "flickr.photosets.create"
17
+
18
+ def delete(params = {})
19
+ client.post flickr_method(__method__), params.merge(photoset_id: id)
20
+ self
21
+ end
22
+ instance_api_method :delete, "flickr.photosets.delete"
23
+
24
+ def edit_photos(params = {})
25
+ client.post flickr_method(__method__), params.merge(photoset_id: id)
26
+ self
27
+ end
28
+ instance_api_method :edit_photos, "flickr.photosets.editPhotos"
29
+ alias edit_videos edit_photos
30
+ instance_api_method :edit_videos, "flickr.photosets.editPhotos"
31
+ alias edit_media edit_photos
32
+ instance_api_method :edit_media, "flickr.photosets.editPhotos"
33
+
34
+ def get_info!(params = {})
35
+ response = client.get flickr_method(__method__), params.merge(photoset_id: id)
36
+ @hash.update(response["photoset"])
37
+ self
38
+ end
39
+ instance_api_method :get_info!, "flickr.photosets.getInfo"
40
+
41
+ def get_photos(params = {})
42
+ get_media(params.merge(media: "photos"))
43
+ end
44
+ instance_api_method :get_photos, "flickr.photosets.getPhotos"
45
+ def get_videos(params = {})
46
+ get_media(params.merge(media: "videos"))
47
+ end
48
+ instance_api_method :get_videos, "flickr.photosets.getPhotos"
49
+ def get_media(params = {})
50
+ response = client.get flickr_method(__method__), handle_extras(params.merge(photoset_id: id))
51
+ Collection.new(response["photoset"].delete("photo"), Media, response["photoset"], client)
52
+ end
53
+ instance_api_method :get_media, "flickr.photosets.getPhotos"
54
+
55
+ def remove_photos(media_id, params = {})
56
+ client.post flickr_method(__method__), params.merge(photoset_id: id, photo_ids: media_id)
57
+ end
58
+ instance_api_method :remove_photos, "flickr.photosets.removePhotos"
59
+ alias remove_videos remove_photos
60
+ instance_api_method :remove_videos, "flickr.photosets.removePhotos"
61
+ alias remove_media remove_photos
62
+ instance_api_method :remove_media, "flickr.photosets.removePhotos"
63
+
64
+ instance_api_method :remove_media, "flickr.photosets.removePhoto"
65
+ alias remove_photo remove_photos
66
+ instance_api_method :remove_photo, "flickr.photosets.removePhoto"
67
+ alias remove_video remove_photos
68
+ instance_api_method :remove_video, "flickr.photosets.removePhoto"
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ class Flickr
2
+ class Video < Media
3
+ def self.get_from_contacts(params = {})
4
+ super(params).select { |media| media.is_a?(self) }
5
+ end
6
+
7
+ def self.search(params = {})
8
+ super(params.merge(media: "videos"))
9
+ end
10
+ end
11
+ end
data/lib/flickr/api.rb ADDED
@@ -0,0 +1,50 @@
1
+ require "flickr/client"
2
+ require "flickr/api_caller"
3
+
4
+ class Flickr
5
+ include ApiCaller
6
+
7
+ def initialize(*access_token)
8
+ @access_token = access_token
9
+ end
10
+
11
+ def client
12
+ @client ||= MethodsClient.new(@access_token)
13
+ end
14
+
15
+ def upload_client
16
+ @upload_client ||= UploadClient.new(@access_token)
17
+ end
18
+
19
+ def self.client
20
+ @client ||= MethodsClient.new(configuration.access_token)
21
+ end
22
+
23
+ def self.upload_client
24
+ @upload_client ||= UploadClient.new(configuration.access_token)
25
+ end
26
+ end
27
+
28
+ require "flickr/api/flickr"
29
+
30
+ class Flickr
31
+ def self.map_interface(method, klass)
32
+ define_method(method) do
33
+ klass.tap do |klass|
34
+ klass.instance_variable_set("@client", client)
35
+ end
36
+ end
37
+
38
+ define_singleton_method(method) do
39
+ klass.tap do |klass|
40
+ klass.instance_variable_set("@client", client)
41
+ end
42
+ end
43
+ end
44
+
45
+ map_interface :media, Media
46
+ map_interface :photos, Photo
47
+ map_interface :videos, Video
48
+ map_interface :people, Person
49
+ map_interface :sets, Set
50
+ end
@@ -0,0 +1,95 @@
1
+ class Flickr
2
+ module ApiCaller
3
+
4
+ def self.included(base)
5
+ base.send(:include, ClientMethods) unless base == Flickr
6
+ base.send(:include, ApiMethods)
7
+ base.send(:include, ParamsFixingMethods)
8
+ end
9
+
10
+ module ClientMethods
11
+ def self.included(base)
12
+ base.send(:include, Methods)
13
+ base.send(:extend, Methods)
14
+ end
15
+
16
+ module Methods
17
+ attr_reader :client
18
+ end
19
+ end
20
+
21
+ module ApiMethods
22
+ def self.included(base)
23
+ base.send(:include, InstanceMethods)
24
+ base.send(:extend, ClassMethods)
25
+ end
26
+
27
+ module ClassMethods
28
+ def instance_api_method(method, flickr_method)
29
+ Flickr.api_methods[flickr_method] << "#{self.name}##{method}"
30
+ children.each { |child| Flickr.api_methods[flickr_method] << "#{child.name}##{method}" } if respond_to?(:children)
31
+ end
32
+
33
+ def class_api_method(method, flickr_method)
34
+ Flickr.api_methods[flickr_method] << "#{self.name}.#{method}"
35
+ children.each { |child| Flickr.api_methods[flickr_method] << "#{child.name}.#{method}" } if respond_to?(:children)
36
+ end
37
+
38
+ def flickr_method(method_name)
39
+ resolve_flickr_method("#{self.name}.#{method_name}")
40
+ end
41
+
42
+ def resolve_flickr_method(full_method_name)
43
+ pair = Flickr.api_methods.find { |key, value| value.include?(full_method_name) }
44
+ pair.first
45
+
46
+ rescue NoMethodError
47
+ raise "method #{full_method_name} is not registered"
48
+ end
49
+ end
50
+
51
+ module InstanceMethods
52
+ def flickr_method(method_name)
53
+ self.class.resolve_flickr_method("#{self.class.name}##{method_name}")
54
+ end
55
+ end
56
+ end
57
+
58
+ module ParamsFixingMethods
59
+ def self.included(base)
60
+ base.send(:include, Methods)
61
+ base.send(:extend, Methods)
62
+ end
63
+
64
+ module Methods
65
+ def handle_extras(params)
66
+ include_sizes(include_media(params))
67
+ end
68
+
69
+ def include_media(params)
70
+ include_in_extras(params, "media")
71
+ end
72
+
73
+ def include_sizes(params)
74
+ return params if params[:sizes].nil?
75
+
76
+ abbrs = case params[:sizes]
77
+ when :all
78
+ Media::SIZES.values
79
+ else
80
+ params[:sizes].map { |size| Media::SIZES[size] }
81
+ end
82
+ urls = abbrs.map { |abbr| "url_#{abbr}" }.join(",")
83
+ include_in_extras(params, urls)
84
+ end
85
+
86
+ def include_in_extras(params, things)
87
+ params.dup.tap do |params|
88
+ params[:extras] = [params[:extras], things].compact.join(",")
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,22 @@
1
+ class Flickr
2
+ class MethodsClient < Client
3
+ def initialize(access_token)
4
+ super(access_token)
5
+ end
6
+
7
+ [:get, :post].each do |http_method|
8
+ define_method(http_method) do |flickr_method, params = {}|
9
+ response = super("rest") do |req|
10
+ req.params[:method] = flickr_method
11
+ req.params.update(params)
12
+ end
13
+
14
+ response.body
15
+ end
16
+ end
17
+
18
+ def parser
19
+ FaradayMiddleware::ParseJson
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ class Flickr
2
+ class Client < Faraday::Connection
3
+ module Middleware
4
+ # A copy-paste from Faraday's master branch
5
+ class Retry < Faraday::Middleware
6
+ # Public: Initialize middleware
7
+ #
8
+ # Options:
9
+ # max - Maximum number of retries (default: 2).
10
+ # interval - Pause in seconds between retries (default: 0).
11
+ # exceptions - The list of exceptions to handle. Exceptions can be
12
+ # given as Class, Module, or String. (default:
13
+ # [Errno::ETIMEDOUT, Timeout::Error, Error::TimeoutError])
14
+ def initialize(app, options = {})
15
+ super(app)
16
+ @retries, options = options, {} if options.is_a? Integer
17
+ @retries ||= options.fetch(:max, 2).to_i
18
+ @sleep = options.fetch(:interval, 0).to_f
19
+ @errmatch = options.fetch(:exceptions) { [Errno::ETIMEDOUT, 'Timeout::Error', Faraday::Error::TimeoutError] }
20
+ end
21
+
22
+ def call(env)
23
+ retries = @retries
24
+ begin
25
+ @app.call(env)
26
+ rescue *@errmatch
27
+ if retries > 0
28
+ retries -= 1
29
+ sleep @sleep if @sleep > 0
30
+ retry
31
+ end
32
+ raise
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ require "cgi"
2
+ require "flickr/client/middleware/retry"
3
+
4
+ class Flickr
5
+ class Client < Faraday::Connection
6
+ module Middleware
7
+ class CheckOAuth < Faraday::Response::Middleware
8
+ def on_complete(env)
9
+ if env[:status] != 200
10
+ message = CGI.parse(env[:body])["oauth_problem"].first
11
+ pretty_message = message.gsub('_', ' ').capitalize
12
+ raise OAuthError, pretty_message
13
+ end
14
+ end
15
+ end
16
+
17
+ class CheckStatus < Faraday::Response::Middleware
18
+ def on_complete(env)
19
+ env[:body] = env[:body]["rsp"] || env[:body]
20
+
21
+ if env[:body]["stat"] != "ok"
22
+ message = env[:body]["message"] || env[:body]["err"]["msg"]
23
+ code = env[:body]["code"] || env[:body]["err"]["code"]
24
+ raise Error.new(message, code)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ class OAuthError < ArgumentError
31
+ end
32
+
33
+ class Error < StandardError
34
+ attr_reader :code
35
+
36
+ def initialize(message, code = nil)
37
+ super(message)
38
+ @code = code.to_i
39
+ end
40
+ end
41
+ end
42
+ end