flickraw 0.7.1 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +82 -1
  3. data/lib/flickraw.rb +136 -91
  4. data/test/test.rb +357 -38
  5. data/test/test_upload.rb +31 -0
  6. metadata +12 -9
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006 Hank Lords <hanklords@gmail.com>
1
+ Copyright (c) 2006 Mael Clerambault <maelclerambault@yahoo.fr>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -13,11 +13,23 @@ The github repository: http://github.com/hanklords/flickraw/tree/master
13
13
  Type this in a console (you might need to be superuser)
14
14
  gem install flickraw
15
15
 
16
- You can recreate this documentation by typing this in the source directory:
16
+ This will recreate the documentation by fetching the methods descriptions from flickr and then virtually plugging them in standard rdoc documentation.
17
17
  rake rdoc
18
18
 
19
+ = Features
20
+
21
+ * Small single file: flickraw.rb is less than 300 lines
22
+ * Complete support of flickr API. This doesn't require an update of the library
23
+ * Ruby syntax similar to the flickr api
24
+ * Flickr authentication
25
+ * Photo upload
26
+ * Proxy support
27
+ * Delayed library loading (for rails users)
28
+
19
29
  = Usage
20
30
 
31
+ == Simple
32
+
21
33
  require 'flickraw'
22
34
 
23
35
  list = flickr.photos.getRecent
@@ -35,6 +47,75 @@ You can recreate this documentation by typing this in the source directory:
35
47
  original = sizes.find {|s| s.label == 'Original' }
36
48
  original.width # => "800"
37
49
 
50
+ == Authentication
51
+
52
+ require 'flickraw'
53
+
54
+ FlickRaw.api_key="... Your API key ..."
55
+ FlickRaw.shared_secret="... Your shared secret ..."
56
+
57
+ frob = flickr.auth.getFrob
58
+ auth_url = FlickRaw.auth_url :frob => frob, :perms => 'read'
59
+
60
+ puts "Open this url in your process to complete the authication process : #{auth_url}"
61
+ puts "Press Enter when you are finished."
62
+ STDIN.getc
63
+
64
+ begin
65
+ auth = flickr.auth.getToken :frob => frob
66
+ login = flickr.test.login
67
+ puts "You are now authenticated as #{login.username} with token #{auth.token}"
68
+ rescue FlickRaw::FailedResponse => e
69
+ puts "Authentication failed : #{e.msg}"
70
+ end
71
+
72
+ You don't need to do that each time, you can reuse your token:
73
+
74
+ require 'flickraw'
75
+
76
+ FlickRaw.api_key="... Your API key ..."
77
+ FlickRaw.shared_secret="... Your shared secret ..."
78
+
79
+ auth = flickr.auth.checkToken :auth_token => "... Your saved token ..."
80
+
81
+ # From here you are logged:
82
+ puts auth.user.username
83
+
84
+ == Upload
85
+
86
+ require 'flickraw'
87
+
88
+ FlickRaw.api_key="... Your API key ..."
89
+ FlickRaw.shared_secret="... Your shared secret ..."
90
+
91
+ PHOTO_PATH='photo.jpg'
92
+
93
+ # You need to be authentified to do that, see the previous examples.
94
+ flickr.upload_photo PHOTO_PATH, :title => "Title", :description => "This is the description"
95
+
96
+ == Flickraw Options
97
+
98
+ You can pass some options to modify flickraw behavior:
99
+
100
+ FlickrawOptions = {
101
+ "api_key" => "... Your API key ...",
102
+ "shared_secret" => "... Your shared secret ...",
103
+ "auth_token" => "... Your saved token..." # if you set this you will be automatically loggued
104
+ "lazyload" => true, # This delay the loading of the library until the first call
105
+
106
+ # Proxy support. alternatively, you can use the http_proxy environment variable
107
+ "proxy_host" => "proxy_host",
108
+ "proxy_port" => "proxy_port",
109
+ "proxy_user" => "proxy_user",
110
+ "proxy_password" => "proxy_password",
111
+
112
+ "timeout" => 5, # Set the request timeout
113
+ "auth_token" => "SAVED_TOKEN" # Set the initial token
114
+ }
115
+
116
+ require 'flickraw'
117
+
118
+
38
119
  See the _examples_ directory to find more examples.
39
120
 
40
121
  = Notes
@@ -1,3 +1,4 @@
1
+ # encoding: ascii-8bit
1
2
  # Copyright (c) 2006 Mael Clerambault <maelclerambault@yahoo.fr>
2
3
  #
3
4
  # Permission is hereby granted, free of charge, to any person obtaining
@@ -23,64 +24,67 @@
23
24
  require 'net/http'
24
25
  require 'digest/md5'
25
26
  require 'json'
26
- require 'cgi'
27
27
 
28
- FlickrawOptions = {} if not Object.const_defined? :FlickrawOptions
29
- if ENV['http_proxy'] and not FlickrawOptions[:proxy_host]
28
+ FlickRawOptions = {} if not Object.const_defined? :FlickRawOptions # :nodoc:
29
+ FlickRawOptions['api_key'] ||= '7b124df89b638e545e3165293883ef62'
30
+ if ENV['http_proxy'] and not FlickRawOptions['proxy_host']
30
31
  proxy = URI.parse ENV['http_proxy']
31
- FlickrawOptions.update(:proxy_host => proxy.host, :proxy_port => proxy.port, :proxy_user => proxy.user, :proxy_password => proxy.password)
32
+ FlickRawOptions.update('proxy_host' => proxy.host, 'proxy_port' => proxy.port, 'proxy_user' => proxy.user, 'proxy_password' => proxy.password)
32
33
  end
