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.
- data/README.md +167 -0
- data/lib/flickr/api/flickr.rb +40 -0
- data/lib/flickr/api/media.rb +63 -0
- data/lib/flickr/api/person.rb +70 -0
- data/lib/flickr/api/photo.rb +11 -0
- data/lib/flickr/api/set.rb +70 -0
- data/lib/flickr/api/video.rb +11 -0
- data/lib/flickr/api.rb +50 -0
- data/lib/flickr/api_caller.rb +95 -0
- data/lib/flickr/client/methods_client.rb +22 -0
- data/lib/flickr/client/middleware/retry.rb +38 -0
- data/lib/flickr/client/middleware.rb +42 -0
- data/lib/flickr/client/upload_client.rb +75 -0
- data/lib/flickr/client.rb +57 -0
- data/lib/flickr/configuration.rb +23 -0
- data/lib/flickr/helpers/base_58.rb +15 -0
- data/lib/flickr/helpers/boolean.rb +4 -0
- data/lib/flickr/helpers/core_ext.rb +5 -0
- data/lib/flickr/helpers/inheritable_attr_accessor.rb +18 -0
- data/lib/flickr/object/attribute/converter.rb +49 -0
- data/lib/flickr/object/attribute/finder.rb +32 -0
- data/lib/flickr/object/attribute.rb +45 -0
- data/lib/flickr/object.rb +39 -0
- data/lib/flickr/objects/attribute_values/collection.rb +10 -0
- data/lib/flickr/objects/attribute_values/location.rb +14 -0
- data/lib/flickr/objects/attribute_values/media.rb +70 -0
- data/lib/flickr/objects/attribute_values/note.rb +11 -0
- data/lib/flickr/objects/attribute_values/permissions.rb +12 -0
- data/lib/flickr/objects/attribute_values/person.rb +23 -0
- data/lib/flickr/objects/attribute_values/photo.rb +19 -0
- data/lib/flickr/objects/attribute_values/set.rb +21 -0
- data/lib/flickr/objects/attribute_values/tag.rb +9 -0
- data/lib/flickr/objects/attribute_values/upload_ticket.rb +11 -0
- data/lib/flickr/objects/attribute_values/video.rb +27 -0
- data/lib/flickr/objects/attribute_values/visibility.rb +10 -0
- data/lib/flickr/objects/collection.rb +58 -0
- data/lib/flickr/objects/location.rb +26 -0
- data/lib/flickr/objects/media.rb +74 -0
- data/lib/flickr/objects/note.rb +14 -0
- data/lib/flickr/objects/permissions.rb +14 -0
- data/lib/flickr/objects/person.rb +42 -0
- data/lib/flickr/objects/photo.rb +48 -0
- data/lib/flickr/objects/set.rb +33 -0
- data/lib/flickr/objects/tag.rb +17 -0
- data/lib/flickr/objects/upload_ticket.rb +18 -0
- data/lib/flickr/objects/video.rb +24 -0
- data/lib/flickr/objects/visibility.rb +12 -0
- data/lib/flickr/objects.rb +28 -0
- data/lib/flickr/version.rb +3 -0
- data/lib/flickr-objects.rb +2 -0
- data/lib/flickr.rb +21 -0
- 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
|
+

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