mwilliams-fleakr 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. data/README.rdoc +350 -0
  2. data/Rakefile +41 -0
  3. data/lib/fleakr/api/file_parameter.rb +47 -0
  4. data/lib/fleakr/api/method_request.rb +66 -0
  5. data/lib/fleakr/api/option.rb +175 -0
  6. data/lib/fleakr/api/parameter.rb +35 -0
  7. data/lib/fleakr/api/parameter_list.rb +97 -0
  8. data/lib/fleakr/api/response.rb +35 -0
  9. data/lib/fleakr/api/upload_request.rb +75 -0
  10. data/lib/fleakr/api/value_parameter.rb +36 -0
  11. data/lib/fleakr/api.rb +8 -0
  12. data/lib/fleakr/core_ext/false_class.rb +7 -0
  13. data/lib/fleakr/core_ext/hash.rb +22 -0
  14. data/lib/fleakr/core_ext/true_class.rb +7 -0
  15. data/lib/fleakr/core_ext.rb +3 -0
  16. data/lib/fleakr/objects/authentication_token.rb +60 -0
  17. data/lib/fleakr/objects/comment.rb +49 -0
  18. data/lib/fleakr/objects/contact.rb +31 -0
  19. data/lib/fleakr/objects/error.rb +22 -0
  20. data/lib/fleakr/objects/group.rb +36 -0
  21. data/lib/fleakr/objects/image.rb +50 -0
  22. data/lib/fleakr/objects/photo.rb +147 -0
  23. data/lib/fleakr/objects/photo_context.rb +49 -0
  24. data/lib/fleakr/objects/search.rb +30 -0
  25. data/lib/fleakr/objects/set.rb +50 -0
  26. data/lib/fleakr/objects/tag.rb +56 -0
  27. data/lib/fleakr/objects/user.rb +95 -0
  28. data/lib/fleakr/objects.rb +12 -0
  29. data/lib/fleakr/support/attribute.rb +46 -0
  30. data/lib/fleakr/support/object.rb +110 -0
  31. data/lib/fleakr/support.rb +2 -0
  32. data/lib/fleakr/version.rb +13 -0
  33. data/lib/fleakr.rb +164 -0
  34. data/test/fixtures/auth.checkToken.xml +8 -0
  35. data/test/fixtures/auth.getFullToken.xml +8 -0
  36. data/test/fixtures/auth.getToken.xml +8 -0
  37. data/test/fixtures/contacts.getPublicList.xml +7 -0
  38. data/test/fixtures/groups.pools.getPhotos.xml +7 -0
  39. data/test/fixtures/people.findByEmail.xml +6 -0
  40. data/test/fixtures/people.findByUsername.xml +6 -0
  41. data/test/fixtures/people.getInfo.xml +18 -0
  42. data/test/fixtures/people.getPublicGroups.xml +7 -0
  43. data/test/fixtures/people.getPublicPhotos.xml +7 -0
  44. data/test/fixtures/photos.comments.getList.xml +7 -0
  45. data/test/fixtures/photos.getContext.xml +6 -0
  46. data/test/fixtures/photos.getInfo.xml +20 -0
  47. data/test/fixtures/photos.getSizes.xml +10 -0
  48. data/test/fixtures/photos.search.xml +7 -0
  49. data/test/fixtures/photosets.comments.getList.xml +7 -0
  50. data/test/fixtures/photosets.getList.xml +13 -0
  51. data/test/fixtures/photosets.getPhotos.xml +7 -0
  52. data/test/fixtures/tags.getListPhoto.xml +9 -0
  53. data/test/fixtures/tags.getListUser.xml +10 -0
  54. data/test/fixtures/tags.getRelated.xml +9 -0
  55. data/test/test_helper.rb +141 -0
  56. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  57. data/test/unit/fleakr/api/method_request_test.rb +94 -0
  58. data/test/unit/fleakr/api/option_test.rb +179 -0
  59. data/test/unit/fleakr/api/parameter_list_test.rb +176 -0
  60. data/test/unit/fleakr/api/parameter_test.rb +34 -0
  61. data/test/unit/fleakr/api/response_test.rb +49 -0
  62. data/test/unit/fleakr/api/upload_request_test.rb +149 -0
  63. data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
  64. data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
  65. data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
  66. data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
  67. data/test/unit/fleakr/objects/authentication_token_test.rb +61 -0
  68. data/test/unit/fleakr/objects/comment_test.rb +66 -0
  69. data/test/unit/fleakr/objects/contact_test.rb +61 -0
  70. data/test/unit/fleakr/objects/error_test.rb +21 -0
  71. data/test/unit/fleakr/objects/group_test.rb +46 -0
  72. data/test/unit/fleakr/objects/image_test.rb +81 -0
  73. data/test/unit/fleakr/objects/photo_context_test.rb +80 -0
  74. data/test/unit/fleakr/objects/photo_test.rb +246 -0
  75. data/test/unit/fleakr/objects/search_test.rb +74 -0
  76. data/test/unit/fleakr/objects/set_test.rb +82 -0
  77. data/test/unit/fleakr/objects/tag_test.rb +98 -0
  78. data/test/unit/fleakr/objects/user_test.rb +91 -0
  79. data/test/unit/fleakr/support/attribute_test.rb +126 -0
  80. data/test/unit/fleakr/support/object_test.rb +129 -0
  81. data/test/unit/fleakr_test.rb +171 -0
  82. metadata +175 -0
