theoooo-fleakr 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/README.rdoc +350 -0
  2. data/Rakefile +41 -0
  3. data/lib/fleakr.rb +163 -0
  4. data/lib/fleakr/api.rb +8 -0
  5. data/lib/fleakr/api/file_parameter.rb +47 -0
  6. data/lib/fleakr/api/method_request.rb +66 -0
  7. data/lib/fleakr/api/option.rb +175 -0
  8. data/lib/fleakr/api/parameter.rb +35 -0
  9. data/lib/fleakr/api/parameter_list.rb +97 -0
  10. data/lib/fleakr/api/response.rb +35 -0
  11. data/lib/fleakr/api/upload_request.rb +75 -0
  12. data/lib/fleakr/api/value_parameter.rb +36 -0
  13. data/lib/fleakr/core_ext.rb +3 -0
  14. data/lib/fleakr/core_ext/false_class.rb +7 -0
  15. data/lib/fleakr/core_ext/hash.rb +22 -0
  16. data/lib/fleakr/core_ext/true_class.rb +7 -0
  17. data/lib/fleakr/objects.rb +12 -0
  18. data/lib/fleakr/objects/authentication_token.rb +60 -0
  19. data/lib/fleakr/objects/comment.rb +49 -0
  20. data/lib/fleakr/objects/contact.rb +31 -0
  21. data/lib/fleakr/objects/error.rb +22 -0
  22. data/lib/fleakr/objects/group.rb +36 -0
  23. data/lib/fleakr/objects/image.rb +50 -0
  24. data/lib/fleakr/objects/photo.rb +147 -0
  25. data/lib/fleakr/objects/photo_context.rb +49 -0
  26. data/lib/fleakr/objects/search.rb +30 -0
  27. data/lib/fleakr/objects/set.rb +50 -0
  28. data/lib/fleakr/objects/tag.rb +56 -0
  29. data/lib/fleakr/objects/user.rb +95 -0
  30. data/lib/fleakr/support.rb +2 -0
  31. data/lib/fleakr/support/attribute.rb +46 -0
  32. data/lib/fleakr/support/object.rb +110 -0
  33. data/lib/fleakr/version.rb +13 -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 +140 -0
  56. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  57. data/test/unit/fleakr/api/method_request_test.rb +93 -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 +145 -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 +58 -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 +243 -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
