flickrie 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/README.md +1 -1
  2. data/lib/flickrie.rb +18 -92
  3. data/lib/flickrie/api_methods.rb +759 -11
  4. data/lib/flickrie/base58.rb +15 -0
  5. data/lib/flickrie/callable.rb +78 -0
  6. data/lib/flickrie/client.rb +25 -17
  7. data/lib/flickrie/instance.rb +10 -15
  8. data/lib/flickrie/middleware.rb +4 -21
  9. data/lib/flickrie/middleware/fix_flickr_data.rb +215 -0
  10. data/lib/flickrie/middleware/retry.rb +23 -0
  11. data/lib/flickrie/{license.rb → objects/license.rb} +0 -0
  12. data/lib/flickrie/{location.rb → objects/location.rb} +13 -13
  13. data/lib/flickrie/{media.rb → objects/media.rb} +30 -25
  14. data/lib/flickrie/{media → objects/media}/exif.rb +0 -0
  15. data/lib/flickrie/{media → objects/media}/note.rb +11 -12
  16. data/lib/flickrie/{media → objects/media}/tag.rb +10 -9
  17. data/lib/flickrie/objects/media/visibility.rb +28 -0
  18. data/lib/flickrie/objects/media_context.rb +17 -0
  19. data/lib/flickrie/objects/media_count.rb +46 -0
  20. data/lib/flickrie/{photo.rb → objects/photo.rb} +2 -3
  21. data/lib/flickrie/{set.rb → objects/set.rb} +9 -30
  22. data/lib/flickrie/{ticket.rb → objects/ticket.rb} +0 -0
  23. data/lib/flickrie/{user.rb → objects/user.rb} +10 -50
  24. data/lib/flickrie/{user → objects/user}/upload_status.rb +0 -0
  25. data/lib/flickrie/{video.rb → objects/video.rb} +3 -4
  26. data/lib/flickrie/version.rb +1 -1
  27. metadata +38 -37
  28. data/lib/flickrie/api_methods/media.rb +0 -698
  29. data/lib/flickrie/api_methods/set.rb +0 -23
  30. data/lib/flickrie/api_methods/user.rb +0 -45
  31. data/lib/flickrie/media/class_methods.rb +0 -217
  32. data/lib/flickrie/media/visibility.rb +0 -29
  33. 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
@@ -2,22 +2,20 @@ require 'faraday'
2
2
 
3
3
  module Flickrie
4
4
  class Client < Faraday::Connection
5
- def get(method, params = {})
6
- if params.delete(:include_sizes)
7
- urls = Photo::FLICKR_SIZES.values.map { |s| "url_#{s}" }.join(',')
8
- params[:extras] = [params[:extras], urls].compact.join(',')
9
- end
10
-
11
- super() do |req|
12
- req.params[:method] = method
13
- req.params.update(params)
14
- end
15
- end
16
-
17
- def post(method, params = {})
18
- super() do |req|
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
@@ -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
- # See {Flickrie.client} for more info.
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
@@ -12,7 +12,7 @@ module Flickrie
12
12
  end
13
13
 
14
14
  # Internal
15
- module Middleware # :nodoc:
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