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.
- data/README.rdoc +350 -0
- data/Rakefile +41 -0
- data/lib/fleakr/api/file_parameter.rb +47 -0
- data/lib/fleakr/api/method_request.rb +66 -0
- data/lib/fleakr/api/option.rb +175 -0
- data/lib/fleakr/api/parameter.rb +35 -0
- data/lib/fleakr/api/parameter_list.rb +97 -0
- data/lib/fleakr/api/response.rb +35 -0
- data/lib/fleakr/api/upload_request.rb +75 -0
- data/lib/fleakr/api/value_parameter.rb +36 -0
- data/lib/fleakr/api.rb +8 -0
- data/lib/fleakr/core_ext/false_class.rb +7 -0
- data/lib/fleakr/core_ext/hash.rb +22 -0
- data/lib/fleakr/core_ext/true_class.rb +7 -0
- data/lib/fleakr/core_ext.rb +3 -0
- data/lib/fleakr/objects/authentication_token.rb +60 -0
- data/lib/fleakr/objects/comment.rb +49 -0
- data/lib/fleakr/objects/contact.rb +31 -0
- data/lib/fleakr/objects/error.rb +22 -0
- data/lib/fleakr/objects/group.rb +36 -0
- data/lib/fleakr/objects/image.rb +50 -0
- data/lib/fleakr/objects/photo.rb +147 -0
- data/lib/fleakr/objects/photo_context.rb +49 -0
- data/lib/fleakr/objects/search.rb +30 -0
- data/lib/fleakr/objects/set.rb +50 -0
- data/lib/fleakr/objects/tag.rb +56 -0
- data/lib/fleakr/objects/user.rb +95 -0
- data/lib/fleakr/objects.rb +12 -0
- data/lib/fleakr/support/attribute.rb +46 -0
- data/lib/fleakr/support/object.rb +110 -0
- data/lib/fleakr/support.rb +2 -0
- data/lib/fleakr/version.rb +13 -0
- data/lib/fleakr.rb +164 -0
- data/test/fixtures/auth.checkToken.xml +8 -0
- data/test/fixtures/auth.getFullToken.xml +8 -0
- data/test/fixtures/auth.getToken.xml +8 -0
- data/test/fixtures/contacts.getPublicList.xml +7 -0
- data/test/fixtures/groups.pools.getPhotos.xml +7 -0
- data/test/fixtures/people.findByEmail.xml +6 -0
- data/test/fixtures/people.findByUsername.xml +6 -0
- data/test/fixtures/people.getInfo.xml +18 -0
- data/test/fixtures/people.getPublicGroups.xml +7 -0
- data/test/fixtures/people.getPublicPhotos.xml +7 -0
- data/test/fixtures/photos.comments.getList.xml +7 -0
- data/test/fixtures/photos.getContext.xml +6 -0
- data/test/fixtures/photos.getInfo.xml +20 -0
- data/test/fixtures/photos.getSizes.xml +10 -0
- data/test/fixtures/photos.search.xml +7 -0
- data/test/fixtures/photosets.comments.getList.xml +7 -0
- data/test/fixtures/photosets.getList.xml +13 -0
- data/test/fixtures/photosets.getPhotos.xml +7 -0
- data/test/fixtures/tags.getListPhoto.xml +9 -0
- data/test/fixtures/tags.getListUser.xml +10 -0
- data/test/fixtures/tags.getRelated.xml +9 -0
- data/test/test_helper.rb +141 -0
- data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
- data/test/unit/fleakr/api/method_request_test.rb +94 -0
- data/test/unit/fleakr/api/option_test.rb +179 -0
- data/test/unit/fleakr/api/parameter_list_test.rb +176 -0
- data/test/unit/fleakr/api/parameter_test.rb +34 -0
- data/test/unit/fleakr/api/response_test.rb +49 -0
- data/test/unit/fleakr/api/upload_request_test.rb +149 -0
- data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
- data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
- data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
- data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
- data/test/unit/fleakr/objects/authentication_token_test.rb +61 -0
- data/test/unit/fleakr/objects/comment_test.rb +66 -0
- data/test/unit/fleakr/objects/contact_test.rb +61 -0
- data/test/unit/fleakr/objects/error_test.rb +21 -0
- data/test/unit/fleakr/objects/group_test.rb +46 -0
- data/test/unit/fleakr/objects/image_test.rb +81 -0
- data/test/unit/fleakr/objects/photo_context_test.rb +80 -0
- data/test/unit/fleakr/objects/photo_test.rb +246 -0
- data/test/unit/fleakr/objects/search_test.rb +74 -0
- data/test/unit/fleakr/objects/set_test.rb +82 -0
- data/test/unit/fleakr/objects/tag_test.rb +98 -0
- data/test/unit/fleakr/objects/user_test.rb +91 -0
- data/test/unit/fleakr/support/attribute_test.rb +126 -0
- data/test/unit/fleakr/support/object_test.rb +129 -0
- data/test/unit/fleakr_test.rb +171 -0
- metadata +175 -0
@@ -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,97 @@
|
|
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
|
+
# [:authenticate?] Request will automatically be authenticated if Fleakr.token is available
|
14
|
+
# set this to false to force it not to authenticate
|
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
|
+
# TODO: need to find a way to move the unexpected behavior in Fleakr.token elsewhere
|
26
|
+
@api_options = options.extract!(:authenticate?)
|
27
|
+
|
28
|
+
@list = Hash.new
|
29
|
+
|
30
|
+
options.each {|k,v| self << ValueParameter.new(k.to_s, v) }
|
31
|
+
|
32
|
+
self << ValueParameter.new('api_key', Fleakr.api_key)
|
33
|
+
self << ValueParameter.new('auth_token', Fleakr.token.value) if authenticate?
|
34
|
+
end
|
35
|
+
|
36
|
+
# Add a new parameter (ValueParameter / FileParameter) to the list
|
37
|
+
#
|
38
|
+
def <<(parameter)
|
39
|
+
@list.merge!(parameter.name => parameter)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Should this parameter list be signed?
|
43
|
+
#
|
44
|
+
def sign?
|
45
|
+
!Fleakr.shared_secret.blank?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Should we send the auth_token with the request?
|
49
|
+
#
|
50
|
+
def authenticate?
|
51
|
+
@api_options.has_key?(:authenticate?) ? @api_options[:authenticate?] : !Fleakr.token.blank?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Access an individual parameter by key (symbol or string)
|
55
|
+
#
|
56
|
+
def [](key)
|
57
|
+
list[key.to_s]
|
58
|
+
end
|
59
|
+
|
60
|
+
def boundary # :nodoc:
|
61
|
+
@boundary ||= Digest::MD5.hexdigest(rand.to_s)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Generate the query string representation of this parameter
|
65
|
+
# list - e.g. <tt>foo=bar&blee=baz</tt>
|
66
|
+
#
|
67
|
+
def to_query
|
68
|
+
list.values.map {|element| element.to_query }.join('&')
|
69
|
+
end
|
70
|
+
|
71
|
+
# Generate the form representation of this parameter list including the
|
72
|
+
# boundary
|
73
|
+
#
|
74
|
+
def to_form
|
75
|
+
form = list.values.map {|p| "--#{self.boundary}\r\n#{p.to_form}" }.join
|
76
|
+
form << "--#{self.boundary}--"
|
77
|
+
|
78
|
+
form
|
79
|
+
end
|
80
|
+
|
81
|
+
def signature # :nodoc:
|
82
|
+
parameters_to_sign = @list.values.reject {|p| !p.include_in_signature? }
|
83
|
+
signature_text = parameters_to_sign.sort.map {|p| "#{p.name}#{p.value}" }.join
|
84
|
+
|
85
|
+
Digest::MD5.hexdigest("#{Fleakr.shared_secret}#{signature_text}")
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def list
|
90
|
+
list = @list
|
91
|
+
list.merge!('api_sig' => ValueParameter.new('api_sig', signature, false)) if self.sign?
|
92
|
+
|
93
|
+
list
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Api # :nodoc:
|
3
|
+
|
4
|
+
# = Response
|
5
|
+
#
|
6
|
+
# Response objects contain Hpricot documents that are traversed and parsed by
|
7
|
+
# the model objects. This class is never called directly but is instantiated
|
8
|
+
# during the request cycle (see: Fleakr::Api::MethodRequest.with_response!)
|
9
|
+
#
|
10
|
+
class Response
|
11
|
+
|
12
|
+
# Creates a new response from a raw XML string returned from a Request
|
13
|
+
def initialize(response_xml)
|
14
|
+
@response_xml = response_xml
|
15
|
+
end
|
16
|
+
|
17
|
+
# Return a document-based representation of the XML contained in the
|
18
|
+
# API response. This is an Hpricot document object
|
19
|
+
def body
|
20
|
+
@body ||= Hpricot.XML(@response_xml)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Did the response from the API contain errors?
|
24
|
+
def error?
|
25
|
+
(self.body/'rsp').attr('stat') != 'ok'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Access the API error if one exists
|
29
|
+
def error
|
30
|
+
Fleakr::Objects::Error.new(self.body) if self.error?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,75 @@
|
|
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, type = :create, options = {})
|
23
|
+
request = self.new(filename, type, 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, type, and options. Type
|
32
|
+
# is one of <tt>:create</tt> or <tt>:update</tt> to specify whether we are saving a new
|
33
|
+
# image or replacing an existing one.
|
34
|
+
#
|
35
|
+
# For a list of available options, see the documentation in Fleakr::Objects::Photo
|
36
|
+
#
|
37
|
+
def initialize(filename, type = :create, options = {})
|
38
|
+
@type = type
|
39
|
+
@options = options
|
40
|
+
|
41
|
+
@parameters = ParameterList.new(upload_options)
|
42
|
+
@parameters << FileParameter.new('photo', filename)
|
43
|
+
end
|
44
|
+
|
45
|
+
# A list of upload options for this upload request (see Fleakr::Api::Option)
|
46
|
+
#
|
47
|
+
def upload_options
|
48
|
+
option_list = @options.map {|key, value| Option.for(key, value) }
|
49
|
+
option_list.inject({}) {|hash, option| hash.merge(option.to_hash)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def headers # :nodoc:
|
53
|
+
{'Content-Type' => "multipart/form-data; boundary=#{self.parameters.boundary}"}
|
54
|
+
end
|
55
|
+
|
56
|
+
def send # :nodoc:
|
57
|
+
response = Net::HTTP.start(endpoint_uri.host, endpoint_uri.port) do |http|
|
58
|
+
logger.info("Sending upload request to: #{endpoint_uri}")
|
59
|
+
logger.debug("Request data:\n#{self.parameters.to_form}")
|
60
|
+
logger.debug("Request headers:\n#{self.headers.inspect}")
|
61
|
+
|
62
|
+
http.post(endpoint_uri.path, self.parameters.to_form, self.headers)
|
63
|
+
end
|
64
|
+
logger.debug("Response data:\n#{response.body}")
|
65
|
+
Response.new(response.body)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
def endpoint_uri
|
70
|
+
@endpoint_uri ||= URI.parse(ENDPOINT_URIS[self.type])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
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,8 @@
|
|
1
|
+
require "fleakr/api/response"
|
2
|
+
require "fleakr/api/method_request"
|
3
|
+
require "fleakr/api/option"
|
4
|
+
require "fleakr/api/upload_request"
|
5
|
+
require "fleakr/api/parameter_list"
|
6
|
+
require "fleakr/api/parameter"
|
7
|
+
require "fleakr/api/value_parameter"
|
8
|
+
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,60 @@
|
|
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
|
+
flickr_attribute :user_id, :from => 'auth/user@nsid'
|
21
|
+
flickr_attribute :user_name, :from => 'auth/user@username'
|
22
|
+
flickr_attribute :full_name, :from => 'auth/user@fullname'
|
23
|
+
|
24
|
+
# Retrieve a full authentication token from the supplied mini-token (e.g. 123-456-789)
|
25
|
+
#
|
26
|
+
def self.from_mini_token(mini_token)
|
27
|
+
from :mini_token, mini_token
|
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(auth_token)
|
34
|
+
from :auth_token, auth_token
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieve a full authentication token from the supplied frob
|
38
|
+
def self.from_frob(frob)
|
39
|
+
from :frob, frob
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.from(thing, value) # :nodoc:
|
43
|
+
api_methods = {
|
44
|
+
:mini_token => 'getFullToken',
|
45
|
+
:auth_token => 'checkToken',
|
46
|
+
:frob => 'getToken'
|
47
|
+
}
|
48
|
+
|
49
|
+
method = "auth.#{api_methods[thing]}"
|
50
|
+
|
51
|
+
parameters = {thing => value, :authenticate? => false}
|
52
|
+
response = Fleakr::Api::MethodRequest.with_response!(method, parameters)
|
53
|
+
|
54
|
+
self.new(response.body)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = Comment
|
5
|
+
#
|
6
|
+
# This class represents a comment that can be associated with a single photo or an
|
7
|
+
# entire photoset.
|
8
|
+
#
|
9
|
+
# == Attributes
|
10
|
+
#
|
11
|
+
# [id] The unique identifier for this comment
|
12
|
+
# [url] The direct URL / permalink to reference this comment
|
13
|
+
# [body] The comment itself - also available with <tt>to_s</tt>
|
14
|
+
#
|
15
|
+
class Comment
|
16
|
+
|
17
|
+
include Fleakr::Support::Object
|
18
|
+
|
19
|
+
find_all :by_photo_id, :call => 'photos.comments.getList', :path => 'comments/comment'
|
20
|
+
find_all :by_set_id, :using => :photoset_id, :call => 'photosets.comments.getList', :path => 'comments/comment'
|
21
|
+
|
22
|
+
flickr_attribute :id
|
23
|
+
flickr_attribute :author_id, :from => '@author'
|
24
|
+
flickr_attribute :created, :from => '@datecreate'
|
25
|
+
flickr_attribute :url, :from => '@permalink'
|
26
|
+
flickr_attribute :body, :from => '.'
|
27
|
+
|
28
|
+
# The user who supplied the comment. See Fleakr::Objects::User for more information
|
29
|
+
#
|
30
|
+
def author
|
31
|
+
@author ||= User.find_by_id(author_id)
|
32
|
+
end
|
33
|
+
|
34
|
+
# When was this comment created?
|
35
|
+
#
|
36
|
+
def created_at
|
37
|
+
Time.at(created.to_i)
|
38
|
+
end
|
39
|
+
|
40
|
+
# The contents of the comment - also available as <tt>body</tt>
|
41
|
+
#
|
42
|
+
def to_s
|
43
|
+
body
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
class Contact # :nodoc:
|
4
|
+
|
5
|
+
include Fleakr::Support::Object
|
6
|
+
|
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
|
+
|
12
|
+
# Retrieve a list of contacts for the specified user ID and return an initialized
|
13
|
+
# collection of #User objects
|
14
|
+
def self.find_all_by_user_id(user_id)
|
15
|
+
response = Fleakr::Api::MethodRequest.with_response!('contacts.getPublicList', :user_id => user_id)
|
16
|
+
(response.body/'contacts/contact').map {|c| Contact.new(c).to_user }
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_user
|
20
|
+
user = User.new
|
21
|
+
self.class.attributes.each do |attribute|
|
22
|
+
attribute_name = attribute.name
|
23
|
+
user.send("#{attribute.name}=".to_sym, self.send(attribute.name))
|
24
|
+
end
|
25
|
+
|
26
|
+
user
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
# = Error
|
4
|
+
#
|
5
|
+
# == Accessors
|
6
|
+
#
|
7
|
+
# This class is a simple wrapper for the error response that the API returns. There are
|
8
|
+
# a couple of attributes:
|
9
|
+
#
|
10
|
+
# [code] The error code as described in the documentation
|
11
|
+
# [message] The associated error message
|
12
|
+
#
|
13
|
+
class Error
|
14
|
+
|
15
|
+
include Fleakr::Support::Object
|
16
|
+
|
17
|
+
flickr_attribute :code, :from => 'err@code'
|
18
|
+
flickr_attribute :message, :from => 'err@msg'
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = Group
|
5
|
+
#
|
6
|
+
# == Accessors
|
7
|
+
#
|
8
|
+
# [id] This group's ID
|
9
|
+
# [name] The name of the group
|
10
|
+
#
|
11
|
+
# == Associations
|
12
|
+
#
|
13
|
+
# [photos] The photos that are in this group
|
14
|
+
#
|
15
|
+
class Group
|
16
|
+
|
17
|
+
include Fleakr::Support::Object
|
18
|
+
|
19
|
+
flickr_attribute :id, :from => '@nsid'
|
20
|
+
flickr_attribute :name
|
21
|
+
flickr_attribute :adult_flag, :from => '@eighteenplus'
|
22
|
+
|
23
|
+
find_all :by_user_id, :call => 'people.getPublicGroups', :path => 'groups/group'
|
24
|
+
|
25
|
+
has_many :photos
|
26
|
+
|
27
|
+
scoped_search
|
28
|
+
|
29
|
+
# Is this group adult-only? (e.g. only 18+ allowed to view)
|
30
|
+
def adult?
|
31
|
+
(adult_flag == '1')
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects
|
3
|
+
|
4
|
+
# = Image
|
5
|
+
#
|
6
|
+
# This class wraps the functionality for saving remote images to disk. It's called
|
7
|
+
# by the Fleakr::Objects::Photo class to save an image with a specific size and would
|
8
|
+
# typically never be called directly.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
#
|
12
|
+
# user = Fleakr.user('brownout')
|
13
|
+
# user.photos.first.small.save_to('/tmp')
|
14
|
+
#
|
15
|
+
# == Attributes
|
16
|
+
#
|
17
|
+
# [size] The name of this image's size (e.g. Square, Large, etc...)
|
18
|
+
# [width] The width of this image
|
19
|
+
# [height] The height of this image
|
20
|
+
# [url] The direct URL for this image
|
21
|
+
# [page] The page on Flickr that represents this photo
|
22
|
+
#
|
23
|
+
class Image
|
24
|
+
|
25
|
+
include Fleakr::Support::Object
|
26
|
+
|
27
|
+
flickr_attribute :width, :height
|
28
|
+
flickr_attribute :size, :from => '@label'
|
29
|
+
flickr_attribute :url, :from => '@source'
|
30
|
+
flickr_attribute :page, :from => '@url'
|
31
|
+
|
32
|
+
find_all :by_photo_id, :call => 'photos.getSizes', :path => 'sizes/size'
|
33
|
+
|
34
|
+
# The filename portion of the image (without the full URL)
|
35
|
+
def filename
|
36
|
+
self.url.match(/([^\/]+)$/)[1]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Save this image to the specified directory or file. If the target is a
|
40
|
+
# directory, the file will be created with the original filename from Flickr.
|
41
|
+
# If the target is a file, it will be saved with the specified name. In the
|
42
|
+
# case that the target file already exists, this method will overwrite it.
|
43
|
+
def save_to(target, prefix = nil)
|
44
|
+
destination = File.directory?(target) ? "#{target}/#{prefix}#{self.filename}" : "#{target}"
|
45
|
+
File.open(destination, 'w') {|f| f << Net::HTTP.get(URI.parse(self.url)) }
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|