33
34
 
34
35
  module FlickRaw
35
- VERSION='0.7.1'
36
+ VERSION='0.8'
36
37
 
37
38
  FLICKR_HOST='api.flickr.com'.freeze
38
-
39
- # Path of flickr REST API
40
39
  REST_PATH='/services/rest/?'.freeze
41
-
42
- # Path of flickr auth page
43
- AUTH_PATH='/services/auth/?'.freeze
44
-
45
- # Path of flickr upload
46
40
  UPLOAD_PATH='/services/upload/'.freeze
47
-
48
- @api_key = '7b124df89b638e545e3165293883ef62'
49
-
50
- module SimpleOStruct # :nodoc:
51
- def __attr_define(k,v)
52
- instance_variable_set "@#{k}", v
53
- meta = class << self; self; end
54
- meta.class_eval { attr_reader k.to_s }
55
- end
56
- end
57
-
58
- class Response # :nodoc:
59
- include SimpleOStruct
60
- def initialize(h)
61
- h.each {|k, v| __attr_define k, Response.structify(v, k) }
41
+ REPLACE_PATH='/services/replace/'.freeze
42
+
43
+ AUTH_PATH='http://flickr.com/services/auth/?'.freeze
44
+ PHOTO_SOURCE_URL='http://farm%s.static.flickr.com/%s/%s_%s%s.%s'.freeze
45
+ URL_PROFILE='http://www.flickr.com/people/'.freeze
46
+ URL_PHOTOSTREAM='http://www.flickr.com/photos/'.freeze
47
+ URL_SHORT="http://flic.kr/p/".freeze
48
+
49
+ class Response
50
+ def self.build(h, type) # :nodoc:
51
+ if type =~ /s$/ and (a = h[$`]).is_a? Array
52
+ ResponseList.new(h, type, a.collect {|e| Response.build(e, $`)})
53
+ elsif h.keys == ["_content"]
54
+ h["_content"]
55
+ else
56
+ Response.new(h, type)
57
+ end
62
58
  end
63
59
 
64
- def self.structify(obj, name = '')
65
- if obj.is_a? Hash
66
- if name =~ /s$/ and obj[$`].is_a? Array
67
- list = structify obj.delete($`)
68
- list.extend SimpleOStruct
69
- list.instance_eval { obj.each {|kv, vv| __attr_define kv, vv } }
70
- list
71
- elsif obj.keys == ['_content']
72
- obj['_content'].to_s
73
- else
74
- Response.new obj
60
+ attr_reader :flickr_type
61
+ def initialize(h, type) # :nodoc:
62
+ @flickr_type, @h = type, {}
63
+ methods = "class << self;"
64
+ h.each {|k,v|
65
+ @h[k] = case v
66
+ when Hash then Response.build(v, k)
67
+ when Array then v.collect {|e| Response.build(e, k)}
68
+ else v
75
69
  end
76
- elsif obj.is_a? Array
77
- obj.collect {|e| structify e}
78
- else
79
- obj
80
- end
70
+ methods << "def #{k}; @h['#{k}'] end;"
71
+ }
72
+ eval methods << "end"
81
73
  end
74
+ def [](k); @h[k] end
75
+ def to_s; @h["_content"] || super end
76
+ def inspect; @h.inspect end
77
+ def to_hash; @h end
78
+ end
82
79
 
83
- def to_s; @_content || super end
80
+ class ResponseList < Response
81
+ include Enumerable
82
+ def initialize(h, t, a); super(h, t); @a = a end
83
+ def [](k); k.is_a?(Fixnum) ? @a[k] : super(k) end
84
+ def each; @a.each{|e| yield e} end
85
+ def to_a; @a end
86
+ def inspect; @a.inspect end
87
+ def size; @a.size end
84
88
  end
85
89
 
86
90
  class FailedResponse < StandardError
@@ -143,19 +147,29 @@ module FlickRaw
143
147
  class Flickr < Request
144
148
  def self.build(methods); methods.each { |m| build_request m } end
145
149
 
146
- def initialize # :nodoc:
150
+ def initialize(token = FlickRawOptions['auth_token']) # :nodoc:
147
151
  Flickr.build(call('flickr.reflection.getMethods')) if Flickr.flickr_objects.empty?
148
152
  super self
149
- @token = nil
153
+ @token = token
150
154
  end
151
155
 
152
156
  # This is the central method. It does the actual request to the flickr server.
153
157
  #
154
158
  # Raises FailedResponse if the response status is _failed_.
155
159
  def call(req, args={})
156
- path = REST_PATH + build_args(args, req).collect { |a, v| "#{a}=#{v}" }.join('&')
157
- http_response = open_flickr {|http| http.get(path, 'User-Agent' => "Flickraw/#{VERSION}") }
158
- parse_response(http_response, req)
160
+ http_response = open_flickr do |http|
161
+ request = Net::HTTP::Post.new(REST_PATH, 'User-Agent' => "Flickraw/#{VERSION}")
162
+ request.set_form_data(build_args(args, req))
163
+ http.request(request)
164
+ end
165
+
166
+ json = JSON.load(http_response.body.empty? ? "{}" : http_response.body)
167
+ raise FailedResponse.new(json['message'], json['code'], req) if json.delete('stat') == 'fail'
168
+ type, json = json.to_a.first if json.size == 1 and json.all? {|k,v| v.is_a? Hash}
169
+
170
+ res = Response.build json, type
171
+ @token = res.token if res.respond_to? :flickr_type and res.flickr_type == "auth"
172
+ res
159
173
  end
