flickraw 0.7.1 → 0.8
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/LICENSE +1 -1
- data/README.rdoc +82 -1
- data/lib/flickraw.rb +136 -91
- data/test/test.rb +357 -38
- data/test/test_upload.rb +31 -0
- metadata +12 -9
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -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
|
-
|
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
|
data/lib/flickraw.rb
CHANGED
@@ -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
|
-
|
29
|
-
|
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
|
-
|
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.
|
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
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
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
|
-
|
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 =
|
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
|
-
|
157
|
-
|
158
|
-
|
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(
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
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
|
-
|
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
|
-
|
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 =>
|
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
|
262
|
+
full_args[:api_sig] = api_sig(full_args) if shared_secret
|
243
263
|
|
244
|
-
|
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
|
307
|
+
flickr if not FlickRawOptions['lazyload']
|
data/test/test.rb
CHANGED
@@ -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
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
169
|
+
|
170
|
+
def test_list
|
32
171
|
list = flickr.photos.getRecent :per_page => '10'
|
33
|
-
assert_instance_of
|
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
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
386
|
+
assert_equal echo.utf8_text, utf8_text
|
68
387
|
end
|
69
388
|
end
|
data/test/test_upload.rb
ADDED
@@ -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.
|
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:
|
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:
|
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.
|
60
|
+
rubygems_version: 1.3.5
|
58
61
|
signing_key:
|
59
|
-
specification_version:
|
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
|
-
|
64
|
+
test_files: []
|
65
|
+
|