data/lib/fleakr.rb ADDED
@@ -0,0 +1,163 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+ require 'rubygems'
3
+
4
+ require 'uri'
5
+ require 'cgi'
6
+ require 'net/http'
7
+ require 'hpricot'
8
+ require 'forwardable'
9
+
10
+ # Require only what we need from ActiveSupport
11
+ require 'active_support/core_ext/array'
12
+ require 'active_support/core_ext/module'
13
+ require 'active_support/core_ext/blank'
14
+ require 'active_support/core_ext/time'
15
+ require 'active_support/inflector'
16
+ require 'active_support/core_ext/string'
17
+
18
+ require 'md5'
19
+ require 'loggable'
20
+
21
+ require 'fleakr/api'
22
+ require 'fleakr/core_ext'
23
+ require 'fleakr/support'
24
+ require 'fleakr/objects'
25
+
26
+ # = Fleakr: A small, yet powerful, gem to interface with Flickr photostreams
27
+ #
28
+ # == Quick Start
29
+ #
30
+ # Getting started is easy, just make sure you have a valid API key from Flickr and you can
31
+ # then start making any non-authenticated request to pull back data for yours and others'
32
+ # photostreams, sets, contacts, groups, etc...
33
+ #
34
+ # For now, all activity originates from a single user which you can find by username or
35
+ # email address.
36
+ #
37
+ # Example:
38
+ #
39
+ # require 'rubygems'
40
+ # require 'fleakr'
41
+ #
42
+ # # Our API key is ABC123 (http://www.flickr.com/services/api/keys/apply/)
43
+ # Fleakr.api_key = 'ABC123'
44
+ # user = Fleakr.user('bees')
45
+ # user = Fleakr.user('user@host.com')
46
+ # # Grab a list of sets
47
+ # user.sets
48
+ # # Grab a list of the user's public groups
49
+ # user.groups
50
+ #
51
+ # To see what other associations and attributes are available, see the Fleakr::Objects::User class
52
+ #
53
+ # == Authentication
54
+ #
55
+ # If you want to do something more than just retrieve public photos (like upload your own),
56
+ # you'll need to generate an authentication token to use across requests and sessions.
57
+ #
58
+ # Assuming you've already applied for a key, go back and make sure you have the right settings
59
+ # to get your auth token. Click on the 'Edit key details' link and ensure that:
60
+ #
61
+ # 1. Your application description and notes are up-to-date
62
+ # 1. The value for 'Authentication Type' is set to 'Mobile Application'
63
+ # 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
64
+ #
65
+ # Once this is set, you'll see your Authentication URL on the key details page (it will look
66
+ # something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
67
+ # confirm access to get your mini-token. Now you're ready to make authenticated requests:
68
+ #
69
+ # require 'rubygems'
70
+ # require 'fleakr'
71
+ #
72
+ # Fleakr.api_key = 'ABC123'
73
+ # Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
74
+ # Fleakr.mini_token = '362-133-214'
75
+ #
76
+ # Fleakr.upload('/path/to/my/photo.jpg')
77
+ # Fleakr.token.value # => "34132412341235-12341234ef34"
78
+ #
79
+ # Once you use the mini-token once, it is no longer available. To use the generated auth_token
80
+ # for future requests, just set Fleakr.auth_token to the generated value.
81
+ #
82
+ module Fleakr
83
+
84
+ # Generic catch-all exception for any API errors
85
+ class ApiError < StandardError; end
86
+
87
+ mattr_accessor :api_key, :shared_secret, :mini_token, :auth_token, :frob
88
+
89
+ # Find a user based on some unique user data. This method will try to find
90
+ # the user based on username and will fall back to email if that fails. Example:
91
+ #
92
+ # Fleakr.api_key = 'ABC123'
93
+ # Fleakr.user('the decapitator') # => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
94
+ # Fleakr.user('user@host.com') # => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
95
+ #
96
+ def self.user(user_data)
97
+ begin
98
+ Objects::User.find_by_username(user_data)
99
+ rescue ApiError
100
+ Objects::User.find_by_email(user_data)
101
+ end
102
+ end
103
+
104
+ # Search all photos on the Flickr site. By default, this searches based on text, but you can pass
105
+ # different search parameters (passed as hash keys):
106
+ #
107
+ # [tags] The list of tags to search on (either as an array or comma-separated)
108
+ # [user_id] Scope the search to this user
109
+ # [group_id] Scope the search to this group
110
+ #
111
+ # If you're interested in User- and Group-scoped searches, you may want to use User#search and Group#search
112
+ # instead.
113
+ #
114
+ def self.search(params)
115
+ params = {:text => params} unless params.is_a?(Hash)
116
+ Objects::Search.new(params).results
117
+ end
118
+
119
+ # Upload one or more files to your Flickr account (requires authentication). Simply provide
120
+ # a filename or a pattern to upload one or more files:
121
+ #
122
+ # Fleakr.upload('/path/to/my/mug.jpg')
123
+ # Fleakr.upload('/User/Pictures/Party/*.jpg')
124
+ #
125
+ # Additionally, options can be supplied as part of the upload that will apply to all files
126
+ # that are matched by the pattern passed to <tt>glob</tt>. For a full list, see
127
+ # Fleakr::Objects::Photo.
128
+ #
129
+ def self.upload(glob, options = {})
130
+ Dir[glob].map {|file| Fleakr::Objects::Photo.upload(file, options) }
131
+ end
132
+
133
+ # Get the authentication token needed for authenticated requests. Will either use
134
+ # a valid auth_token (if available) or a mini-token to generate the auth_token.
135
+ #
136
+ def self.token
137
+ @token ||= begin
138
+ if Fleakr.auth_token
139
+ Fleakr::Objects::AuthenticationToken.from_auth_token(Fleakr.auth_token)
140
+ elsif Fleakr.frob
141
+ Fleakr::Objects::AuthenticationToken.from_frob(Fleakr.frob)
142
+ elsif Fleakr.mini_token
143
+ Fleakr::Objects::AuthenticationToken.from_mini_token(Fleakr.mini_token)
144
+ end
145
+ end
146
+ end
147
+
148
+ # Reset the cached token whenever setting a new value for the mini_token, auth_token, or frob
149
+ #
150
+ [:mini_token, :auth_token, :frob].each do |attribute|
151
+ class_eval <<-ACCESSOR
152
+ def self.#{attribute}=(#{attribute})
153
+ reset_token
154
+ @@#{attribute} = #{attribute}
155
+ end
156
+ ACCESSOR
157
+ end
158
+
159
+ def self.reset_token # :nodoc: #
160
+ @token = nil
161
+ end
162
+
163
+ end