data/README.rdoc ADDED
@@ -0,0 +1,350 @@
1
+ = Fleakr
2
+
3
+ == Description
4
+
5
+ A small, yet powerful, gem to interface with Flickr photostreams
6
+
7
+ == Installation
8
+
9
+ === Stable
10
+
11
+ sudo gem install fleakr
12
+
13
+ === Bleeding Edge
14
+
15
+ sudo gem install reagent-fleakr --source=http://gems.github.com
16
+
17
+ Or ...
18
+
19
+ $ git clone git://github.com/reagent/fleakr.git
20
+ $ cd fleakr
21
+ $ rake gem && sudo gem install pkg/fleakr-<version>.gem
22
+
23
+ == Usage
24
+
25
+ To get started, you'll need to grab an API key from Flickr to at least perform any of
26
+ the non-authenticated, read-only calls. Head on over to the Flickr site to grab one, I'll
27
+ be here when you get back: http://www.flickr.com/services/api/misc.api_keys.html
28
+
29
+ Now that you have your key, you can get things rolling with irb and the fleakr gem:
30
+
31
+ $ irb -r rubygems
32
+ >> require 'fleakr'
33
+
34
+ Then, set your API key (only need to do this once per session):
35
+
36
+ >> Fleakr.api_key = '<your api key here>'
37
+
38
+ === A Brief Tour
39
+
40
+ With just an API key, you have the ability to retrieve a substantial amount of data
41
+ about users, their photosets, photos, contacts, and groups. Let's start by finding a
42
+ user by his username:
43
+
44
+ >> user = Fleakr.user('the decapitator')
45
+ => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
46
+
47
+ Or by email:
48
+
49
+ >> user = Fleakr.user('user@host.com')
50
+ => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
51
+
52
+ Once you have a user, you can find his associated sets:
53
+
54
+ >> user.sets
55
+ => [#<Fleakr::Objects::Set:0x671358 @title="The Decapitator", @description="">,
56
+ #<Fleakr::Objects::Set:0x66d898 @title="londonpaper hijack", ...
57
+
58
+ His individual photos:
59
+
60
+ >> user.photos.first
61
+ => #<Fleakr::Objects::Photo:0x161b024 @title="\"Be Fabulous\"" ... >
62
+
63
+ Or contacts:
64
+
65
+ >> user.contacts.first
66
+ => #<Fleakr::Objects::User:0x19039bc @username=".schill",
67
+ @id="12289718@N00", @icon_farm="1", @icon_server="4">
68
+
69
+ Or his groups if you would like:
70
+
71
+ >> user.groups
72
+ => [#<Fleakr::Objects::Group:0x11f2330 ...,
73
+ #<Fleakr::Objects::Group:0x11f2308 ...
74
+ >> user.groups.first.name
75
+ => "Rural Decay"
76
+ >> user.groups.first.id
77
+ => "14581414@N00"
78
+
79
+ Groups also contain photos:
80
+
81
+ >> user.groups.last.photos.first.title
82
+ => "Welcome To The Machine"
83
+
84
+ When accessing a set, you can also grab all the photos that are in that set:
85
+
86
+ >> user.sets.first
87
+ => #<Fleakr::Objects::Set:0x1195bbc @title="The Decapitator", @id="72157603480986566", @description="">
88
+ >> user.sets.first.photos.first
89
+ => #<Fleakr::Objects::Photo:0x1140108 ... >
90
+ >> user.sets.first.photos.first.title
91
+ => "Untitled1"
92
+
93
+ === Photos
94
+
95
+ Each photo object contains metadata about a collection of images, each representing different
96
+ sizes. Once we have a single photo:
97
+
98
+ >> photo = user.photos.first
99
+ => #<Fleakr::Objects::Photo:0x161b024 @title="\"Be Fabulous\"" ... >
100
+
101
+ We can get information about one of the sizes:
102
+
103
+ >> photo.small
104
+ => #<Fleakr::Objects::Image:0x1768f1c @height="172", @size="Small", @width="240",
105
+ @url="http://farm4.static.flickr.com/3250/2924549350_cbc1804258_m.jpg",
106
+ @page="http://www.flickr.com/photos/the_decapitator/2924549350/sizes/s/">
107
+
108
+ Grab the URL for the image itself:
109
+
110
+ >> photo.small.url
111
+ => "http://farm4.static.flickr.com/3250/2924549350_cbc1804258_m.jpg"
112
+
113
+ Or grab the URL for its page on the Flickr site:
114
+
115
+ >> photo.small.page
116
+ => "http://www.flickr.com/photos/the_decapitator/2924549350/sizes/s/"
117
+
118
+ Other sizes are available (:square, :thumbnail, :small, :medium, :large, :original) and
119
+ are accessed in the same way:
120
+
121
+ >> photo.original.url
122
+ => "http://farm4.static.flickr.com/3250/2924549350_1cf67c2d47_o.jpg"
123
+
124
+ === Tags
125
+
126
+ Tags are available for users and photos. Retrieving them is easy:
127
+
128
+ >> user = Fleakr.user('the decapitator')
129
+ >> user.tags
130
+ => [#<Fleakr::Objects::Tag:0x190d5fc @value="ad">,
131
+ #<Fleakr::Objects::Tag:0x1908a20 @value="ads">, ...
132
+ >> user.photos.first.tags
133
+ => [#<Fleakr::Objects::Tag:0x17b1b18 @machine_flag="0", @author_id="21775151@N06", ...
134
+
135
+ All tags have values, but for tags associated with photos there is some additional information:
136
+
137
+ >> tag = user.photos.first.tags.first
138
+ >> tag.id
139
+ => "21729829-3263659141-427098"
140
+ >> tag.raw
141
+ => "decapitator"
142
+ >> tag.value
143
+ => "decapitator"
144
+ >> tag.to_s
145
+ => "decapitator"
146
+ >> tag.machine?
147
+ => false
148
+ >> tag.author
149
+ => #<Fleakr::Objects::User:0x1a149f0 @username="the decapitator", ... >
150
+
151
+ Each tag can also have related tags:
152
+
153
+ >> user.photos.first.tags[1].related.first.related.first.to_s
154
+ => "face"
155
+
156
+ You get the idea - see Fleakr::Objects::Tag for more information.
157
+
158
+ === Comments
159
+
160
+ Similar to tags, photosets and photos can each have comments:
161
+
162
+ >> user.sets.first.comments
163
+ => [#<Fleakr::Objects::Comment:0x19795cc ...
164
+ >> user.photos.first.comments
165
+ => [#<Fleakr::Objects::Comment:0x17bf0b0 @body="Dayum, that's some wishful thinking!" ...
166
+
167
+ All comments have additional information:
168
+
169
+ >> comment = user.photos.first.comments.first
170
+ >> comment.id
171
+ => "21729829-3263659141-72157613553885978"
172
+ >> comment.body
173
+ => "Dayum, that's some wishful thinking!"
174
+ >> comment.to_s
175
+ => "Dayum, that's some wishful thinking!"
176
+ >> comment.url
177
+ => "http://www.flickr.com/photos/the_decapitator/3263659141/#comment72157613553885978"
178
+ >> comment.author
179
+ => #<Fleakr::Objects::User:0x178e3d4 @username="jaspertandy", ... >
180
+
181
+ See Fleakr::Objects::Comment for more information.
182
+
183
+ === Saving Images
184
+
185
+ If a photo interests you, save it down to a directory of your choosing:
186
+
187
+ >> photo.original.save_to('/tmp')
188
+ => #<File:/tmp/2924549350_1cf67c2d47_o.jpg (closed)>
189
+
190
+ Similarly, you can save down entire sets. Just specify the target directory and the size
191
+ of the images you're interested in:
192
+
193
+ >> user.sets.first.save_to('/tmp', :square)
194
+ => [#<Fleakr::Objects::Photo:0x1187a1c @secret="715587b2cb" ...
195
+
196
+ This creates a subdirectory within the target directory based on the set's name and preserves
197
+ the original order of the photos:
198
+
199
+ >> Dir["/tmp/#{user.sets.first.title}/*.jpg"].map
200
+ => ["/tmp/The Decapitator/01_2117922283_715587b2cb_s.jpg",
201
+ "/tmp/The Decapitator/02_2125604584_9c09348fd6_s.jpg",
202
+ "/tmp/The Decapitator/03_2118696542_8af5763bde_s.jpg", ... ]
203
+
204
+ === Searching
205
+
206
+ If you would prefer to just search photos, you can do that with search text:
207
+
208
+ >> photos = Fleakr.search('ponies!!')
209
+ => [#<Fleakr::Objects::Photo:0x11f4e64 @title="hiroshima atomic garden", @id="3078234390">,
210
+ #<Fleakr::Objects::Photo:0x11f4928 @title="PONYLOV", @id="3077360853">, ...
211
+ >> photos.first.title
212
+ => "hiroshima atomic garden"
213
+
214
+ You can also search based on tags:
215
+
216
+ >> photos = Fleakr.search(:tags => 'macro')
217
+ >> photos.first.title
218
+ => "Demure"
219
+ >> photos.first.id
220
+ => "3076049945"
221
+
222
+ Searches can also be scoped to other entities in the system (namely Users and Groups):
223
+
224
+ >> user.groups.first.search('awesome')
225
+ => [#<Fleakr::Objects::Photo:0x18cb4cc @server_id="2012", @id="2181921273",
226
+ @farm_id="3", @title="", @secret="634eda7521">, ...
227
+ >> user.search('serpent')
228
+ => [#<Fleakr::Objects::Photo:0x18a6960 @server_id="41", @id="81370156",
229
+ @farm_id="1", @title="Clear and Serpent Danger", @secret="013091582a">]
230
+
231
+ === Uploading Files
232
+
233
+ Before you can upload files, you need to be able to make authenticated calls to the Flickr
234
+ API. Skip to the next section (Authenticated Calls) for details on how to make this work.
235
+
236
+ Uploading single files is simple:
237
+
238
+ >> Fleakr.upload('/path/to/image.jpg')
239
+ => [#<Fleakr::Objects::Photo:0x217fb54 @updated="1236133594", @server_id="3266", ...>]
240
+
241
+ Notice that the newly-uploaded image is returned. You can further inspect / modify this as
242
+ necessary. The real magic is in uploading multiple files - the upload method takes a file
243
+ glob:
244
+
245
+ >> Fleakr.upload('/path/to/images/*.jpg')
246
+ => [#<Fleakr::Objects::Photo:0x217faa0 ...>,
247
+ #<Fleakr::Objects::Photo:0x212fb18 ...>,
248
+ #<Fleakr::Objects::Photo:0x20e09c8 ...>]
249
+
250
+ You can also set options on the file(s) that you're uploading:
251
+
252
+ >> Fleakr.upload('/path/to/party/images/*.jpg', :viewable_by => :everyone,
253
+ :title => 'Party Pics')
254
+
255
+ The full list of options can be found in the Fleakr::Objects::Photo documentation.
256
+
257
+ === Authenticated Calls
258
+
259
+ While read-only access to the API gets you quite a bit of data, you'll need to generate an
260
+ authentication token if you want access to the more powerful features (like uploading your
261
+ own photos).
262
+
263
+ Assuming you've already applied for a key, go back and make sure you have the right settings
264
+ to get your auth token. Click on the 'Edit key details' link and ensure that:
265
+
266
+ 1. Your application description and notes are up-to-date
267
+ 1. The value for 'Authentication Type' is set to 'Mobile Application'
268
+ 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
269
+
270
+ Once this is set, you'll see your Authentication URL on the key details page (it will look
271
+ something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
272
+ confirm access to get your mini-token. Now you're ready to make authenticated requests:
273
+
274
+ require 'rubygems'
275
+ require 'fleakr'
276
+
277
+ Fleakr.api_key = 'ABC123'
278
+ Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
279
+ Fleakr.mini_token = '362-133-214'
280
+
281
+ Fleakr.upload('/path/to/my/photo.jpg')
282
+ Fleakr.token.value # => "34132412341235-12341234ef34"
283
+
284
+ Once you use the mini-token once, it is no longer available. To use the generated auth_token
285
+ for future requests, just set Fleakr.auth_token to the generated value. Similarly, if you have
286
+ an authenticated frob from Flickr (using authentication for desktop applications, for example)
287
+ you can also set <tt>Fleakr.frob</tt> to the frob value returned from the API.
288
+
289
+ === What Went Wrong?
290
+
291
+ Because so much of the underlying API is hidden under the covers, it's often tough to know
292
+ what's really going on when you run into unexpected behavior. To make things easier, you can
293
+ have Fleakr log all of the API traffic. Here's how:
294
+
295
+ Fleakr.logger = Logger.new('/tmp/fleakr.log')
296
+
297
+ Now any calls to the API will log both their request and response data to that file. But be
298
+ warned, this can be pretty verbose by default (especially if you're doing file uploads). To see
299
+ just the requests you need to tune the log level:
300
+
301
+ logger = Logger.new('/tmp/fleakr.log')
302
+ logger.level = Logger::INFO
303
+
304
+ Fleakr.logger = logger
305
+
306
+ Even if something doesn't go wrong, this is a good way to get a sense for when you're making
307
+ API requests.
308
+
309
+ == Roadmap / TODO
310
+
311
+ === 0.4.x
312
+
313
+ * Implement remaining bits of person and photo-related API calls (read-only)
314
+
315
+ === 0.5.x
316
+
317
+ * Implement asynchronous file upload / replacement w/ ticket checking
318
+ * Provide a better searching interface with ruby-like option syntax
319
+
320
+ === Future
321
+
322
+ * Implement save-able search results (e.g. Fleakr.search('ponies').save_to('/path', :medium))
323
+ * Implement deeper associations for core elements (e.g. tags / etc..)
324
+ * Implement write methods for photos & photosets
325
+ * Implement flickr.places.* portion of API
326
+
327
+ == License
328
+
329
+ Copyright (c) 2008 Patrick Reagan (reaganpr@gmail.com)
330
+
331
+ Permission is hereby granted, free of charge, to any person
332
+ obtaining a copy of this software and associated documentation
333
+ files (the "Software"), to deal in the Software without
334
+ restriction, including without limitation the rights to use,
335
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
336
+ copies of the Software, and to permit persons to whom the
337
+ Software is furnished to do so, subject to the following
338
+ conditions:
339
+
340
+ The above copyright notice and this permission notice shall be
341
+ included in all copies or substantial portions of the Software.
342
+
343
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
344
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
345
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
346
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
347
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
348
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
349
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
350
+ OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ require 'lib/fleakr/version'
6
+
7
+ task :default => :test
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'fleakr'
11
+ s.version = Fleakr::Version.to_s
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = %w(README.rdoc)
14
+ s.rdoc_options = %w(--main README.rdoc)
15
+ s.summary = "A small, yet powerful, gem to interface with Flickr photostreams"
16
+ s.author = 'Patrick Reagan'
17
+ s.email = 'reaganpr@gmail.com'
18
+ s.homepage = 'http://sneaq.net'
19
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
20
+
21
+ s.add_dependency('hpricot', '~> 0.8.1')
22
+ s.add_dependency('activesupport', '~> 2.0')
23
+ s.add_dependency('loggable', '~> 0.2.0')
24
+ end
25
+
26
+ Rake::GemPackageTask.new(spec) do |pkg|
27
+ pkg.gem_spec = spec
28
+ end
29
+
30
+ Rake::TestTask.new do |t|
31
+ t.libs << 'test'
32
+ t.test_files = FileList["test/**/*_test.rb"]
33
+ t.verbose = true
34
+ end
35
+
36
+ desc 'Generate the gemspec to serve this Gem from Github'
37
+ task :github do
38
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
39
+ File.open(file, 'w') {|f| f << spec.to_ruby }
40
+ puts "Created gemspec: #{file}"
41
+ end
@@ -0,0 +1,47 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = FileParameter
5
+ #
6
+ # Parameter class to encapsulate file data sent to the Flickr upload API
7
+ #
8
+ class FileParameter < Parameter
9
+
10
+ MIME_TYPES = {
11
+ '.jpg' => 'image/jpeg',
12
+ '.png' => 'image/png',
13
+ '.gif' => 'image/gif'
14
+ }
15
+
16
+ # Create a parameter with name and specified filename
17
+ #
18
+ def initialize(name, filename)
19
+ @filename = filename
20
+ super(name, false)
21
+ end
22
+
23
+ # Discover MIME type by file extension using MIME_TYPES constant
24
+ #
25
+ def mime_type
26
+ MIME_TYPES[File.extname(@filename)]
27
+ end
28
+
29
+ # File data (from @filename) to pass to the Flickr API
30
+ #
31
+ def value
32
+ @value ||= File.read(@filename)
33
+ end
34
+
35
+ # Generate a form representation of this file for upload (as multipart/form-data)
36
+ #
37
+ def to_form
38
+ "Content-Disposition: form-data; name=\"#{self.name}\"; filename=\"#{@filename}\"\r\n" +
39
+ "Content-Type: #{self.mime_type}\r\n" +
40
+ "\r\n" +
41
+ "#{self.value}\r\n"
42
+ end
43
+
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,66 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = MethodRequest
5
+ #
6
+ # Handles all API requests that are non-upload related. For upload requests see the
7
+ # UploadRequest class.
8
+ #
9
+ class MethodRequest
10
+ attr_reader :parameters, :method
11
+
12
+ # Makes a request to the Flickr API and returns a valid Response object. If
13
+ # there are errors on the response it will raise an ApiError exception. See
14
+ # MethodRequest#new for details about the additional parameters
15
+ #
16
+ def self.with_response!(method, additional_parameters = {})
17
+ request = self.new(method, additional_parameters)
18
+ response = request.send
19
+
20
+ raise(Fleakr::ApiError, "Code: #{response.error.code} - #{response.error.message}") if response.error?
21
+
22
+ response
23
+ end
24
+
25
+ # Create a new request for the specified API method and pass along any additional
26
+ # parameters. The Flickr API uses namespacing for its methods - this is optional
27
+ # when calling this method.
28
+ #
29
+ # This must be called after initializing the library with the required API key
30
+ # see (#Fleakr.api_key=)
31
+ #
32
+ # The <tt>additional_parameters</tt> is a list of parameters to pass directly to
33
+ # the Flickr API call. The exception to this is the <tt>:authenticate?</tt> option
34
+ # that will force the call to not be authenticated if it is set to false (The default
35
+ # behavior is to authenticate all calls when we have a token).
36
+ #
37
+ def initialize(method, additional_parameters = {})
38
+ @parameters = ParameterList.new(additional_parameters)
39
+
40
+ self.method = method
41
+ end
42
+
43
+ def method=(method) # :nodoc:
44
+ @method = method.sub(/^(flickr\.)?/, 'flickr.')
45
+ @parameters << ValueParameter.new('method', @method)
46
+ end
47
+
48
+ def send # :nodoc:
49
+ logger.info("Sending request to: #{endpoint_uri}")
50
+ response_xml = Net::HTTP.get(endpoint_uri)
51
+ logger.debug("Response data:\n#{response_xml}")
52
+
53
+ Response.new(response_xml)
54
+ end
55
+
56
+ private
57
+ def endpoint_uri
58
+ uri = URI.parse('http://api.flickr.com/services/rest/')
59
+ uri.query = self.parameters.to_query
60
+ uri
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,175 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = Option
5
+ #
6
+ # Top-level class for creating specific option instances based on type
7
+ #
8
+ class Option
9
+
10
+ MAPPING = {
11
+ :tags => 'TagOption',
12
+ :viewable_by => 'ViewOption',
13
+ :level => 'LevelOption',
14
+ :type => 'TypeOption',
15
+ :hide? => 'HiddenOption'
16
+ }
17
+
18
+ # Initialize a new option for the specified type and value
19
+ #
20
+ def self.for(type, value)
21
+ class_for(type).new(type, value)
22
+ end
23
+
24
+ def self.class_for(type) # :nodoc:
25
+ class_name = MAPPING[type] || 'SimpleOption'
26
+ "Fleakr::Api::#{class_name}".constantize
27
+ end
28
+
29
+ end
30
+
31
+ # = SimpleOption
32
+ #
33
+ # Simple name / value option pair
34
+ #
35
+ class SimpleOption
36
+
37
+ attr_reader :type, :value
38
+
39
+ # Create an option of the specified type and value
40
+ #
41
+ def initialize(type, value)
42
+ @type = type
43
+ @value = value
44
+ end
45
+
46
+ # Generate hash representation of this option
47
+ #
48
+ def to_hash
49
+ {type => value}
50
+ end
51
+
52
+ end
53
+
54
+ # = TagOption
55
+ #
56
+ # Represents values for tags
57
+ #
58
+ class TagOption < SimpleOption
59
+
60
+ # Tag with specified values. Value passed will be converted to an array if it isn't
61
+ # already
62
+ #
63
+ def initialize(type, value)
64
+ super type, value
65
+ @value = Array(self.value)
66
+ end
67
+
68
+ # Hash representation of tag values (separated by spaces). Handles multi-word tags
69
+ # by enclosing each tag in double quotes.
70
+ #
71
+ def to_hash
72
+ tags = value.map {|tag| "\"#{tag}\"" }
73
+ {type => tags.join(' ')}
74
+ end
75
+
76
+ end
77
+
78
+ # = ViewOption
79
+ #
80
+ # Specify who is able to view the photo.
81
+ #
82
+ class ViewOption < SimpleOption
83
+
84
+ # Specify who this is viewable by (e.g. everyone / friends / family).
85
+ #
86
+ def initialize(type, value)
87
+ super type, Array(value)
88
+ end
89
+
90
+ # Is this publicly viewable? (i.e. :everyone)
91
+ #
92
+ def public?
93
+ value == [:everyone]
94
+ end
95
+
96
+ # Is this viewable by friends? (i.e. :friends)
97
+ #
98
+ def friends?
99
+ value.include?(:friends)
100
+ end
101
+
102
+ # Is this viewable by family? (i.e. :family)
103
+ #
104
+ def family?
105
+ value.include?(:family)
106
+ end
107
+
108
+ # Hash representation of photo permissions
109
+ #
110
+ def to_hash
111
+ {:is_public => public?.to_i, :is_friend => friends?.to_i, :is_family => family?.to_i}
112
+ end
113
+
114
+ end
115
+
116
+ # = LevelOption
117
+ #
118
+ # Specify the "safety level" of this photo (e.g. safe / moderate / restricted)
119
+ #
120
+ class LevelOption < SimpleOption
121
+
122
+ def value # :nodoc:
123
+ case @value
124
+ when :safe then 1
125
+ when :moderate then 2
126
+ when :restricted then 3
127
+ end
128
+ end
129
+
130
+ # Hash representation of the safety_level for this photo
131
+ #
132
+ def to_hash
133
+ {:safety_level => value}
134
+ end
135
+
136
+ end
137
+
138
+ # = TypeOption
139
+ #
140
+ # Specify the type of this photo (e.g. photo / screenshot / other)
141
+ #
142
+ class TypeOption < SimpleOption
143
+
144
+ def value # :nodoc:
145
+ case @value
146
+ when :photo then 1
147
+ when :screenshot then 2
148
+ when :other then 3
149
+ end
150
+ end
151
+
152
+ # Hash representation of this type
153
+ #
154
+ def to_hash
155
+ {:content_type => value}
156
+ end
157
+
158
+ end
159
+
160
+ # = HiddenOption
161
+ #
162
+ # Specify whether this photo should be hidden from search
163
+ #
164
+ class HiddenOption < SimpleOption
165
+
166
+ # Hash representation of whether to hide this photo
167
+ #
168
+ def to_hash
169
+ {:hidden => (value ? 2 : 1)}
170
+ end
171
+
172
+ end
173
+
174
+ end
175
+ end