benschwarz-flickraw 0.5.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README +44 -0
  2. data/copying.txt +20 -0
  3. data/flickraw_rdoc.rb +147 -0
  4. data/lib/flickraw.rb +252 -0
  5. data/test/test.rb +67 -0
  6. metadata +66 -0
data/README ADDED
@@ -0,0 +1,44 @@
1
+ = Flickraw
2
+
3
+ Flickraw is a library to access flickr[http://flickr.com] api in a simple way.
4
+ It maps exactly the methods described in {the official api documentation}[http://www.flickr.com/services/api].
5
+ It also try to present the data returned in a simple and intuitive way.
6
+ The methods are fetched from flickr when loading the library by using introspection capabilities. So it is always up-to-date with regards to new methods added by flickr.
7
+
8
+ You can read the class documentation here : FlickRaw.
9
+
10
+ The rubyforge project : http://rubyforge.org/projects/flickraw
11
+
12
+ = Installation
13
+ Type this in a console (you might need to be superuser)
14
+ gem install flickraw
15
+
16
+ You can recreate this documentation by typing this in the source directory:
17
+ rake rdoc
18
+
19
+ = Usage
20
+
21
+ require 'flickraw'
22
+
23
+ list = flickr.photos.getRecent
24
+
25
+ id = list[0].id
26
+ secret = list[0].secret
27
+ info = flickr.photos.getInfo :photo_id => id, :secret => secret
28
+
29
+ info.title # => "PICT986"
30
+ info.dates.taken # => "2006-07-06 15:16:18"
31
+
32
+
33
+ sizes = flickr.photos.getSizes :photo_id => id
34
+
35
+ original = sizes.find {|s| s.label == 'Original' }
36
+ original.width # => "800"
37
+
38
+ See the _examples_ directory to find more examples.
39
+
40
+ = Notes
41
+ If you want to use the api authenticated with several user at the same time, you must pass the authentication token explicitely each time.
42
+ This is because it is keeping the authentication token internally.
43
+ As an alternative, you can create new Flickr objects besides Object.flickr which is created for you. Use Flickr.new to this effect.
44
+
data/copying.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006 Hank Lords <hanklords@gmail.com>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/flickraw_rdoc.rb ADDED
@@ -0,0 +1,147 @@
1
+ require "rdoc/parsers/parserfactory"
2
+ require "rdoc/parsers/parse_rb"
3
+
4
+ FLICKR_API_URL='http://www.flickr.com/services/api'
5
+
6
+ FakedToken = Struct.new :text
7
+
8
+ module RDoc
9
+ class FlickrawParser < RubyParser
10
+ extend ParserFactory
11
+ parse_files_matching(/flickraw\.rb$/)
12
+
13
+ def scan
14
+ super
15
+
16
+ fr = @top_level.find_module_named 'FlickRaw'
17
+ k = fr.add_class NormalClass, 'Flickr', 'FlickRaw::Request'
18
+ k.record_location @top_level
19
+ @stats.num_classes += 1
20
+
21
+ add_flickr_methods(FlickRaw::Flickr, k)
22
+ @top_level
23
+ end
24
+
25
+ private
26
+ def add_flickr_methods(obj, doc)
27
+ obj.constants.each { |const_name|
28
+ const = obj.const_get const_name
29
+ if const.is_a?(Class) && const < FlickRaw::Request
30
+ name = const.name.sub(/.*::/, '')
31
+ k = doc.add_class NormalClass, name, 'FlickRaw::Request'
32
+ k.record_location @top_level
33
+ @stats.num_classes += 1
34
+
35
+ m = AnyMethod.new nil, name.downcase
36
+ m.comment = "Returns a #{name} object."
37
+ m.params = ''
38
+ m.singleton = false
39
+ doc.add_method m
40
+
41
+ progress("c")
42
+ @stats.num_methods += 1
43
+
44
+ add_flickr_methods(const, k)
45
+ end
46
+ }
47
+
48
+ obj.flickr_methods.each {|name|
49
+ flickr_method = obj.request_name + '.' + name
50
+ info = flickr.reflection.getMethodInfo :method_name => flickr_method
51
+
52
+ m = AnyMethod.new nil, name
53
+ m.comment = flickr_method_comment(info)
54
+ m.params = flickr_method_args(info)
55
+ m.singleton = false
56
+
57
+ m.start_collecting_tokens
58
+ m.add_token FakedToken.new( %{
59
+ # Generated automatically from flickr api
60
+ def #{name}(*args)
61
+ @flickr.call '#{flickr_method}', *args
62
+ end
63
+ } )
64
+ doc.add_method m
65
+ progress(".")
66
+ @stats.num_methods += 1
67
+ }
68
+ end
69
+
70
+ def flickr_method_comment(info)
71
+ description = unescapeHTML(info.method.description.to_s)
72
+ # description.gsub!( /<\/?(\w+)>/ ) {|b|
73
+ # return b if ['em', 'b', 'tt'].include? $1
74
+ # return ''
75
+ # }
76
+
77
+ if info.respond_to? :arguments
78
+ args = info.arguments.select { |arg| arg.name != 'api_key' }
79
+
80
+ arguments = "<b>Arguments</b>\n"
81
+ if args.size > 0
82
+ args.each {|arg|
83
+ arguments << "[#{arg.name} "
84
+ arguments << "<em>(required)</em> " if arg.optional == '0'
85
+ arguments << "] "
86
+ arguments << "#{unescapeHTML(arg.to_s)}\n"
87
+ }
88
+ end
89
+ end
90
+
91
+ if info.respond_to? :errors
92
+ errors = "<b>Error codes</b>\n"
93
+ info.errors.each {|e|
94
+ errors << "* #{e.code}: <em>#{e.message}</em>\n\n"
95
+ errors << " #{unescapeHTML e.to_s}\n"
96
+ }
97
+ end
98
+
99
+ if info.method.respond_to? :response
100
+ response = "<b>Returns</b>\n"
101
+ raw = unescapeHTML(info.method.response.to_s)
102
+ response << raw.collect { |line| line.insert(0, ' ') }.join
103
+ else
104
+ response = ''
105
+ end
106
+
107
+ str = "{#{info.method.name}}[#{FLICKR_API_URL}/#{info.method.name}.html] request.\n\n"
108
+ str << description << "\n\n"
109
+ str << arguments << "\n\n"
110
+ str << errors << "\n\n"
111
+ str << response << "\n\n"
112
+ end
113
+
114
+ def flickr_method_args(info)
115
+ str = ''
116
+ if info.respond_to? :arguments
117
+ args = info.arguments.select { |arg| arg.name != 'api_key' }
118
+
119
+ if args.size > 0
120
+ str << '('
121
+ args.each {|arg|
122
+ str << ":#{arg.name} => '#{arg.name}'"
123
+ str << ','
124
+ }
125
+ str.chomp! ','
126
+ str << ')'
127
+ end
128
+ end
129
+ str
130
+ end
131
+
132
+ def unescapeHTML(string)
133
+ string.gsub!('\/', '/')
134
+ string.gsub(/&(.*?);/n) do
135
+ match = $1.dup
136
+ case match
137
+ when /\Aamp\z/ni then '&'
138
+ when /\Aquot\z/ni then '"'
139
+ when /\Agt\z/ni then '>'
140
+ when /\Alt\z/ni then '<'
141
+ when /\Anbsp\z/ni then ' '
142
+ else "&#{match};"
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
data/lib/flickraw.rb ADDED
@@ -0,0 +1,252 @@
1
+ # Copyright (c) 2006 Mael Clerambault <maelclerambault@yahoo.fr>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ begin
23
+ require 'minigems'
24
+ rescue LoadError
25
+ require 'rubygems'
26
+ end
27
+ require 'net/http'
28
+ require 'open-uri'
29
+ require 'md5'
30
+ require 'json'
31
+ require 'cgi'
32
+
33
+ module FlickRaw
34
+ VERSION='0.5.1.1'
35
+
36
+ FLICKR_HOST='http://api.flickr.com'.freeze
37
+
38
+ # Path of flickr REST API
39
+ REST_PATH='/services/rest/?'.freeze
40
+
41
+ # Path of flickr auth page
42
+ AUTH_PATH='/services/auth/?'.freeze
43
+
44
+ # Path of flickr upload
45
+ UPLOAD_PATH='/services/upload/'.freeze
46
+
47
+ @api_key = '7b124df89b638e545e3165293883ef62'
48
+
49
+ module SimpleOStruct # :nodoc:
50
+ def __attr_define(k,v)
51
+ instance_variable_set "@#{k}", v
52
+ meta = class << self; self; end
53
+ meta.class_eval { attr_reader k.to_s }
54
+ end
55
+ end
56
+
57
+ class Response # :nodoc:
58
+ include SimpleOStruct
59
+ def initialize(h)
60
+ h.each {|k, v| __attr_define k, Response.structify(v, k) }
61
+ end
62
+
63
+ def self.structify(obj, name = '')
64
+ if obj.is_a? Hash
65
+ if name =~ /s$/ and obj[$`].is_a? Array
66
+ list = structify obj.delete($`)
67
+ list.extend SimpleOStruct
68
+ list.instance_eval { obj.each {|kv, vv| __attr_define kv, vv } }
69
+ list
70
+ elsif obj.keys == ['_content']
71
+ obj['_content'].to_s
72
+ else
73
+ Response.new obj
74
+ end
75
+ elsif obj.is_a? Array
76
+ obj.collect {|e| structify e}
77
+ else
78
+ obj
79
+ end
80
+ end
81
+
82
+ def to_s; @_content || super end
83
+ end
84
+
85
+ class FailedResponse < StandardError
86
+ attr_reader :code
87
+ alias :msg :message
88
+ def initialize(msg, code, req)
89
+ @code = code
90
+ super("'#{req}' - #{msg}")
91
+ end
92
+ end
93
+
94
+ class Request
95
+ def initialize(flickr = nil) # :nodoc:
96
+ @flickr = flickr
97
+
98
+ self.class.flickr_objects.each {|name|
99
+ klass = self.class.const_get name.capitalize
100
+ instance_variable_set "@#{name}", klass.new(@flickr)
101
+ }
102
+ end
103
+
104
+ def self.build_request(req) # :nodoc:
105
+ method_nesting = req.split '.'
106
+ raise "'#{@name}' : Method name mismatch" if method_nesting.shift != request_name.split('.').last
107
+
108
+ if method_nesting.size > 1
109
+ name = method_nesting.first
110
+ class_name = name.capitalize
111
+ if const_defined? class_name
112
+ klass = const_get( class_name)
113
+ else
114
+ klass = Class.new Request
115
+ const_set(class_name, klass)
116
+ attr_reader name
117
+ flickr_objects << name
118
+ end
119
+
120
+ klass.build_request method_nesting.join('.')
121
+ else
122
+ req = method_nesting.first
123
+ define_method(req) { |*args|
124
+ class_req = self.class.request_name
125
+ @flickr.call class_req + '.' + req, *args
126
+ }
127
+ flickr_methods << req
128
+ end
129
+ end
130
+
131
+ # List of the flickr subobjects of this object
132
+ def self.flickr_objects; @flickr_objects ||= [] end
133
+
134
+ # List of the flickr methods of this object
135
+ def self.flickr_methods; @flickr_methods ||= [] end
136
+
137
+ # Returns the prefix of the request corresponding to this class.
138
+ def self.request_name; name.downcase.gsub(/::/, '.').sub(/[^\.]+\./, '') end
139
+ end
140
+
141
+ # Root class of the flickr api hierarchy.
142
+ class Flickr < Request
143
+ def initialize # :nodoc:
144
+ super self
145
+ @token = nil
146
+ end
147
+
148
+ # This is the central method. It does the actual request to the flickr server.
149
+ #
150
+ # Raises FailedResponse if the response status is _failed_.
151
+ def call(req, args={})
152
+ path = REST_PATH + build_args(args, req).collect { |a, v| "#{a}=#{v}" }.join('&')
153
+ http_response = open(FLICKR_HOST + path).read #Net::HTTP.start(FLICKR_HOST) { |http| http.get(path, 'User-Agent' => "Flickraw/#{VERSION}") }
154
+ parse_response(http_response, req)
155
+ end
156
+
157
+ # Use this to upload the photo in _file_.
158
+ #
159
+ # flickr.upload_photo '/path/to/the/photo', :title => 'Title', :description => 'This is the description'
160
+ #
161
+ # See http://www.flickr.com/services/api/upload.api.html for more information on the arguments.
162
+ def upload_photo(file, args={})
163
+ photo = File.open(file, 'rb') { |f| f.read }
164
+ boundary = MD5.md5(photo).to_s
165
+
166
+ header = {'Content-type' => "multipart/form-data, boundary=#{boundary} ", 'User-Agent' => "Flickraw/#{VERSION}"}
167
+ query = ''
168
+ build_args(args).each { |a, v|
169
+ query <<
170
+ "--#{boundary}\r\n" <<
171
+ "Content-Disposition: form-data; name=\"#{a}\"\r\n\r\n" <<
172
+ "#{v}\r\n"
173
+ }
174
+ query <<
175
+ "--#{boundary}\r\n" <<
176
+ "Content-Disposition: form-data; name=\"photo\"; filename=\"#{file}\"\r\n" <<
177
+ "Content-Transfer-Encoding: binary\r\n" <<
178
+ "Content-Type: image/jpeg\r\n\r\n" <<
179
+ photo <<
180
+ "\r\n" <<
181
+ "--#{boundary}--"
182
+
183
+ http_response = Net::HTTP.start(FLICKR_HOST) { |http| http.post(UPLOAD_PATH, query, header) }
184
+ xml = http_response.body
185
+ if xml[/stat="(\w+)"/, 1] == 'fail'
186
+ msg = xml[/msg="([^"]+)"/, 1]
187
+ code = xml[/code="([^"]+)"/, 1]
188
+ raise FailedResponse.new(msg, code, 'flickr.upload')
189
+ end
190
+ Response.structify( {:stat => 'ok', :photoid => xml[/<photoid>(\w+)<\/photoid>/, 1], :ticketid => xml[/<ticketid>([^<]+)<\/ticketid>/, 1]})
191
+ end
192
+
193
+ private
194
+ def parse_response(response, req = nil)
195
+ json = JSON.load(response)
196
+ raise FailedResponse.new(json['message'], json['code'], req) if json.delete('stat') == 'fail'
197
+ name, json = json.to_a.first if json.size == 1
198
+
199
+ res = Response.structify json, name
200
+ lookup_token(req, res)
201
+ res
202
+ end
203
+
204
+ def build_args(args={}, req = nil)
205
+ full_args = {:api_key => FlickRaw.api_key, :format => 'json', :nojsoncallback => 1}
206
+ full_args[:method] = req if req
207
+ full_args[:auth_token] = @token if @token
208
+ args.each {|k, v| full_args[k.to_sym] = v.to_s }
209
+ full_args[:api_sig] = FlickRaw.api_sig(full_args) if FlickRaw.shared_secret
210
+ args.each {|k, v| full_args[k.to_sym] = CGI.escape(v.to_s) } if req
211
+ full_args
212
+ end
213
+
214
+ def lookup_token(req, res)
215
+ token_reqs = ['flickr.auth.getToken', 'flickr.auth.getFullToken', 'flickr.auth.checkToken']
216
+ @token = res.token if token_reqs.include?(req) and res.respond_to?(:token)
217
+ end
218
+ end
219
+
220
+ class << self
221
+ # Your flickr API key, see http://www.flickr.com/services/api/keys for more information
222
+ attr_accessor :api_key
223
+
224
+ # The shared secret of _api_key_, see http://www.flickr.com/services/api/keys for more information
225
+ attr_accessor :shared_secret
226
+
227
+ # Returns the flickr auth URL.
228
+ def auth_url(args={})
229
+ full_args = {:api_key => FlickRaw.api_key, :perms => 'read'}
230
+ args.each {|k, v| full_args[k.to_sym] = v }
231
+ full_args[:api_sig] = api_sig(full_args) if FlickRaw.shared_secret
232
+
233
+ FLICKR_HOST + AUTH_PATH + full_args.collect { |a, v| "#{a}=#{v}" }.join('&')
234
+ end
235
+
236
+ # Returns the signature of hsh. This is meant to be passed in the _api_sig_ parameter.
237
+ def api_sig(hsh)
238
+ MD5.md5(FlickRaw.shared_secret + hsh.sort{|a, b| a[0].to_s <=> b[0].to_s }.flatten.join).to_s
239
+ end
240
+ end
241
+
242
+ methods = Flickr.new.call 'flickr.reflection.getMethods'
243
+ methods.each { |method| Flickr.build_request method }
244
+ end
245
+
246
+ # Use this to access the flickr API easily. You can type directly the flickr requests as they are described on the flickr website.
247
+ # require 'flickraw'
248
+ #
249
+ # recent_photos = flickr.photos.getRecent
250
+ # puts recent_photos[0].title
251
+ def flickr; $flickraw ||= FlickRaw::Flickr.new end
252
+
data/test/test.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'test/unit'
2
+ require 'lib/flickraw'
3
+
4
+ # utf8 hack
5
+ def u(str)
6
+ str.gsub(/\\+u([0-9a-fA-F]{4,4})/u){["#$1".hex ].pack('U*')}
7
+ end
8
+
9
+ class Basic < Test::Unit::TestCase
10
+ def test_known
11
+ 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"]
12
+ found_methods = flickr.reflection.getMethods
13
+ assert_instance_of Array, found_methods
14
+ known_methods.each { |m| assert found_methods.include?(m), m}
15
+ end
16
+
17
+ def test_found
18
+ found_methods = flickr.reflection.getMethods
19
+ found_methods.each { |m|
20
+ assert_nothing_raised {
21
+ begin
22
+ eval m
23
+ rescue FlickRaw::FailedResponse
24
+ end
25
+ }
26
+ }
27
+ end
28
+
29
+ def test_photos
30
+ list = flickr.photos.getRecent :per_page => '10'
31
+ assert_instance_of Array, list
32
+ assert_equal(list.size, 10)
33
+
34
+ id = secret = info = nil
35
+ assert_nothing_raised(NoMethodError) {
36
+ id = list[0].id
37
+ secret = list[0].secret
38
+ }
39
+ assert_nothing_raised(FlickRaw::FailedResponse) {
40
+ info = flickr.photos.getInfo :photo_id => id, :secret => secret
41
+ }
42
+ assert_respond_to info, :id
43
+ assert_respond_to info, :secret
44
+ assert_respond_to info, :title
45
+ assert_respond_to info, :description
46
+ assert_respond_to info, :owner
47
+ assert_respond_to info, :dates
48
+ assert_respond_to info, :comments
49
+ assert_respond_to info, :tags
50
+ end
51
+
52
+ def test_url_escape
53
+ result_set = nil
54
+ assert_nothing_raised {
55
+ result_set = flickr.photos.search :text => "family vacation"
56
+ }
57
+ assert_operator result_set.total.to_i, :>=, 0
58
+
59
+ # Unicode tests
60
+ echo = nil
61
+ utf8_text = "Hélène François, €uro"
62
+ assert_nothing_raised {
63
+ echo = flickr.test.echo :utf8_text => utf8_text
64
+ }
65
+ assert_equal u(echo.utf8_text), utf8_text
66
+ end
67
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: benschwarz-flickraw
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Mael Clerambault
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-12-22 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description:
25
+ email: maelclerambault@yahoo.fr
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/flickraw.rb
34
+ - flickraw_rdoc.rb
35
+ - copying.txt
36
+ - README
37
+ - Rakefile
38
+ - test/test.rb
39
+ has_rdoc: false
40
+ homepage: http://flickraw.rubyforge.org
41
+ post_install_message:
42
+ rdoc_options: []
43
+
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ requirements: []
59
+
60
+ rubyforge_project: flickraw
61
+ rubygems_version: 1.2.0
62
+ signing_key:
63
+ specification_version: 2
64
+ summary: Flickr library with a syntax close to the syntax described on http://www.flickr.com/services/api
65
+ test_files: []
66
+