160
174
 
161
175
  # Use this to upload the photo in _file_.
@@ -163,12 +177,43 @@ module FlickRaw
163
177
  # flickr.upload_photo '/path/to/the/photo', :title => 'Title', :description => 'This is the description'
164
178
  #
165
179
  # See http://www.flickr.com/services/api/upload.api.html for more information on the arguments.
166
- def upload_photo(file, args={})
180
+ def upload_photo(file, args={}); upload_flickr(UPLOAD_PATH, file, args) end
181
+
182
+ # Use this to replace the photo with :photo_id with the photo in _file_.
183
+ #
184
+ # flickr.replace_photo '/path/to/the/photo', :photo_id => id
185
+ #
186
+ # See http://www.flickr.com/services/api/replace.api.html for more information on the arguments.
187
+ def replace_photo(file, args={}); upload_flickr(REPLACE_PATH, file, args) end
188
+
189
+ private
190
+ def build_args(args={}, req = nil)
191
+ full_args = {:api_key => FlickRaw.api_key, :format => 'json', :nojsoncallback => "1"}
192
+ full_args[:method] = req if req
193
+ full_args[:auth_token] = @token if @token
194
+ args.each {|k, v|
195
+ v = v.to_s.encode("utf-8").force_encoding("ascii-8bit") if RUBY_VERSION >= "1.9"
196
+ full_args[k.to_sym] = v.to_s
197
+ }
198
+ full_args[:api_sig] = FlickRaw.api_sig(full_args) if FlickRaw.shared_secret
199
+ full_args
200
+ end
201
+
202
+ def open_flickr
203
+ Net::HTTP::Proxy(FlickRawOptions['proxy_host'], FlickRawOptions['proxy_port'], FlickRawOptions['proxy_user'], FlickRawOptions['proxy_password']).start(FLICKR_HOST) {|http|
204
+ http.read_timeout = FlickRawOptions['timeout'] if FlickRawOptions['timeout']
205
+ yield http
206
+ }
207
+ end
208
+
209
+ def upload_flickr(method, file, args={})
167
210
  photo = File.open(file, 'rb') { |f| f.read }
168
211
  boundary = Digest::MD5.hexdigest(photo)
169
212
 
170
213
  header = {'Content-type' => "multipart/form-data, boundary=#{boundary} ", 'User-Agent' => "Flickraw/#{VERSION}"}
171
214
  query = ''
215
+
216
+ file = file.to_s.encode("utf-8").force_encoding("ascii-8bit") if RUBY_VERSION >= "1.9"
172
217
  build_args(args).each { |a, v|
173
218
  query <<
174
219
  "--#{boundary}\r\n" <<
@@ -184,70 +229,70 @@ module FlickRaw
184
229
  "\r\n" <<
185
230
  "--#{boundary}--"
186
231
 
187
- http_response = open_flickr {|http| http.post(UPLOAD_PATH, query, header) }
232
+ http_response = open_flickr {|http| http.post(method, query, header) }
188
233
  xml = http_response.body
189
234
  if xml[/stat="(\w+)"/, 1] == 'fail'
190
235
  msg = xml[/msg="([^"]+)"/, 1]
191
236
  code = xml[/code="([^"]+)"/, 1]
192
237
  raise FailedResponse.new(msg, code, 'flickr.upload')
193
238
  end
194
- Response.structify( {:stat => 'ok', :photoid => xml[/<photoid>(\w+)<\/photoid>/, 1], :ticketid => xml[/<ticketid>([^<]+)<\/ticketid>/, 1]})
195
- end
196
-
197
- private
198
- def parse_response(response, req = nil)
199
- json = JSON.load(response.body)
200
- raise FailedResponse.new(json['message'], json['code'], req) if json.delete('stat') == 'fail'
201
- name, json = json.to_a.first if json.size == 1
202
-
203
- res = Response.structify json, name
204
- lookup_token(req, res)
205
- res
206
- end
207
-
208
- def build_args(args={}, req = nil)
209
- full_args = {:api_key => FlickRaw.api_key, :format => 'json', :nojsoncallback => 1}
210
- full_args[:method] = req if req
211
- full_args[:auth_token] = @token if @token
212
- args.each {|k, v| full_args[k.to_sym] = v.to_s }
213
- full_args[:api_sig] = FlickRaw.api_sig(full_args) if FlickRaw.shared_secret
214
- args.each {|k, v| full_args[k.to_sym] = CGI.escape(v.to_s) } if req
215
- full_args
216
- end
217
-
218
- def lookup_token(req, res)
219
- token_reqs = ['flickr.auth.getToken', 'flickr.auth.getFullToken', 'flickr.auth.checkToken']
220
- @token = res.token if token_reqs.include?(req) and res.respond_to?(:token)
221
- end
222
-
223
- def open_flickr
224
- Net::HTTP::Proxy(FlickrawOptions[:proxy_host], FlickrawOptions[:proxy_port], FlickrawOptions[:proxy_user], FlickrawOptions[:proxy_password]).start(FLICKR_HOST) {|http|
225
- http.read_timeout = FlickrawOptions[:timeout] if FlickrawOptions[:timeout]
226
- yield http
227
- }
239
+ type = xml[/<(\w+)/, 1]
240
+ h = {
241
+ "secret" => xml[/secret="([^"]+)"/, 1],
242
+ "originalsecret" => xml[/originalsecret="([^"]+)"/, 1],
243
+ "_content" => xml[/>([^<]+)<\//, 1]
244
+ }.delete_if {|k,v| v.nil? }
245
+ Response.build(h, type)
228
246
  end
