flickrie 1.5.0 → 1.5.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 (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