flickrie 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/lib/flickrie.rb +18 -92
- data/lib/flickrie/api_methods.rb +759 -11
- data/lib/flickrie/base58.rb +15 -0
- data/lib/flickrie/callable.rb +78 -0
- data/lib/flickrie/client.rb +25 -17
- data/lib/flickrie/instance.rb +10 -15
- data/lib/flickrie/middleware.rb +4 -21
- data/lib/flickrie/middleware/fix_flickr_data.rb +215 -0
- data/lib/flickrie/middleware/retry.rb +23 -0
- data/lib/flickrie/{license.rb → objects/license.rb} +0 -0
- data/lib/flickrie/{location.rb → objects/location.rb} +13 -13
- data/lib/flickrie/{media.rb → objects/media.rb} +30 -25
- data/lib/flickrie/{media → objects/media}/exif.rb +0 -0
- data/lib/flickrie/{media → objects/media}/note.rb +11 -12
- data/lib/flickrie/{media → objects/media}/tag.rb +10 -9
- data/lib/flickrie/objects/media/visibility.rb +28 -0
- data/lib/flickrie/objects/media_context.rb +17 -0
- data/lib/flickrie/objects/media_count.rb +46 -0
- data/lib/flickrie/{photo.rb → objects/photo.rb} +2 -3
- data/lib/flickrie/{set.rb → objects/set.rb} +9 -30
- data/lib/flickrie/{ticket.rb → objects/ticket.rb} +0 -0
- data/lib/flickrie/{user.rb → objects/user.rb} +10 -50
- data/lib/flickrie/{user → objects/user}/upload_status.rb +0 -0
- data/lib/flickrie/{video.rb → objects/video.rb} +3 -4
- data/lib/flickrie/version.rb +1 -1
- metadata +38 -37
- data/lib/flickrie/api_methods/media.rb +0 -698
- data/lib/flickrie/api_methods/set.rb +0 -23
- data/lib/flickrie/api_methods/user.rb +0 -45
- data/lib/flickrie/media/class_methods.rb +0 -217
- data/lib/flickrie/media/visibility.rb +0 -29
- data/lib/flickrie/media_count.rb +0 -54
@@ -0,0 +1,15 @@
|
|
1
|
+
module Flickrie
|
2
|
+
module Base58
|
3
|
+
ALPHABET = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'.chars.to_a.freeze
|
4
|
+
|
5
|
+
def to_base58(value)
|
6
|
+
value = Integer(value)
|
7
|
+
begin
|
8
|
+
value, remainder = value.divmod(58)
|
9
|
+
result = ALPHABET[remainder] + (result || '')
|
10
|
+
end while value > 0
|
11
|
+
|
12
|
+
result
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'flickrie/client'
|
2
|
+
require 'flickrie/upload_client'
|
3
|
+
require 'flickrie/middleware'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
module Flickrie
|
7
|
+
module Callable
|
8
|
+
# This is for manual use (for example, if I haven't covered something yet, and you really need it).
|
9
|
+
# Here's an example:
|
10
|
+
#
|
11
|
+
# response = Flickrie.client.get "flickr.photos.getInfo", :photo_id => 8423943
|
12
|
+
# response.body['photo']['id'] # => 8423943
|
13
|
+
# response.body['photo']['description'] # => "..."
|
14
|
+
#
|
15
|
+
# Flickrie.client.post "flickr.photos.licenses.setLicense", :photo_id => 1241497, :license_id => 2
|
16
|
+
#
|
17
|
+
# For the full list of available API methods, see [this page](http://www.flickr.com/services/api/).
|
18
|
+
#
|
19
|
+
# @return [HTTP response] A Faraday HTTP response
|
20
|
+
def client
|
21
|
+
params = {
|
22
|
+
:url => 'http://api.flickr.com/services/rest',
|
23
|
+
:params => {
|
24
|
+
:format => 'json',
|
25
|
+
:nojsoncallback => '1',
|
26
|
+
:api_key => api_key
|
27
|
+
},
|
28
|
+
:request => {
|
29
|
+
:open_timeout => open_timeout || DEFAULTS[:open_timeout],
|
30
|
+
:timeout => timeout || DEFAULTS[:timeout]
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
@client ||=
|
35
|
+
Client.new(params) do |b|
|
36
|
+
b.use Middleware::Retry
|
37
|
+
b.use FaradayMiddleware::OAuth,
|
38
|
+
:consumer_key => api_key,
|
39
|
+
:consumer_secret => shared_secret,
|
40
|
+
:token => access_token,
|
41
|
+
:token_secret => access_secret
|
42
|
+
|
43
|
+
b.use Middleware::FixFlickrData
|
44
|
+
b.use Middleware::StatusCheck
|
45
|
+
b.use FaradayMiddleware::ParseJson
|
46
|
+
b.use Middleware::OAuthCheck
|
47
|
+
|
48
|
+
b.adapter :net_http
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def upload_client
|
53
|
+
params = {
|
54
|
+
:url => 'http://api.flickr.com/services',
|
55
|
+
:request => {
|
56
|
+
:open_timeout => open_timeout || DEFAULTS[:open_timeout]
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
@upload_client ||=
|
61
|
+
UploadClient.new(params) do |b|
|
62
|
+
b.use Middleware::Retry
|
63
|
+
b.use FaradayMiddleware::OAuth,
|
64
|
+
:consumer_key => api_key,
|
65
|
+
:consumer_secret => shared_secret,
|
66
|
+
:token => access_token,
|
67
|
+
:token_secret => access_secret
|
68
|
+
b.request :multipart
|
69
|
+
|
70
|
+
b.use Middleware::UploadStatusCheck
|
71
|
+
b.use FaradayMiddleware::ParseXml
|
72
|
+
b.use Middleware::OAuthCheck
|
73
|
+
|
74
|
+
b.adapter :net_http
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/lib/flickrie/client.rb
CHANGED
@@ -2,22 +2,20 @@ require 'faraday'
|
|
2
2
|
|
3
3
|
module Flickrie
|
4
4
|
class Client < Faraday::Connection
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
req.params[:method] = method
|
20
|
-
req.params.update(params)
|
5
|
+
# @!method get(method, params = {})
|
6
|
+
# @!method post(method, params = {})
|
7
|
+
[:get, :post].each do |http_method|
|
8
|
+
define_method(http_method) do |flickr_method, params = {}|
|
9
|
+
# (:include_sizes => true) --> (:extras => "url_sq,url_q,url_s,...")
|
10
|
+
if params.delete(:include_sizes)
|
11
|
+
urls = Photo::FLICKR_SIZES.values.map { |s| "url_#{s}" }.join(',')
|
12
|
+
params[:extras] = [params[:extras], urls].compact.join(',')
|
13
|
+
end
|
14
|
+
|
15
|
+
super() do |req|
|
16
|
+
req.params[:method] = flickr_method
|
17
|
+
req.params.update(params)
|
18
|
+
end
|
21
19
|
end
|
22
20
|
end
|
23
21
|
|
@@ -82,7 +80,7 @@ module Flickrie
|
|
82
80
|
end
|
83
81
|
|
84
82
|
def get_media_counts(params = {})
|
85
|
-
get 'flickr.photos.getCounts', params
|
83
|
+
get 'flickr.photos.getCounts', ensure_utc(params)
|
86
84
|
end
|
87
85
|
|
88
86
|
def get_media_exif(media_id, params = {})
|
@@ -223,5 +221,15 @@ module Flickrie
|
|
223
221
|
dup_params[:extras] = [dup_params[:extras], 'media'].compact.join(',')
|
224
222
|
end
|
225
223
|
end
|
224
|
+
|
225
|
+
def ensure_utc(params)
|
226
|
+
params.dup.tap do |hash|
|
227
|
+
if hash[:taken_dates].is_a?(String)
|
228
|
+
hash[:taken_dates] = hash[:taken_dates].split(',').
|
229
|
+
map { |date| DateTime.parse(date) }.
|
230
|
+
map(&:to_time).map(&:getutc).join(',')
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
226
234
|
end
|
227
235
|
end
|
data/lib/flickrie/instance.rb
CHANGED
@@ -2,6 +2,15 @@ module Flickrie
|
|
2
2
|
class Instance
|
3
3
|
attr_reader :access_token, :access_secret
|
4
4
|
|
5
|
+
def self.delegate(*attributes)
|
6
|
+
attributes.each do |attribute|
|
7
|
+
define_method(attribute) do
|
8
|
+
Flickrie.send(attribute)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
delegate :api_key, :shared_secret, :open_timeout, :timeout, :pagination
|
13
|
+
|
5
14
|
# Initializes a new authenticated instance. Example:
|
6
15
|
#
|
7
16
|
# flickrie = Flickrie::Instance.new("ACCESS_TOKEN", "ACCESS_SECRET")
|
@@ -10,21 +19,7 @@ module Flickrie
|
|
10
19
|
@access_token, @access_secret = access_token, access_secret
|
11
20
|
end
|
12
21
|
|
13
|
-
|
14
|
-
def client
|
15
|
-
@client ||= Flickrie.new_client(access_token_hash)
|
16
|
-
end
|
17
|
-
|
22
|
+
include Callable
|
18
23
|
include ApiMethods
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def upload_client
|
23
|
-
@upload_client ||= Flickrie.new_upload_client(access_token_hash)
|
24
|
-
end
|
25
|
-
|
26
|
-
def access_token_hash
|
27
|
-
{:token => access_token, :secret => access_secret}
|
28
|
-
end
|
29
24
|
end
|
30
25
|
end
|
data/lib/flickrie/middleware.rb
CHANGED
@@ -12,7 +12,7 @@ module Flickrie
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# Internal
|
15
|
-
module Middleware
|
15
|
+
module Middleware
|
16
16
|
class StatusCheck < Faraday::Response::Middleware
|
17
17
|
def on_complete(env)
|
18
18
|
if env[:body]['stat'] != 'ok'
|
@@ -40,26 +40,6 @@ module Flickrie
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
class Retry < Faraday::Middleware
|
44
|
-
def initialize(app, retries = 2)
|
45
|
-
@retries = retries
|
46
|
-
super(app)
|
47
|
-
end
|
48
|
-
|
49
|
-
def call(env)
|
50
|
-
retries = @retries
|
51
|
-
begin
|
52
|
-
@app.call(env)
|
53
|
-
rescue Faraday::Error::TimeoutError
|
54
|
-
if retries > 0
|
55
|
-
retries -= 1
|
56
|
-
retry
|
57
|
-
end
|
58
|
-
raise
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
43
|
class ParseOAuthParams < FaradayMiddleware::ResponseMiddleware
|
64
44
|
define_parser do |body|
|
65
45
|
CGI.parse(body).inject({}) do |hash, (key, value)|
|
@@ -69,3 +49,6 @@ module Flickrie
|
|
69
49
|
end
|
70
50
|
end
|
71
51
|
end
|
52
|
+
|
53
|
+
require 'flickrie/middleware/retry'
|
54
|
+
require 'flickrie/middleware/fix_flickr_data'
|
@@ -0,0 +1,215 @@
|
|
1
|
+
module Flickrie
|
2
|
+
module Middleware
|
3
|
+
class FixFlickrData < Faraday::Response::Middleware
|
4
|
+
def call(env)
|
5
|
+
response = @app.call(env)
|
6
|
+
fix_flickr_data!(response)
|
7
|
+
response
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# Ugly, just normalizing the data
|
13
|
+
def fix_flickr_data!(response)
|
14
|
+
data = response.env[:body]
|
15
|
+
query = CGI.parse(response.env[:url].query)
|
16
|
+
flickr_method = query['method'].first
|
17
|
+
|
18
|
+
case flickr_method
|
19
|
+
# people
|
20
|
+
when 'flickr.people.findByUsername'
|
21
|
+
data['user']['username'] = data['user']['username']['_content']
|
22
|
+
when 'flickr.people.findByEmail'
|
23
|
+
data['user']['username'] = data['user']['username']['_content']
|
24
|
+
when 'flickr.people.getInfo'
|
25
|
+
%w[username realname location description profileurl mobileurl photosurl].each do |attribute|
|
26
|
+
data['person'][attribute] = data['person'][attribute]['_content']
|
27
|
+
end
|
28
|
+
%w[count firstdatetaken firstdate].each do |photo_attribute|
|
29
|
+
data['person']['photos'][photo_attribute] = data['person']['photos'][photo_attribute]['_content']
|
30
|
+
end
|
31
|
+
when 'flickr.test.login'
|
32
|
+
data['user']['username'] = data['user']['username']['_content']
|
33
|
+
when 'flickr.people.getUploadStatus'
|
34
|
+
data['user']['username'] = data['user']['username']['_content']
|
35
|
+
data['user']['upload_status'] = {
|
36
|
+
'bandwidth' => data['user'].delete('bandwidth'),
|
37
|
+
'filesize' => data['user'].delete('filesize'),
|
38
|
+
'sets' => data['user'].delete('sets'),
|
39
|
+
'videosize' => data['user'].delete('videosize'),
|
40
|
+
'videos' => data['user'].delete('videos')
|
41
|
+
}
|
42
|
+
|
43
|
+
# photos
|
44
|
+
when 'flickr.people.getPhotos'
|
45
|
+
fix_common!(data)
|
46
|
+
when 'flickr.people.getPublicPhotos'
|
47
|
+
fix_common!(data)
|
48
|
+
when 'flickr.photos.getInfo'
|
49
|
+
data['photo']['title'] = data['photo']['title']['_content']
|
50
|
+
data['photo']['description'] = data['photo']['description']['_content']
|
51
|
+
data['photo']['comments_count'] = data['photo'].delete('comments')['_content']
|
52
|
+
data['photo']['dates']['uploaded'] = data['photo'].delete('dateuploaded')
|
53
|
+
data['photo']['tags'] = data['photo']['tags']['tag']
|
54
|
+
when 'flickr.photosets.getPhotos'
|
55
|
+
data['photoset']['photo'].map! do |media_hash|
|
56
|
+
media_hash['owner'] = {
|
57
|
+
'id' => data['photoset']['owner'],
|
58
|
+
'nsid' => data['photoset']['owner'],
|
59
|
+
'username' => data['photoset']['ownername'],
|
60
|
+
}
|
61
|
+
fix_extras!(media_hash)
|
62
|
+
media_hash
|
63
|
+
end
|
64
|
+
when 'flickr.photos.getSizes'
|
65
|
+
data['sizes']['usage'] = {
|
66
|
+
'canblog' => data['sizes']['canblog'],
|
67
|
+
'canprint' => data['sizes']['canprint'],
|
68
|
+
'candownload' => data['sizes']['candownload']
|
69
|
+
}
|
70
|
+
data['sizes']['id'] = query['photo_id'].first
|
71
|
+
if data['sizes']['size'].find { |hash| hash['label'] == 'Video Player' }
|
72
|
+
# Video
|
73
|
+
data['sizes']['video'] ||= {}
|
74
|
+
data['sizes']['size'].each do |info|
|
75
|
+
case info['label']
|
76
|
+
when 'Video Player' then data['sizes']['video']['source_url'] = info['source']
|
77
|
+
when 'Site MP4' then data['sizes']['video']['download_url'] = info['source']
|
78
|
+
when 'Mobile MP4' then data['sizes']['video']['mobile_download_url'] = info['source']
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
flickr_sizes = {
|
83
|
+
'Square' => Photo::FLICKR_SIZES['Square 75'],
|
84
|
+
'Large Square' => Photo::FLICKR_SIZES['Square 150'],
|
85
|
+
'Thumbnail' => Photo::FLICKR_SIZES['Thumbnail'],
|
86
|
+
'Small' => Photo::FLICKR_SIZES['Small 240'],
|
87
|
+
'Small 320' => Photo::FLICKR_SIZES['Small 320'],
|
88
|
+
'Medium' => Photo::FLICKR_SIZES['Medium 500'],
|
89
|
+
'Medium 640' => Photo::FLICKR_SIZES['Medium 640'],
|
90
|
+
'Medium 800' => Photo::FLICKR_SIZES['Medium 800'],
|
91
|
+
'Large' => Photo::FLICKR_SIZES['Large 1024'],
|
92
|
+
'Large 1600' => Photo::FLICKR_SIZES['Large 1600'],
|
93
|
+
'Large 2048' => Photo::FLICKR_SIZES['Large 2048'],
|
94
|
+
'Original' => Photo::FLICKR_SIZES['Original']
|
95
|
+
}
|
96
|
+
data['sizes']['size'].each do |size_info|
|
97
|
+
size_abbr = flickr_sizes[size_info['label']]
|
98
|
+
data['sizes']["width_#{size_abbr}"] = size_info['width']
|
99
|
+
data['sizes']["height_#{size_abbr}"] = size_info['height']
|
100
|
+
data['sizes']["url_#{size_abbr}"] = size_info['source']
|
101
|
+
end
|
102
|
+
end
|
103
|
+
when 'flickr.photos.search'
|
104
|
+
fix_common!(data)
|
105
|
+
when 'flickr.photos.getContactsPhotos'
|
106
|
+
data['photos']['photo'].each do |media_hash|
|
107
|
+
media_hash['ownername'] = media_hash.delete('username')
|
108
|
+
end
|
109
|
+
fix_common!(data)
|
110
|
+
when 'flickr.photos.getContactsPublicPhotos'
|
111
|
+
data['photos']['photo'].each do |media_hash|
|
112
|
+
media_hash['ownername'] = media_hash.delete('username')
|
113
|
+
end
|
114
|
+
fix_common!(data)
|
115
|
+
when 'flickr.photos.getNotInSet'
|
116
|
+
fix_common!(data)
|
117
|
+
when 'flickr.people.getPhotosOf'
|
118
|
+
fix_common!(data)
|
119
|
+
when 'flickr.photos.getPerms'
|
120
|
+
fix_visibility!(data['perms'])
|
121
|
+
data['perms']['permissions'] = {
|
122
|
+
'permcomment' => data['perms'].delete('permcomment'),
|
123
|
+
'permaddmeta' => data['perms'].delete('permaddmeta')
|
124
|
+
}
|
125
|
+
when 'flickr.photos.getRecent'
|
126
|
+
fix_common!(data)
|
127
|
+
when 'flickr.photos.getUntagged'
|
128
|
+
fix_common!(data)
|
129
|
+
when 'flickr.photos.getWithGeoData'
|
130
|
+
fix_common!(data)
|
131
|
+
when 'flickr.photos.getWithoutGeoData'
|
132
|
+
fix_common!(data)
|
133
|
+
when 'flickr.photos.recentlyUpdated'
|
134
|
+
fix_common!(data)
|
135
|
+
|
136
|
+
# photosets
|
137
|
+
when 'flickr.photosets.getInfo'
|
138
|
+
data['photoset']['title'] = data['photoset']['title']['_content']
|
139
|
+
data['photoset']['description'] = data['photoset']['description']['_content']
|
140
|
+
when 'flickr.photosets.getList'
|
141
|
+
data['photosets']['photoset'].map! do |set_hash|
|
142
|
+
set_hash['count_photos'] = set_hash.delete('photos')
|
143
|
+
set_hash['count_videos'] = set_hash.delete('videos')
|
144
|
+
set_hash['title'] = set_hash['title']['_content']
|
145
|
+
set_hash['description'] = set_hash['description']['_content']
|
146
|
+
set_hash['owner'] = query['user_id'].first
|
147
|
+
set_hash
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def fix_extras!(hash)
|
153
|
+
if hash['iconserver'] or hash['iconfarm']
|
154
|
+
hash['owner'] ||= {}
|
155
|
+
hash['owner'].update \
|
156
|
+
'iconserver' => hash.delete('iconserver'),
|
157
|
+
'iconfarm' => hash.delete('iconfarm')
|
158
|
+
end
|
159
|
+
|
160
|
+
if hash['place_id']
|
161
|
+
geo_info = %w[latitude longitude accuracy context place_id woeid]
|
162
|
+
hash['location'] = geo_info.inject({}) do |location, geo|
|
163
|
+
location.update(geo => hash.delete(geo))
|
164
|
+
end
|
165
|
+
hash['geoperms'] = {
|
166
|
+
'isfamily' => hash['geo_is_family'],
|
167
|
+
'isfriend' => hash['geo_is_friend'],
|
168
|
+
'iscontact' => hash['geo_is_contact'],
|
169
|
+
'ispublic' => hash['geo_is_public']
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
if hash['tags']
|
174
|
+
hash['tags'] = hash['tags'].split(' ').map do |tag_content|
|
175
|
+
{'_content' => tag_content, 'machine_tag' => 0}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
if hash['machine_tags']
|
179
|
+
hash['tags'] ||= []
|
180
|
+
hash['tags'] += hash.delete('machine_tags').split(' ').map do |tag_content|
|
181
|
+
{'_content' => tag_content, 'machine_tag' => 1}
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
hash['dates'] = {
|
186
|
+
'uploaded' => hash.delete('dateupload'),
|
187
|
+
'lastupdate' => hash.delete('lastupdate'),
|
188
|
+
'taken' => hash.delete('datetaken'),
|
189
|
+
'takengranularity' => hash.delete('datetakengranularity'),
|
190
|
+
}
|
191
|
+
end
|
192
|
+
|
193
|
+
def fix_visibility!(hash)
|
194
|
+
hash['visibility'] = {
|
195
|
+
'ispublic' => hash.delete('ispublic'),
|
196
|
+
'isfriend' => hash.delete('isfriend'),
|
197
|
+
'isfamily' => hash.delete('isfamily')
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
def fix_common!(hash)
|
202
|
+
hash['photos']['photo'].map! do |media_hash|
|
203
|
+
media_hash['owner'] = {
|
204
|
+
'id' => media_hash['owner'],
|
205
|
+
'nsid' => media_hash.delete('owner'),
|
206
|
+
'username' => media_hash.delete('ownername')
|
207
|
+
}
|
208
|
+
fix_extras!(media_hash)
|
209
|
+
fix_visibility!(media_hash)
|
210
|
+
media_hash
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|