229
247
  end
230
248
 
231
249
  class << self
232
250
  # Your flickr API key, see http://www.flickr.com/services/api/keys for more information
233
- attr_accessor :api_key
251
+ def api_key; FlickRawOptions['api_key'] end
252
+ def api_key=(key); FlickRawOptions['api_key'] = key end
234
253
 
235
254
  # The shared secret of _api_key_, see http://www.flickr.com/services/api/keys for more information
236
- attr_accessor :shared_secret
255
+ def shared_secret; FlickRawOptions['shared_secret'] end
256
+ def shared_secret=(key); FlickRawOptions['shared_secret'] = key end
237
257
 
238
258
  # Returns the flickr auth URL.
239
259
  def auth_url(args={})
240
- full_args = {:api_key => FlickRaw.api_key, :perms => 'read'}
260
+ full_args = {:api_key => api_key, :perms => 'read'}
241
261
  args.each {|k, v| full_args[k.to_sym] = v }
242
- full_args[:api_sig] = api_sig(full_args) if FlickRaw.shared_secret
262
+ full_args[:api_sig] = api_sig(full_args) if shared_secret
243
263
 
244
- 'http://' + FLICKR_HOST + AUTH_PATH + full_args.collect { |a, v| "#{a}=#{v}" }.join('&')
264
+ AUTH_PATH + full_args.collect { |a, v| "#{a}=#{v}" }.join('&')
245
265
  end
246
266
 
247
267
  # Returns the signature of hsh. This is meant to be passed in the _api_sig_ parameter.
248
268
  def api_sig(hsh)
249
269
  Digest::MD5.hexdigest(FlickRaw.shared_secret + hsh.sort{|a, b| a[0].to_s <=> b[0].to_s }.flatten.join)
250
270
  end
