fleakr 0.3.0 → 0.4.0

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 (51) hide show
  1. data/README.rdoc +114 -19
  2. data/Rakefile +1 -1
  3. data/lib/fleakr/api/file_parameter.rb +47 -0
  4. data/lib/fleakr/api/method_request.rb +57 -0
  5. data/lib/fleakr/api/parameter.rb +35 -0
  6. data/lib/fleakr/api/parameter_list.rb +96 -0
  7. data/lib/fleakr/api/response.rb +2 -2
  8. data/lib/fleakr/api/upload_request.rb +64 -0
  9. data/lib/fleakr/api/value_parameter.rb +36 -0
  10. data/lib/fleakr/api.rb +7 -0
  11. data/lib/fleakr/core_ext/hash.rb +22 -0
  12. data/lib/fleakr/core_ext.rb +1 -0
  13. data/lib/fleakr/objects/authentication_token.rb +43 -0
  14. data/lib/fleakr/objects/contact.rb +5 -5
  15. data/lib/fleakr/objects/error.rb +2 -2
  16. data/lib/fleakr/objects/group.rb +2 -2
  17. data/lib/fleakr/objects/image.rb +7 -7
  18. data/lib/fleakr/objects/photo.rb +69 -5
  19. data/lib/fleakr/objects/search.rb +3 -6
  20. data/lib/fleakr/objects/set.rb +11 -5
  21. data/lib/fleakr/objects/user.rb +14 -26
  22. data/lib/fleakr/objects.rb +9 -0
  23. data/lib/fleakr/support/attribute.rb +30 -12
  24. data/lib/fleakr/support/object.rb +20 -4
  25. data/lib/fleakr/support.rb +2 -0
  26. data/lib/fleakr/version.rb +1 -1
  27. data/lib/fleakr.rb +66 -7
  28. data/test/fixtures/auth.checkToken.xml +8 -0
  29. data/test/fixtures/auth.getFullToken.xml +8 -0
  30. data/test/fixtures/people.getInfo.xml +1 -1
  31. data/test/fixtures/photos.getInfo.xml +20 -0
  32. data/test/test_helper.rb +18 -3
  33. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  34. data/test/unit/fleakr/api/method_request_test.rb +103 -0
  35. data/test/unit/fleakr/api/parameter_list_test.rb +161 -0
  36. data/test/unit/fleakr/api/parameter_test.rb +34 -0
  37. data/test/unit/fleakr/api/upload_request_test.rb +133 -0
  38. data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
  39. data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
  40. data/test/unit/fleakr/objects/authentication_token_test.rb +47 -0
  41. data/test/unit/fleakr/objects/image_test.rb +10 -5
  42. data/test/unit/fleakr/objects/photo_test.rb +96 -36
  43. data/test/unit/fleakr/objects/search_test.rb +1 -1
  44. data/test/unit/fleakr/objects/set_test.rb +12 -1
  45. data/test/unit/fleakr/objects/user_test.rb +2 -16
  46. data/test/unit/fleakr/support/attribute_test.rb +82 -24
  47. data/test/unit/fleakr/support/object_test.rb +26 -3
  48. data/test/unit/fleakr_test.rb +65 -6
  49. metadata +28 -5
  50. data/lib/fleakr/api/request.rb +0 -58
  51. data/test/unit/fleakr/api/request_test.rb +0 -93
data/README.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  == Description
4
4
 
5
- A teeny tiny gem to interface with Flickr photostreams
5
+ A small, yet powerful, gem to interface with Flickr photostreams
6
6
 
7
7
  == Installation
8
8
 
@@ -22,16 +22,24 @@ Or ...
22
22
 
23
23
  == Usage
24
24
 
25
- Before doing anything, require the library:
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
26
28
 
27
- >> require 'rubygems'
28
- >> require 'fleakr'
29
+ Now that you have your key, you can get things rolling with irb and the fleakr gem:
29
30
 
31
+ $ irb -r rubygems
32
+ >> require 'fleakr'
33
+
30
34
  Then, set your API key (only need to do this once per session):
31
35
 
32
36
  >> Fleakr.api_key = '<your api key here>'
33
-
34
- Find a user by username:
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:
35
43
 
