flickr-objects 0.0.1

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.
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