271
+
272
+ BASE58_ALPHABET="123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ".freeze
273
+ def base58(id)
274
+ id = id.to_i
275
+ alphabet = BASE58_ALPHABET.split(//)
276
+ base = alphabet.length
277
+ begin
278
+ id, m = id.divmod(base)
279
+ r = alphabet[m] + (r || '')
280
+ end while id > 0
281
+ r
282
+ end
283
+
284
+ def url(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, "", "jpg"] end
285
+ def url_m(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, "_m", "jpg"] end
286
+ def url_s(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, "_s", "jpg"] end
287
+ def url_t(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, "_t", "jpg"] end
288
+ def url_b(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.secret, "_b", "jpg"] end
289
+ def url_o(r); PHOTO_SOURCE_URL % [r.farm, r.server, r.id, r.originalsecret, "_o", r.originalformat] end
290
+ def url_profile(r); URL_PROFILE + (r.owner.respond_to?(:nsid) ? r.owner.nsid : r.owner) + "/" end
291
+ def url_photostream(r); URL_PHOTOSTREAM + (r.owner.respond_to?(:nsid) ? r.owner.nsid : r.owner) + "/" end
292
+ def url_photopage(r); url_photostream(r) + r.id end
293
+ def url_photosets(r); url_photostream(r) + "sets/" end
294
+ def url_photoset(r); url_photosets(r) + r.id end
295
+ def url_short(r); URL_SHORT + base58(r.id) end
251
296
  end
252
297
  end
253
298
 
@@ -259,4 +304,4 @@ end
259
304
  def flickr; $flickraw ||= FlickRaw::Flickr.new end
260
305
 
261
306
  # Load the methods if the option lazyload is not specified
262
- flickr if not FlickrawOptions[:lazyload]
307
+ flickr if not FlickRawOptions['lazyload']
@@ -3,52 +3,371 @@
3
3
  require 'test/unit'
4
4
  require 'lib/flickraw'
5
5
 
6
- # utf8 hack
7
- def u(str)
8
- str.gsub(/\\+u([0-9a-fA-F]{4,4})/u){["#$1".hex ].pack('U*')}
9
- end
10
-
11
6
  class Basic < Test::Unit::TestCase
12
- def test_known
13
- known_methods = ["flickr.activity.userComments", "flickr.activity.userPhotos", "flickr.auth.checkToken", "flickr.auth.getFrob", "flickr.auth.getFullToken", "flickr.auth.getToken", "flickr.blogs.getList", "flickr.blogs.postPhoto", "flickr.contacts.getList", "flickr.contacts.getPublicList", "flickr.favorites.add", "flickr.favorites.getList", "flickr.favorites.getPublicList", "flickr.favorites.remove", "flickr.groups.browse", "flickr.groups.getInfo", "flickr.groups.pools.add", "flickr.groups.pools.getContext", "flickr.groups.pools.getGroups", "flickr.groups.pools.getPhotos", "flickr.groups.pools.remove", "flickr.groups.search", "flickr.interestingness.getList", "flickr.people.findByEmail", "flickr.people.findByUsername", "flickr.people.getInfo", "flickr.people.getPublicGroups", "flickr.people.getPublicPhotos", "flickr.people.getUploadStatus", "flickr.photos.addTags", "flickr.photos.comments.addComment", "flickr.photos.comments.deleteComment", "flickr.photos.comments.editComment", "flickr.photos.comments.getList", "flickr.photos.delete", "flickr.photos.geo.getLocation", "flickr.photos.geo.getPerms", "flickr.photos.geo.removeLocation", "flickr.photos.geo.setLocation", "flickr.photos.geo.setPerms", "flickr.photos.getAllContexts", "flickr.photos.getContactsPhotos", "flickr.photos.getContactsPublicPhotos", "flickr.photos.getContext", "flickr.photos.getCounts", "flickr.photos.getExif", "flickr.photos.getFavorites", "flickr.photos.getInfo", "flickr.photos.getNotInSet", "flickr.photos.getPerms", "flickr.photos.getRecent", "flickr.photos.getSizes", "flickr.photos.getUntagged", "flickr.photos.getWithGeoData", "flickr.photos.getWithoutGeoData", "flickr.photos.licenses.getInfo", "flickr.photos.licenses.setLicense", "flickr.photos.notes.add", "flickr.photos.notes.delete", "flickr.photos.notes.edit", "flickr.photos.recentlyUpdated", "flickr.photos.removeTag", "flickr.photos.search", "flickr.photos.setDates", "flickr.photos.setMeta", "flickr.photos.setPerms", "flickr.photos.setTags", "flickr.photos.transform.rotate", "flickr.photos.upload.checkTickets", "flickr.photosets.addPhoto", "flickr.photosets.comments.addComment", "flickr.photosets.comments.deleteComment", "flickr.photosets.comments.editComment", "flickr.photosets.comments.getList", "flickr.photosets.create", "flickr.photosets.delete", "flickr.photosets.editMeta", "flickr.photosets.editPhotos", "flickr.photosets.getContext", "flickr.photosets.getInfo", "flickr.photosets.getList", "flickr.photosets.getPhotos", "flickr.photosets.orderSets", "flickr.photosets.removePhoto", "flickr.reflection.getMethodInfo", "flickr.reflection.getMethods", "flickr.tags.getHotList", "flickr.tags.getListPhoto", "flickr.tags.getListUser", "flickr.tags.getListUserPopular", "flickr.tags.getListUserRaw", "flickr.tags.getRelated", "flickr.test.echo", "flickr.test.login", "flickr.test.null", "flickr.urls.getGroup", "flickr.urls.getUserPhotos", "flickr.urls.getUserProfile", "flickr.urls.lookupGroup", "flickr.urls.lookupUser"]
14
- found_methods = flickr.reflection.getMethods
15
- assert_instance_of Array, found_methods
16
- known_methods.each { |m| assert found_methods.include?(m), m}
7
+ def test_request
8
+ flickr_objects = %w{activity auth blogs collections commons contacts
9
+ favorites groups interestingness machinetags panda
10
+ people photos photosets places prefs reflection tags
11
+ test urls
12
+ }
13
+ assert_equal FlickRaw::Flickr.flickr_objects, flickr_objects
14
+ flickr_objects.each {|o|
15
+ assert_respond_to flickr, o
16
+ assert_kind_of FlickRaw::Request, eval("flickr." + o)
17
+ }
17
18
  end
18
-
19
- def test_found
20
- found_methods = flickr.reflection.getMethods
21
- found_methods.each { |m|
22
- assert_nothing_raised {
23
- begin
24
- eval m
25
- rescue FlickRaw::FailedResponse
26
- end
27
- }
19
+
20
+ def test_known
21
+ known_methods = %w{
22
+ flickr.activity.userComments
23
+ flickr.activity.userPhotos
24
+ flickr.auth.checkToken
25
+ flickr.auth.getFrob
26
+ flickr.auth.getFullToken
27
+ flickr.auth.getToken
28
+ flickr.blogs.getList
29
+ flickr.blogs.getServices
30
+ flickr.blogs.postPhoto
31
+ flickr.collections.getInfo
32
+ flickr.collections.getTree
33
+ flickr.commons.getInstitutions
34
+ flickr.contacts.getList
35
+ flickr.contacts.getListRecentlyUploaded
36
+ flickr.contacts.getPublicList
37
+ flickr.favorites.add
38
+ flickr.favorites.getList
39
+ flickr.favorites.getPublicList
40
+ flickr.favorites.remove
41
+ flickr.groups.browse
42
+ flickr.groups.getInfo
43
+ flickr.groups.members.getList
44
+ flickr.groups.pools.add
45
+ flickr.groups.pools.getContext
46
+ flickr.groups.pools.getGroups
47
+ flickr.groups.pools.getPhotos
48
+ flickr.groups.pools.remove
49
+ flickr.groups.search
50
+ flickr.interestingness.getList
51
+ flickr.machinetags.getNamespaces
52
+ flickr.machinetags.getPairs
53
+ flickr.machinetags.getPredicates
54
+ flickr.machinetags.getRecentValues
55
+ flickr.machinetags.getValues
56
+ flickr.panda.getList
57
+ flickr.panda.getPhotos
58
+ flickr.people.findByEmail
59
+ flickr.people.findByUsername
60
+ flickr.people.getInfo
61
+ flickr.people.getPublicGroups
62
+ flickr.people.getPublicPhotos
63
+ flickr.people.getUploadStatus
64
+ flickr.photos.addTags
65
+ flickr.photos.comments.addComment
66
+ flickr.photos.comments.deleteComment
67
+ flickr.photos.comments.editComment
68
+ flickr.photos.comments.getList
69
+ flickr.photos.comments.getRecentForContacts
70
+ flickr.photos.delete
71
+ flickr.photos.geo.batchCorrectLocation
72
+ flickr.photos.geo.correctLocation
73
+ flickr.photos.geo.getLocation
74
+ flickr.photos.geo.getPerms
75
+ flickr.photos.geo.photosForLocation
76
+ flickr.photos.geo.removeLocation
77
+ flickr.photos.geo.setContext
78
+ flickr.photos.geo.setLocation
79
+ flickr.photos.geo.setPerms
80
+ flickr.photos.getAllContexts
81
+ flickr.photos.getContactsPhotos
82
+ flickr.photos.getContactsPublicPhotos
83
+ flickr.photos.getContext
84
+ flickr.photos.getCounts
85
+ flickr.photos.getExif
86
+ flickr.photos.getFavorites
87
+ flickr.photos.getInfo
88
+ flickr.photos.getNotInSet
89
+ flickr.photos.getPerms
90
+ flickr.photos.getRecent
91
+ flickr.photos.getSizes
92
+ flickr.photos.getUntagged
93
+ flickr.photos.getWithGeoData
94
+ flickr.photos.getWithoutGeoData
95
+ flickr.photos.licenses.getInfo
96
+ flickr.photos.licenses.setLicense
97
+ flickr.photos.notes.add
98
+ flickr.photos.notes.delete
99
+ flickr.photos.notes.edit
100
+ flickr.photos.recentlyUpdated
101
+ flickr.photos.removeTag
102
+ flickr.photos.search
103
+ flickr.photos.setContentType
104
+ flickr.photos.setDates
105
+ flickr.photos.setMeta
106
+ flickr.photos.setPerms
107
+ flickr.photos.setSafetyLevel
108
+ flickr.photos.setTags
109
+ flickr.photos.transform.rotate
110
+ flickr.photos.upload.checkTickets
111
+ flickr.photosets.addPhoto
112
+ flickr.photosets.comments.addComment
113
+ flickr.photosets.comments.deleteComment
114
+ flickr.photosets.comments.editComment
115
+ flickr.photosets.comments.getList
116
+ flickr.photosets.create
117
+ flickr.photosets.delete
118
+ flickr.photosets.editMeta
119
+ flickr.photosets.editPhotos
120
+ flickr.photosets.getContext
121
+ flickr.photosets.getInfo
122
+ flickr.photosets.getList
123
+ flickr.photosets.getPhotos
124
+ flickr.photosets.orderSets
125
+ flickr.photosets.removePhoto
126
+ flickr.places.find
127
+ flickr.places.findByLatLon
128
+ flickr.places.getChildrenWithPhotosPublic
129
+ flickr.places.getInfo
130
+ flickr.places.getInfoByUrl
131
+ flickr.places.getPlaceTypes
132
+ flickr.places.getShapeHistory
133
+ flickr.places.getTopPlacesList
134
+ flickr.places.placesForBoundingBox
135
+ flickr.places.placesForContacts
136
+ flickr.places.placesForTags
137
+ flickr.places.placesForUser
138
+ flickr.places.resolvePlaceId
139
+ flickr.places.resolvePlaceURL
140
+ flickr.places.tagsForPlace
141
+ flickr.prefs.getContentType
142
+ flickr.prefs.getGeoPerms
143
+ flickr.prefs.getHidden
144
+ flickr.prefs.getPrivacy
145
+ flickr.prefs.getSafetyLevel
146
+ flickr.reflection.getMethodInfo
147
+ flickr.reflection.getMethods
148
+ flickr.tags.getClusterPhotos
149
+ flickr.tags.getClusters
150
+ flickr.tags.getHotList
151
+ flickr.tags.getListPhoto
152
+ flickr.tags.getListUser
153
+ flickr.tags.getListUserPopular
154
+ flickr.tags.getListUserRaw
155
+ flickr.tags.getRelated
156
+ flickr.test.echo
157
+ flickr.test.login
158
+ flickr.test.null
159
+ flickr.urls.getGroup
160
+ flickr.urls.getUserPhotos
161
+ flickr.urls.getUserProfile
162
+ flickr.urls.lookupGroup
163
+ flickr.urls.lookupUser
28
164
  }
165
+ found_methods = flickr.reflection.getMethods
166
+ assert_instance_of FlickRaw::ResponseList, found_methods
167
+ assert_equal known_methods, found_methods.to_a
29
168
  end
30
-
31
- def test_photos
169
+
170
+ def test_list
32
171
  list = flickr.photos.getRecent :per_page => '10'
33
- assert_instance_of Array, list
172
+ assert_instance_of FlickRaw::ResponseList, list
34
173
  assert_equal(list.size, 10)
174
+ end
175
+
176
+ def people(user)
177
+ assert_equal "41650587@N02", user.id
178
+ assert_equal "41650587@N02", user.nsid
179
+ assert_equal "ruby_flickraw", user.username
180
+ end
181
+
182
+ def photo(info)
183
+ assert_equal "3839885270", info.id
184
+ assert_equal "41650587@N02", info.owner
185
+ assert_equal "6fb8b54e06", info.secret
186
+ assert_equal "2485", info.server
187
+ assert_equal 3, info.farm
188
+ assert_equal "cat", info.title
189
+ assert_equal 1, info.ispublic
190
+ end
35
191
 
36
- id = secret = info = nil
37
- assert_nothing_raised(NoMethodError) {
38
- id = list[0].id
39
- secret = list[0].secret
40
- }
192
+ # favorites
193
+ def test_favorites_getPublicList
194
+ list = flickr.favorites.getPublicList :user_id => "41650587@N02"
195
+ assert_equal 1, list.size
196
+ assert_equal "3829093290", list[0].id
197
+ end
198
+
199
+ # groups
200
+ def test_groups_getInfo
201
+ info = flickr.groups.getInfo :group_id => "51035612836@N01"
202
+ assert_equal "51035612836@N01", info.id
203
+ assert_equal "Flickr API", info.name
204
+ end
205
+
206
+ def test_groups_search
207
+ list = flickr.groups.search :text => "Flickr API"
208
+ assert list.any? {|g| g.nsid == "51035612836@N01"}
209
+ end
210
+
211
+ # panda
212
+ def test_panda_getList
213
+ pandas = flickr.panda.getList
214
+ assert_equal ["ling ling", "hsing hsing", "wang wang"], pandas.to_a
215
+ end
216
+
217
+ def test_panda_getList
218
+ pandas = flickr.panda.getPhotos :panda_name => "wang wang"
219
+ assert_equal "wang wang", pandas.panda
220
+ assert_respond_to pandas[0], :title
221
+ end
222
+
223
+ # people
224
+ def test_people_findByEmail
225
+ user = flickr.people.findByEmail :find_email => "flickraw@yahoo.com"
226
+ people user
227
+ end
228
+
229
+ def test_people_findByUsername
230
+ user = flickr.people.findByUsername :username => "ruby_flickraw"
231
+ people user
232
+ end
233
+
234
+ def test_people_getInfo
235
+ user = flickr.people.getInfo :user_id => "41650587@N02"
236
+ people user
237
+ assert_equal "Flickraw", user.realname
238
+ assert_equal "http://www.flickr.com/photos/41650587@N02/", user.photosurl
239
+ assert_equal "http://www.flickr.com/people/41650587@N02/", user.profileurl
240
+ assert_equal "http://m.flickr.com/photostream.gne?id=41630239", user.mobileurl
241
+ assert_equal 0, user.ispro
242
+ end
243
+
244
+ def test_people_getPublicGroups
245
+ groups = flickr.people.getPublicGroups :user_id => "41650587@N02"
246
+ assert groups.to_a.empty?
247
+ end
248
+
249
+ def test_people_getPublicPhotos
250
+ info = flickr.people.getPublicPhotos :user_id => "41650587@N02"
251
+ assert_equal 1, info.size
252
+ assert_equal "1", info.total
253
+ assert_equal 1, info.pages
254
+ assert_equal 1, info.page
255
+ photo info[0]
256
+ end
257
+
258
+ # photos
259
+ def test_photos_getInfo
260
+ id = "3839885270"
261
+ info = nil
41
262
  assert_nothing_raised(FlickRaw::FailedResponse) {
42
- info = flickr.photos.getInfo :photo_id => id, :secret => secret
263
+ info = flickr.photos.getInfo(:photo_id => id)
264
+ }
265
+
266
+ %w{id secret server farm license owner title description dates comments tags media}.each {|m|
267
+ assert_respond_to info, m
268
+ assert_not_nil info[m]
43
269
  }
44
- assert_respond_to info, :id
45
- assert_respond_to info, :secret
46
- assert_respond_to info, :title
47
- assert_respond_to info, :description
48
- assert_respond_to info, :owner
49
- assert_respond_to info, :dates
50
- assert_respond_to info, :comments
51
- assert_respond_to info, :tags
270
+
271
+ assert_equal id, info.id
272
+ assert_equal "cat", info.title
273
+ assert_equal "This is my cat", info.description
274
+ assert_equal "ruby_flickraw", info.owner["username"]
275
+ assert_equal "Flickraw", info.owner["realname"]
276
+ assert_equal %w{cat pet}, info.tags.map {|t| t.to_s}.sort
277
+ end
278
+
279
+ def test_photos_getExif
280
+ info = flickr.photos.getExif :photo_id => "3839885270"
281
+ assert_equal "Canon DIGITAL IXUS 55", info.exif.find {|f| f.tag == "Model"}.raw
282
+ assert_equal "1/60", info.exif.find {|f| f.tag == "ExposureTime"}.raw
283
+ assert_equal "4.9", info.exif.find {|f| f.tag == "FNumber"}.raw
284
+ assert_equal "1600", info.exif.find {|f| f.tag == "ImageWidth"}.raw
285
+ assert_equal "1200", info.exif.find {|f| f.tag == "ImageHeight"}.raw
286
+ end
287
+
288
+ def test_photos_getSizes
289
+ info = flickr.photos.getSizes :photo_id => "3839885270"
290
+ assert_equal "http://www.flickr.com/photos/41650587@N02/3839885270/sizes/l/", info.find {|f| f.label == "Large"}.url
291
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06_b.jpg", info.find {|f| f.label == "Large"}.source
292
+ end
293
+
294
+ def test_photos_search
295
+ info = flickr.photos.search :user_id => "41650587@N02"
296
+ photo info[0]
297
+ end
298
+
299
+ # photos.comments
300
+ def test_photos_comments_getList
301
+ comments = flickr.photos.comments.getList :photo_id => "3839885270"
302
+ assert_equal 1, comments.size
303
+ assert_equal "3839885270", comments.photo_id
304
+ assert_equal "41630239-3839885270-72157621986549875", comments[0].id
305
+ assert_equal "41650587@N02", comments[0].author
306
+ assert_equal "ruby_flickraw", comments[0].authorname
307
+ assert_equal "http://www.flickr.com/photos/41650587@N02/3839885270/#comment72157621986549875", comments[0].permalink
308
+ assert_equal "This is a cute cat !", comments[0].to_s
309
+ end
310
+
311
+ # tags
312
+ def test_tags_getListPhoto
313
+ tags = flickr.tags.getListPhoto :photo_id => "3839885270"
314
+ assert_equal 2, tags.tags.size
315
+ assert_equal "3839885270", tags.id
316
+ assert_equal %w{cat pet}, tags.tags.map {|t| t.to_s}.sort
317
+ end
318
+
319
+ def test_tags_getListUser
320
+ tags = flickr.tags.getListUser :user_id => "41650587@N02"
321
+ assert_equal "41650587@N02", tags.id
322
+ assert_equal %w{cat pet}, tags.tags.sort
323
+ end
324
+
325
+ # urls
326
+ def test_urls_getGroup
327
+ info = flickr.urls.getGroup :group_id => "51035612836@N01"
328
+ assert_equal "51035612836@N01", info.nsid
329
+ assert_equal "http://www.flickr.com/groups/api/", info.url
330
+ end
331
+
332
+ def test_urls_getUserPhotos
333
+ info = flickr.urls.getUserPhotos :user_id => "41650587@N02"
334
+ assert_equal "41650587@N02", info.nsid
335
+ assert_equal "http://www.flickr.com/photos/41650587@N02/", info.url
336
+ end
337
+
338
+ def test_urls_getUserProfile
339
+ info = flickr.urls.getUserProfile :user_id => "41650587@N02"
340
+ assert_equal "41650587@N02", info.nsid
341
+ assert_equal "http://www.flickr.com/people/41650587@N02/", info.url
342
+ end
343
+
344
+ def test_urls_lookupGroup
345
+ info = flickr.urls.lookupGroup :url => "http://www.flickr.com/groups/api/"
346
+ assert_equal "51035612836@N01", info.id
347
+ assert_equal "Flickr API", info.groupname
348
+ end
349
+
350
+ def test_urls_lookupUser
351
+ info = flickr.urls.lookupUser :url => "http://www.flickr.com/photos/41650587@N02/"
352
+ assert_equal "41650587@N02", info.id
353
+ assert_equal "ruby_flickraw", info.username
354
+ end
355
+
356
+ def test_urls
357
+ id = "3839885270"
358
+ info = flickr.photos.getInfo(:photo_id => id)
359
+
360
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06.jpg", FlickRaw.url(info)
361
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06_m.jpg", FlickRaw.url_m(info)
362
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06_s.jpg", FlickRaw.url_s(info)
363
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06_t.jpg", FlickRaw.url_t(info)
364
+ assert_equal "http://farm3.static.flickr.com/2485/3839885270_6fb8b54e06_b.jpg", FlickRaw.url_b(info)
365
+
366
+ assert_equal "http://www.flickr.com/people/41650587@N02/", FlickRaw.url_profile(info)
367
+ assert_equal "http://www.flickr.com/photos/41650587@N02/", FlickRaw.url_photostream(info)
368
+ assert_equal "http://www.flickr.com/photos/41650587@N02/3839885270", FlickRaw.url_photopage(info)
369
+ assert_equal "http://www.flickr.com/photos/41650587@N02/sets/", FlickRaw.url_photosets(info)
370
+ assert_equal "http://flic.kr/p/6Rjq7s", FlickRaw.url_short(info)
52
371
  end
53
372
 
54
373
  def test_url_escape
@@ -64,6 +383,6 @@ class Basic < Test::Unit::TestCase
64
383
  assert_nothing_raised {
65
384
  echo = flickr.test.echo :utf8_text => utf8_text
66
385
  }
67
- assert_equal u(echo.utf8_text), utf8_text
386
+ assert_equal echo.utf8_text, utf8_text
68
387
  end
69
388
  end
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'test/unit'
4
+ require 'lib/flickraw'
5
+
6
+ # FlickRaw.shared_secret = # Shared secret
7
+ # flickr.auth.checkToken :auth_token => # Auth token
8
+
9
+ class Upload < Test::Unit::TestCase
10
+ def test_upload
11
+
12
+ path = File.dirname(__FILE__) + '/image testée.jpg'
13
+ u = info = nil
14
+ title = "Titre de l'image testée"
15
+ description = "Ceci est la description de l'image testée"
16
+ assert_nothing_raised {
17
+ u = flickr.upload_photo path,
18
+ :title => title,
19
+ :description => description
20
+ }
21
+
22
+ assert_nothing_raised {
23
+ info = flickr.photos.getInfo :photo_id => u.to_s
24
+ }
25
+
26
+ assert_equal title, info.title
27
+ assert_equal description, info.description
28
+
29
+ assert_nothing_raised {flickr.photos.delete :photo_id => u.to_s}
30
+ end
31
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flickraw
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: "0.8"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mael Clerambault
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-08 00:00:00 +02:00
12
+ date: 2010-01-03 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -27,13 +27,16 @@ files:
27
27
  - LICENSE
28
28
  - README.rdoc
29
29
  - rakefile
30
- - examples/flickr_KDE.rb
31
- - examples/upload.rb
32
30
  - examples/auth.rb
31
+ - examples/flickr_KDE.rb
33
32
  - examples/interestingness.rb
33
+ - examples/upload.rb
34
+ - test/test_upload.rb
34
35
  - test/test.rb
35
- has_rdoc: false
36
+ has_rdoc: true
36
37
  homepage: http://hanklords.github.com/flickraw/
38
+ licenses: []
39
+
37
40
  post_install_message:
38
41
  rdoc_options: []
39
42
 
@@ -54,9 +57,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
57
  requirements: []
55
58
 
56
59
  rubyforge_project: flickraw
57
- rubygems_version: 1.3.1
60
+ rubygems_version: 1.3.5
58
61
  signing_key:
59
- specification_version: 2
62
+ specification_version: 3
60
63
  summary: Flickr library with a syntax close to the syntax described on http://www.flickr.com/services/api
61
- test_files:
62
- - test/test.rb
64
+ test_files: []
65
+