36
44
  >> user = Fleakr.user('the decapitator')
37
45
  => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
@@ -47,13 +55,18 @@ Once you have a user, you can find his associated sets:
47
55
  => [#<Fleakr::Objects::Set:0x671358 @title="The Decapitator", @description="">,
48
56
  #<Fleakr::Objects::Set:0x66d898 @title="londonpaper hijack", ...
49
57
 
58
+ His individual photos:
59
+
60
+ >> user.photos.first
61
+ => #<Fleakr::Objects::Photo:0x161b024 @title="\"Be Fabulous\"" ... >
62
+
50
63
  Or contacts:
51
64
 
52
65
  >> user.contacts.first
53
66
  => #<Fleakr::Objects::User:0x19039bc @username=".schill",
54
67
  @id="12289718@N00", @icon_farm="1", @icon_server="4">
55
68
 
56
- Or groups if you would like:
69
+ Or his groups if you would like:
57
70
 
58
71
  >> user.groups
59
72
  => [#<Fleakr::Objects::Group:0x11f2330 ...,
@@ -77,20 +90,59 @@ When accessing a set, you can also grab all the photos that are in that set:
77
90
  >> user.sets.first.photos.first.title
78
91
  => "Untitled1"
79
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
+ === Saving Images
125
+
80
126
  If a photo interests you, save it down to a directory of your choosing:
81
127
 
82
- >> user.sets.first.photos.first.small.save_to('/tmp')
83
- => #<File:/tmp/2117922283_715587b2cb_m.jpg (closed)>
128
+ >> photo.original.save_to('/tmp')
129
+ => #<File:/tmp/2924549350_1cf67c2d47_o.jpg (closed)>
84
130
 
85
- If you can't decide on a photo and would rather just save the whole set, specify the target directory
86
- and the size of the images you're interested in:
131
+ Similarly, you can save down entire sets. Just specify the target directory and the size
132
+ of the images you're interested in:
87
133
 
88
134
  >> user.sets.first.save_to('/tmp', :square)
89
135
  => [#<Fleakr::Objects::Photo:0x1187a1c @secret="715587b2cb" ...
136
+
137
+ This creates a subdirectory within the target directory based on the set's name and preserves
138
+ the original order of the photos:
139
+
90
140
  >> Dir["/tmp/#{user.sets.first.title}/*.jpg"].map
91
- => ["/tmp/The Decapitator/2117919621_8b2d601bff_s.jpg",
92
- "/tmp/The Decapitator/2117921045_5fb15eff90_s.jpg",
93
- "/tmp/The Decapitator/2117922283_715587b2cb_s.jpg", ...
141
+ => ["/tmp/The Decapitator/01_2117922283_715587b2cb_s.jpg",
142
+ "/tmp/The Decapitator/02_2125604584_9c09348fd6_s.jpg",
143
+ "/tmp/The Decapitator/03_2118696542_8af5763bde_s.jpg", ... ]
144
+
145
+ === Searching
94
146
 
95
147
  If you would prefer to just search photos, you can do that with search text:
96
148
 
@@ -116,13 +168,56 @@ Searches can also be scoped to other entities in the system (namely Users and Gr
116
168
  >> user.search('serpent')
117
169
  => [#<Fleakr::Objects::Photo:0x18a6960 @server_id="41", @id="81370156",
118
170
  @farm_id="1", @title="Clear and Serpent Danger", @secret="013091582a">]
119
-
120
- == TODO
121
171
 
122
- * Implement remaining bits of person, photoset, and photo-releated APIs
172
+ === Authenticated Calls & Uploads
173
+
174
+ While read-only access to the API gets you quite a bit of data, you'll need to generate an
175
+ authentication token if you want access to the more powerful features (like uploading your
176
+ own photos).
177
+
178
+ Assuming you've already applied for a key, go back and make sure you have the right settings
179
+ to get your auth token. Click on the 'Edit key details' link and ensure that:
180
+
181
+ 1. Your application description and notes are up-to-date
182
+ 1. The value for 'Authentication Type' is set to 'Mobile Application'
183
+ 1. The value for 'Mobile Permissions' is set to either 'write' or 'delete'
184
+
185
+ Once this is set, you'll see your Authentication URL on the key details page (it will look
186
+ something like http://www.flickr.com/auth-534525246245). Paste this URL into your browser and
187
+ confirm access to get your mini-token. Now you're ready to make authenticated requests:
188
+
189
+ require 'rubygems'
190
+ require 'fleakr'
191
+
192
+ Fleakr.api_key = 'ABC123'
193
+ Fleakr.shared_secret = 'sekrit' # Available with your key details on the Flickr site
194
+ Fleakr.mini_token = '362-133-214'
195
+
196
+ Fleakr.upload('/path/to/my/photo.jpg')
197
+ Fleakr.token.value # => "34132412341235-12341234ef34"
198
+
199
+ Once you use the mini-token once, it is no longer available. To use the generated auth_token
200
+ for future requests, just set Fleakr.auth_token to the generated value.
201
+
202
+ == Roadmap / TODO
203
+
204
+ === 0.4.x
205
+
206
+ * Allow passing of parameters to file uploads to allow for access control / naming
207
+ * Implement remaining bits of person and photo-related API calls (read-only)
208
+ * Automatically sign all calls (if we have a secret), authenticate all calls (if we have a token)
209
+
210
+ === 0.5.x
211
+
212
+ * Implement asynchronous file upload / replacement w/ ticket checking
123
213
  * Provide a better searching interface
124
- * Lazily load attributes for objects that need to be accessed via secondary API call
125
-
214
+
215
+ === Future
216
+
217
+ * Implement save-able search results (e.g. Fleakr.search('ponies').save_to('/path', :medium))
218
+ * Implement deeper associations for core elements (e.g. tags / etc..)
219
+ * Implement write methods for photos & photosets
220
+
126
221
  == License
127
222
 
128
223
  Copyright (c) 2008 Patrick Reagan (reaganpr@gmail.com)
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ spec = Gem::Specification.new do |s|
12
12
  s.has_rdoc = true
13
13
  s.extra_rdoc_files = %w(README.rdoc)
14
14
  s.rdoc_options = %w(--main README.rdoc)
15
- s.summary = "A teeny tiny gem to interface with Flickr photostreams"
15
+ s.summary = "A small, yet powerful, gem to interface with Flickr photostreams"
16
16
  s.author = 'Patrick Reagan'
17
17
  s.email = 'reaganpr@gmail.com'
18
18
  s.homepage = 'http://sneaq.net'
@@ -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,57 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ class MethodRequest
5
+ attr_reader :parameters, :method
6
+
7
+ # Makes a request to the Flickr API and returns a valid Response object. If
8
+ # there are errors on the response it will raise an ApiError exception. See
9
+ # #Fleakr::Api::MethodRequest.new for details about the additional parameters
10
+ #
11
+ def self.with_response!(method, additional_parameters = {})
12
+ request = self.new(method, additional_parameters)
13
+ response = request.send
14
+
15
+ raise(Fleakr::ApiError, "Code: #{response.error.code} - #{response.error.message}") if response.error?
16
+
17
+ response
18
+ end
19
+
20
+ # Create a new request for the specified API method and pass along any additional
21
+ # parameters. The Flickr API uses namespacing for its methods - this is optional
22
+ # when calling this method.
23
+ #
24
+ # This must be called after initializing the library with the required API key
25
+ # see (#Fleakr.api_key=)
26
+ #
27
+ # The <tt>additional_parameters</tt> is a list of parameters to pass directly to
28
+ # the Flickr API call. Exceptions to this are the <tt>:sign?</tt> and
29
+ # <tt>:authenticate?</tt> options that determine if the call should be signed or
30
+ # authenticated.
31
+ #
32
+ def initialize(method, additional_parameters = {})
33
+ @parameters = ParameterList.new(additional_parameters)
34
+
35
+ self.method = method
36
+ end
37
+
38
+ def method=(method) # :nodoc:
39
+ @method = method.sub(/^(flickr\.)?/, 'flickr.')
40
+ @parameters << ValueParameter.new('method', @method)
41
+ end
42
+
43
+ def send # :nodoc:
44
+ Response.new(Net::HTTP.get(endpoint_uri))
45
+ end
46
+
47
+ private
48
+ def endpoint_uri
49
+ uri = URI.parse('http://api.flickr.com/services/rest/')
50
+ uri.query = self.parameters.to_query
51
+ uri
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = Parameter
5
+ #
6
+ # Base class for other parameters that get passed to the Flickr API - see
7
+ # #FileParameter and #ValueParameter for examples
8
+ #
9
+ class Parameter
10
+
11
+ attr_reader :name
12
+
13
+ # A new named parameter (never used directly)
14
+ #
15
+ def initialize(name, include_in_signature = true)
16
+ @name = name
17
+ @include_in_signature = include_in_signature
18
+ end
19
+
20
+ # Should this parameter be used when generating the signature?
21
+ #
22
+ def include_in_signature?
23
+ (@include_in_signature == true) ? true : false
24
+ end
25
+
26
+ # Used for sorting when generating a signature
27
+ #
28
+ def <=>(other)
29
+ self.name <=> other.name
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,96 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = ParameterList
5
+ #
6
+ # Represents a list of parameters that get passed as part of a
7
+ # MethodRequest or UploadRequest. These can be transformed as necessary
8
+ # into query strings (using #to_query) or form data (using #to_form)
9
+ #
10
+ class ParameterList
11
+
12
+ # Create a new parameter list with optional parameters:
13
+ # [:sign?] Will these parameters be used to sign the request?
14
+ # [:authenticate?] Will the request need to be authenticated?
15
+ #
16
+ # Any additional name / value pairs will be created as individual
17
+ # ValueParameters as part of the list. Example:
18
+ #
19
+ # >> list = Fleakr::Api::ParameterList.new(:foo => 'bar')
20
+ # => #<Fleakr::Api::ParameterList:0x1656e6c @list=... >
21
+ # >> list[:foo]
22
+ # => #<Fleakr::Api::ValueParameter:0x1656da4 @include_in_signature=true, @name="foo", @value="bar">
23
+ #
24
+ def initialize(options = {})
25
+ @api_options = options.extract!(:sign?, :authenticate?)
26
+
27
+ @list = Hash.new
28
+
29
+ options.each {|k,v| self << ValueParameter.new(k.to_s, v) }
30
+
31
+ self << ValueParameter.new('api_key', Fleakr.api_key)
32
+ self << ValueParameter.new('auth_token', Fleakr.token.value) if authenticate?
33
+ end
34
+
35
+ # Add a new parameter (ValueParameter / FileParameter) to the list
36
+ #
37
+ def <<(parameter)
38
+ @list.merge!(parameter.name => parameter)
39
+ end
40
+
41
+ # Should this parameter list be signed?
42
+ #
43
+ def sign?
44
+ (@api_options[:sign?] == true || authenticate?) ? true : false
45
+ end
46
+
47
+ # Should we send the auth_token with the request?
48
+ #
49
+ def authenticate?
50
+ (@api_options[:authenticate?] == true) ? true : false
51
+ end
52
+
53
+ # Access an individual parameter by key (symbol or string)
54
+ #
55
+ def [](key)
56
+ list[key.to_s]
57
+ end
58
+
59
+ def boundary # :nodoc:
60
+ @boundary ||= Digest::MD5.hexdigest(rand.to_s)
61
+ end
62
+
63
+ # Generate the query string representation of this parameter
64
+ # list - e.g. <tt>foo=bar&blee=baz</tt>
65
+ #
66
+ def to_query
67
+ list.values.map(&:to_query).join('&')
68
+ end
69
+
70
+ # Generate the form representation of this parameter list including the
71
+ # boundary
72
+ #
73
+ def to_form
74
+ form = list.values.map {|p| "--#{self.boundary}\r\n#{p.to_form}" }.join
75
+ form << "--#{self.boundary}--"
76
+
77
+ form
78
+ end
79
+
80
+ def signature # :nodoc:
81
+ parameters_to_sign = @list.values.reject {|p| !p.include_in_signature? }
82
+ signature_text = parameters_to_sign.sort.map {|p| "#{p.name}#{p.value}" }.join
83
+
84
+ Digest::MD5.hexdigest("#{Fleakr.shared_secret}#{signature_text}")
85
+ end
86
+
87
+ private
88
+ def list
89
+ list = @list
90
+ list.merge!('api_sig' => ValueParameter.new('api_sig', signature, false)) if self.sign?
91
+
92
+ list
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,11 +1,11 @@
1
1
  module Fleakr
2
- module Api
2
+ module Api # :nodoc:
3
3
 
4
4
  # = Response
5
5
  #
6
6
  # Response objects contain Hpricot documents that are traversed and parsed by
7
7
  # the model objects. This class is never called directly but is instantiated
8
- # during the request cycle (see: Fleakr::Api::Request.with_response!)
8
+ # during the request cycle (see: Fleakr::Api::MethodRequest.with_response!)
9
9
  #
10
10
  class Response
11
11
 
@@ -0,0 +1,64 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = UploadRequest
5
+ #
6
+ # This implements the upload functionality of the Flickr API which is needed
7
+ # to create new photos and replace the photo content of existing photos
8
+ #
9
+ class UploadRequest
10
+
11
+ ENDPOINT_URIS = {
12
+ :create => 'http://api.flickr.com/services/upload/',
13
+ :update => 'http://api.flickr.com/services/replace/'
14
+ }
15
+
16
+ attr_reader :parameters, :type
17
+
18
+ # Send a request and return a Response object. If an API error occurs, this raises
19
+ # a Fleakr::ApiError with the reason for the error. See UploadRequest#new for more
20
+ # details.
21
+ #
22
+ def self.with_response!(filename, options = {})
23
+ request = self.new(filename, options)
24
+ response = request.send
25
+
26
+ raise(Fleakr::ApiError, "Code: #{response.error.code} - #{response.error.message}") if response.error?
27
+
28
+ response
29
+ end
30
+
31
+ # Create a new UploadRequest with the specified filename and options:
32
+ #
33
+ # [:type] Valid values are :create and :update and are used when uploading new
34
+ # photos or replacing existing ones
35
+ #
36
+ def initialize(filename, options = {})
37
+ type_options = options.extract!(:type)
38
+ options.merge!(:authenticate? => true)
39
+
40
+ @type = type_options[:type] || :create
41
+
42
+ @parameters = ParameterList.new(options)
43
+ @parameters << FileParameter.new('photo', filename)
44
+ end
45
+
46
+ def headers # :nodoc:
47
+ {'Content-Type' => "multipart/form-data; boundary=#{self.parameters.boundary}"}
48
+ end
49
+
50
+ def send # :nodoc:
51
+ response = Net::HTTP.start(endpoint_uri.host, endpoint_uri.port) do |http|
52
+ http.post(endpoint_uri.path, self.parameters.to_form, self.headers)
53
+ end
54
+ Response.new(response.body)
55
+ end
56
+
57
+ private
58
+ def endpoint_uri
59
+ @endpoint_uri ||= URI.parse(ENDPOINT_URIS[self.type])
60
+ end
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ module Fleakr
2
+ module Api # :nodoc:
3
+
4
+ # = ValueParameter
5
+ #
6
+ # A simple name / value parameter for use in API calls
7
+ #
8
+ class ValueParameter < Parameter
9
+
10
+ attr_reader :value
11
+
12
+ # Create a new parameter with the specified name / value pair.
13
+ #
14
+ def initialize(name, value, include_in_signature = true)
15
+ @value = value
16
+ super(name, include_in_signature)
17
+ end
18
+
19
+ # Generate the query string representation of this parameter.
20
+ #
21
+ def to_query
22
+ "#{self.name}=#{CGI.escape(self.value.to_s)}"
23
+ end
24
+
25
+ # Generate the form representation of this parameter.
26
+ #
27
+ def to_form
28
+ "Content-Disposition: form-data; name=\"#{self.name}\"\r\n" +
29
+ "\r\n" +
30
+ "#{self.value}\r\n"
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
data/lib/fleakr/api.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "fleakr/api/response"
2
+ require "fleakr/api/method_request"
3
+ require "fleakr/api/upload_request"
4
+ require "fleakr/api/parameter_list"
5
+ require "fleakr/api/parameter"
6
+ require "fleakr/api/value_parameter"
7
+ require "fleakr/api/file_parameter"
@@ -0,0 +1,22 @@
1
+ class Hash
2
+
3
+ # Extract the matching keys from the source hash and return
4
+ # a new hash with those keys:
5
+ #
6
+ # >> h = {:a => 'b', :c => 'd'}
7
+ # => {:a=>"b", :c=>"d"}
8
+ # >> h.extract!(:a)
9
+ # => {:a=>"b"}
10
+ # >> h
11
+ # => {:c=>"d"}
12
+ #
13
+ def extract!(*keys)
14
+ value = {}
15
+
16
+ keys.each {|k| value.merge!({k => self[k]}) if self.has_key?(k) }
17
+ keys.each {|k| delete(k) }
18
+
19
+ value
20
+ end
21
+
22
+ end
@@ -0,0 +1 @@
1
+ require 'fleakr/core_ext/hash'
@@ -0,0 +1,43 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = AuthenticationToken
5
+ #
6
+ # This class represents an authentication token used for API calls that
7
+ # require authentication before they can be used
8
+ #
9
+ # == Attributes
10
+ #
11
+ # [value] The token value that is used in subsequent API calls
12
+ # [permissions] The permissions granted to this application (read / write / delete)
13
+ #
14
+ class AuthenticationToken
15
+
16
+ include Fleakr::Support::Object
17
+
18
+ flickr_attribute :value, :from => 'auth/token'
19
+ flickr_attribute :permissions, :from => 'auth/perms'
20
+
21
+ # Retrieve a full authentication token from the supplied mini-token (e.g. 123-456-789)
22
+ #
23
+ def self.from_mini_token(token)
24
+ parameters = {:mini_token => token, :sign? => true}
25
+ response = Fleakr::Api::MethodRequest.with_response!('auth.getFullToken', parameters)
26
+
27
+ self.new(response.body)
28
+ end
29
+
30
+ # Retrieve a full authentication token from the supplied auth_token string
31
+ # (e.g. 45-76598454353455)
32
+ #
33
+ def self.from_auth_token(token)
34
+ parameters = {:auth_token => token, :sign? => true}
35
+ response = Fleakr::Api::MethodRequest.with_response!('auth.checkToken', parameters)
36
+
37
+ self.new(response.body)
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -4,15 +4,15 @@ module Fleakr
4
4
 
5
5
  include Fleakr::Support::Object
6
6
 
7
- flickr_attribute :id, :attribute => 'nsid'
8
- flickr_attribute :username, :attribute => 'username'
9
- flickr_attribute :icon_server, :attribute => 'iconserver'
10
- flickr_attribute :icon_farm, :attribute => 'iconfarm'
7
+ flickr_attribute :id, :from => '@nsid'
8
+ flickr_attribute :username
9
+ flickr_attribute :icon_server, :from => '@iconserver'
10
+ flickr_attribute :icon_farm, :from => '@iconfarm'
11
11
 
12
12
  # Retrieve a list of contacts for the specified user ID and return an initialized
13
13
  # collection of #User objects
14
14
  def self.find_all_by_user_id(user_id)
15
- response = Fleakr::Api::Request.with_response!('contacts.getPublicList', :user_id => user_id)
15
+ response = Fleakr::Api::MethodRequest.with_response!('contacts.getPublicList', :user_id => user_id)
16
16
  (response.body/'contacts/contact').map {|c| Contact.new(c).to_user }
17
17
  end
18
18
 
@@ -14,8 +14,8 @@ module Fleakr
14
14
 
15
15
  include Fleakr::Support::Object
16
16
 
17
- flickr_attribute :code, :xpath => 'rsp/err', :attribute => 'code'
18
- flickr_attribute :message, :xpath => 'rsp/err', :attribute => 'msg'
17
+ flickr_attribute :code, :from => 'err@code'
18
+ flickr_attribute :message, :from => 'err@msg'
19
19
 
20
20
  end
21
21
  end
@@ -12,8 +12,8 @@ module Fleakr
12
12
 
13
13
  include Fleakr::Support::Object
14
14
 
15
- flickr_attribute :id, :attribute => 'nsid'
16
- flickr_attribute :name, :attribute => 'name'
15
+ flickr_attribute :id, :from => '@nsid'
16
+ flickr_attribute :name
17
17
 
18
18
  find_all :by_user_id, :call => 'people.getPublicGroups', :path => 'groups/group'
19
19