latompa-fleakr 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 +37 -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 +148 -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 +171 -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 +70 -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 +247 -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,148 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = Photo
|
5
|
+
#
|
6
|
+
# Handles both the retrieval of Photo objects from various associations (e.g. User / Set) as
|
7
|
+
# well as the ability to upload images to the Flickr site.
|
8
|
+
#
|
9
|
+
# == Attributes
|
10
|
+
#
|
11
|
+
# [id] The ID for this photo
|
12
|
+
# [title] The title of this photo
|
13
|
+
# [description] The description of this photo
|
14
|
+
# [secret] This photo's secret (used for sharing photo without permissions checking)
|
15
|
+
# [comment_count] Count of the comments attached to this photo
|
16
|
+
# [url] This photo's page on Flickr
|
17
|
+
# [square] The tiny square representation of this photo
|
18
|
+
# [thumbnail] The thumbnail for this photo
|
19
|
+
# [small] The small representation of this photo
|
20
|
+
# [medium] The medium representation of this photo
|
21
|
+
# [large] The large representation of this photo
|
22
|
+
# [original] The original photo
|
23
|
+
# [previous] The previous photo based on the current context
|
24
|
+
# [next] The next photo based on the current context
|
25
|
+
#
|
26
|
+
# == Associations
|
27
|
+
#
|
28
|
+
# [images] The underlying images for this photo.
|
29
|
+
# [tags] The tags for this photo.
|
30
|
+
# [comments] The comments associated with this photo
|
31
|
+
#
|
32
|
+
class Photo
|
33
|
+
|
34
|
+
# Available sizes for this photo
|
35
|
+
SIZES = [:square, :thumbnail, :small, :medium, :large, :original]
|
36
|
+
|
37
|
+
include Fleakr::Support::Object
|
38
|
+
extend Forwardable
|
39
|
+
|
40
|
+
def_delegators :context, :next, :previous
|
41
|
+
|
42
|
+
flickr_attribute :id, :from => ['@id', 'photoid']
|
43
|
+
flickr_attribute :title, :description, :secret, :posted, :taken, :url
|
44
|
+
flickr_attribute :farm_id, :from => '@farm'
|
45
|
+
flickr_attribute :server_id, :from => '@server'
|
46
|
+
flickr_attribute :owner_id, :from => ['@owner', 'owner@nsid']
|
47
|
+
flickr_attribute :updated, :from => '@lastupdate'
|
48
|
+
flickr_attribute :comment_count, :from => 'comments'
|
49
|
+
flickr_attribute :originalsecret
|
50
|
+
|
51
|
+
# TODO:
|
52
|
+
# * visibility
|
53
|
+
# * editability
|
54
|
+
# * usage
|
55
|
+
|
56
|
+
find_all :by_set_id, :using => :photoset_id, :call => 'photosets.getPhotos', :path => 'photoset/photo'
|
57
|
+
find_all :by_user_id, :call => 'people.getPublicPhotos', :path => 'photos/photo'
|
58
|
+
find_all :by_group_id, :call => 'groups.pools.getPhotos', :path => 'photos/photo'
|
59
|
+
|
60
|
+
find_one :by_id, :using => :photo_id, :call => 'photos.getInfo'
|
61
|
+
|
62
|
+
lazily_load :posted, :taken, :updated, :comment_count, :url, :description, :with => :load_info
|
63
|
+
|
64
|
+
has_many :images, :tags, :comments
|
65
|
+
|
66
|
+
# Upload the photo specified by <tt>filename</tt> to the user's Flickr account. When uploading,
|
67
|
+
# there are several options available (none are required):
|
68
|
+
#
|
69
|
+
# [:title] The title for this photo. Any string is allowed.
|
70
|
+
# [:description] The description for this photo. Any string is allowed.
|
71
|
+
# [:tags] A collection of tags for this photo. This can be a string or array of strings.
|
72
|
+
# [:viewable_by] Who can view this photo? Acceptable values are one of <tt>:everyone</tt>,
|
73
|
+
# <tt>:friends</tt> or <tt>:family</tt>. This can also take an array of values
|
74
|
+
# (e.g. <tt>[:friends, :family]</tt>) to make it viewable by friends and family.
|
75
|
+
# [:level] The safety level of this photo. Acceptable values are one of <tt>:safe</tt>,
|
76
|
+
# <tt>:moderate</tt>, or <tt>:restricted</tt>.
|
77
|
+
# [:type] The type of image this is. Acceptable values are one of <tt>:photo</tt>,
|
78
|
+
# <tt>:screenshot</tt>, or <tt>:other</tt>.
|
79
|
+
# [:hide?] Should this photo be hidden from public searches? Takes a boolean.
|
80
|
+
#
|
81
|
+
def self.upload(filename, options = {})
|
82
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename, :create, options)
|
83
|
+
photo = Photo.new(response.body)
|
84
|
+
Photo.find_by_id(photo.id)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Replace the current photo's image with the one specified by filename. This
|
88
|
+
# call requires authentication.
|
89
|
+
#
|
90
|
+
def replace_with(filename)
|
91
|
+
response = Fleakr::Api::UploadRequest.with_response!(filename, :update, :photo_id => self.id)
|
92
|
+
self.populate_from(response.body)
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO: Refactor this to remove duplication w/ User#load_info - possibly in the lazily_load class method
|
97
|
+
def load_info # :nodoc:
|
98
|
+
response = Fleakr::Api::MethodRequest.with_response!('photos.getInfo', :photo_id => self.id)
|
99
|
+
self.populate_from(response.body)
|
100
|
+
end
|
101
|
+
|
102
|
+
def context # :nodoc:
|
103
|
+
@context ||= begin
|
104
|
+
response = Fleakr::Api::MethodRequest.with_response!('photos.getContext', :photo_id => self.id)
|
105
|
+
PhotoContext.new(response.body)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# The user who uploaded this photo. See Fleakr::Objects::User for additional information.
|
110
|
+
#
|
111
|
+
def owner
|
112
|
+
@owner ||= User.find_by_id(owner_id)
|
113
|
+
end
|
114
|
+
|
115
|
+
# When was this photo posted?
|
116
|
+
#
|
117
|
+
def posted_at
|
118
|
+
Time.at(posted.to_i)
|
119
|
+
end
|
120
|
+
|
121
|
+
# When was this photo taken?
|
122
|
+
#
|
123
|
+
def taken_at
|
124
|
+
Time.parse(taken)
|
125
|
+
end
|
126
|
+
|
127
|
+
# When was this photo last updated? This includes addition of tags and other metadata.
|
128
|
+
#
|
129
|
+
def updated_at
|
130
|
+
Time.at(updated.to_i)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Create methods to access image sizes by name
|
134
|
+
SIZES.each do |size|
|
135
|
+
define_method(size) do
|
136
|
+
images_by_size[size]
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
def images_by_size
|
142
|
+
image_sizes = SIZES.inject({}) {|l,o| l.merge(o => nil)}
|
143
|
+
self.images.inject(image_sizes) {|l,o| l.merge!(o.size.downcase.to_sym => o) }
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = PhotoContext
|
5
|
+
#
|
6
|
+
# This class represents the context for a photo as retrieved from the API. It's not
|
7
|
+
# intended to be used directly, but is used in conjunction with Photo#previous and
|
8
|
+
# Photo#next
|
9
|
+
#
|
10
|
+
# == Attributes
|
11
|
+
#
|
12
|
+
# [count] The number of photos available
|
13
|
+
|
14
|
+
class PhotoContext
|
15
|
+
|
16
|
+
include Fleakr::Support::Object
|
17
|
+
|
18
|
+
flickr_attribute :count
|
19
|
+
flickr_attribute :next_id, :from => 'nextphoto@id'
|
20
|
+
flickr_attribute :previous_id, :from => 'prevphoto@id'
|
21
|
+
|
22
|
+
# Is there a previous photo available for the current photo?
|
23
|
+
#
|
24
|
+
def previous?
|
25
|
+
previous_id != '0'
|
26
|
+
end
|
27
|
+
|
28
|
+
# The previous photo if one is available
|
29
|
+
#
|
30
|
+
def previous
|
31
|
+
Photo.find_by_id(previous_id) if previous?
|
32
|
+
end
|
33
|
+
|
34
|
+
# Is there a next photo available for the current photo?
|
35
|
+
#
|
36
|
+
def next?
|
37
|
+
next_id != '0'
|
38
|
+
end
|
39
|
+
|
40
|
+
# The next photo if one is available
|
41
|
+
#
|
42
|
+
def next
|
43
|
+
Photo.find_by_id(next_id) if next?
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
class Search
|
4
|
+
|
5
|
+
# Create a new search
|
6
|
+
def initialize(search_options)
|
7
|
+
@search_options = search_options
|
8
|
+
end
|
9
|
+
|
10
|
+
# Retrieve search results from the API
|
11
|
+
def results
|
12
|
+
@results ||= begin
|
13
|
+
response = Fleakr::Api::MethodRequest.with_response!('photos.search', parameters)
|
14
|
+
(response.body/'rsp/photos/photo').map {|p| Photo.new(p) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def tag_list
|
20
|
+
Array(@search_options[:tags]).join(',')
|
21
|
+
end
|
22
|
+
|
23
|
+
def parameters
|
24
|
+
@search_options.merge!(:tags => tag_list) if tag_list.length > 0
|
25
|
+
@search_options
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = Set
|
5
|
+
#
|
6
|
+
# == Attributes
|
7
|
+
#
|
8
|
+
# [id] The ID for this photoset
|
9
|
+
# [title] The title of this photoset
|
10
|
+
# [description] The description of this set
|
11
|
+
# [count] Count of photos in this set
|
12
|
+
#
|
13
|
+
# == Associations
|
14
|
+
#
|
15
|
+
# [photos] The collection of photos for this set. See Fleakr::Objects::Photo
|
16
|
+
# [comments] All comments associated with this set. See Fleakr::Objects::Comment
|
17
|
+
#
|
18
|
+
class Set
|
19
|
+
|
20
|
+
include Fleakr::Support::Object
|
21
|
+
|
22
|
+
has_many :photos, :comments
|
23
|
+
|
24
|
+
flickr_attribute :id, :title, :description
|
25
|
+
flickr_attribute :count, :from => '@photos'
|
26
|
+
|
27
|
+
find_all :by_user_id, :call => 'photosets.getList', :path => 'photosets/photoset'
|
28
|
+
|
29
|
+
# Save all photos in this set to the specified directory for the specified size. Allowed
|
30
|
+
# Sizes include <tt>:square</tt>, <tt>:small</tt>, <tt>:thumbnail</tt>, <tt>:medium</tt>,
|
31
|
+
# <tt>:large</tt>, and <tt>:original</tt>. When saving the set, this method will create
|
32
|
+
# a subdirectory based on the set's title.
|
33
|
+
#
|
34
|
+
def save_to(path, size)
|
35
|
+
target = "#{path}/#{self.title}"
|
36
|
+
FileUtils.mkdir(target) unless File.exist?(target)
|
37
|
+
|
38
|
+
self.photos.each_with_index do |photo, index|
|
39
|
+
image = photo.send(size)
|
40
|
+
image.save_to(target, file_prefix(index)) unless image.nil?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def file_prefix(index) # :nodoc:
|
45
|
+
sprintf("%0#{self.count.length}d_", (index + 1))
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = Tag
|
5
|
+
#
|
6
|
+
# This class represents a tag that can be associated with a photo or an individual user.
|
7
|
+
#
|
8
|
+
# == Attributes
|
9
|
+
#
|
10
|
+
# [id] The unique identifier for this tag
|
11
|
+
# [raw] The raw, user-entered value for this tag
|
12
|
+
# [value] The formatted value for this tag. Also available through <tt>to_s</tt>
|
13
|
+
#
|
14
|
+
class Tag
|
15
|
+
|
16
|
+
include Fleakr::Support::Object
|
17
|
+
|
18
|
+
flickr_attribute :id, :raw
|
19
|
+
flickr_attribute :author_id, :from => '@author'
|
20
|
+
flickr_attribute :value, :from => '.' # pull this from the current node
|
21
|
+
flickr_attribute :machine_flag, :from => '@machine_tag'
|
22
|
+
|
23
|
+
find_all :by_photo_id, :call => 'tags.getListPhoto', :path => 'photo/tags/tag'
|
24
|
+
find_all :by_user_id, :call => 'tags.getListUser', :path => 'who/tags/tag'
|
25
|
+
|
26
|
+
# The first user who created this tag. See Fleakr::Objects::User for more information
|
27
|
+
#
|
28
|
+
def author
|
29
|
+
@author ||= User.find_by_id(author_id) unless author_id.nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
# A list of related tags. Each of the objects in the collection is an instance of Tag
|
33
|
+
#
|
34
|
+
def related
|
35
|
+
@related ||= begin
|
36
|
+
response = Fleakr::Api::MethodRequest.with_response!('tags.getRelated', :tag => value)
|
37
|
+
(response.body/'rsp/tags/tag').map {|e| Tag.new(e) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Is this a machine tag?
|
42
|
+
#
|
43
|
+
def machine?
|
44
|
+
machine_flag != '0'
|
45
|
+
end
|
46
|
+
|
47
|
+
# The formatted value of the tag. Also available as <tt>value</tt>
|
48
|
+
#
|
49
|
+
def to_s
|
50
|
+
value
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Objects # :nodoc:
|
3
|
+
|
4
|
+
# = User
|
5
|
+
#
|
6
|
+
# == Accessors
|
7
|
+
#
|
8
|
+
# This class maps directly onto the flickr.people.* API methods and provides the following attributes
|
9
|
+
# for a user:
|
10
|
+
#
|
11
|
+
# [id] The ID for this user (also referred to as the NSID in the API docs)
|
12
|
+
# [username] This user's username
|
13
|
+
# [name] This user's full name (if entered)
|
14
|
+
# [location] This user's location (if entered)
|
15
|
+
# [photos_url] The direct URL to this user's photostream
|
16
|
+
# [profile_url] The direct URL to this user's profile
|
17
|
+
# [photos_count] The number of photos that this user has uploaded
|
18
|
+
# [icon_url] This user's buddy icon (or a default one if an icon wasn't uploaded)
|
19
|
+
# [pro?] Does this user have a pro account?
|
20
|
+
# [admin?] Is this user an admin?
|
21
|
+
#
|
22
|
+
# == Associations
|
23
|
+
#
|
24
|
+
# The User class is pretty central to many of the other data available across the system, so there are a
|
25
|
+
# few associations available to a user:
|
26
|
+
#
|
27
|
+
# [sets] A list of this user's public sets (newest first). See Fleakr::Objects::Set for more information.
|
28
|
+
# [groups] A list of this user's public groups. See Fleakr::Objects::Group.
|
29
|
+
# [photos] A list of this user's public photos (newest first). See Fleakr::Objects::Photo.
|
30
|
+
# [contacts] A list of this user's contacts - these are simply User objects
|
31
|
+
# [tags] The tags associated with this user
|
32
|
+
#
|
33
|
+
# == Examples
|
34
|
+
#
|
35
|
+
# Access to a specific user is typically done through the Fleakr.user method:
|
36
|
+
#
|
37
|
+
# user = Fleakr.user('brownout')
|
38
|
+
# user.id
|
39
|
+
# user.username
|
40
|
+
# user.sets
|
41
|
+
# user.contacts
|
42
|
+
#
|
43
|
+
class User
|
44
|
+
|
45
|
+
include Fleakr::Support::Object
|
46
|
+
|
47
|
+
flickr_attribute :id, :from => 'user@nsid'
|
48
|
+
flickr_attribute :username, :location
|
49
|
+
flickr_attribute :name, :from => 'person/realname'
|
50
|
+
flickr_attribute :photos_url, :from => 'person/photosurl'
|
51
|
+
flickr_attribute :profile_url, :from => 'person/profileurl'
|
52
|
+
flickr_attribute :photos_count, :from => 'person/photos/count'
|
53
|
+
flickr_attribute :icon_server, :from => 'person@iconserver'
|
54
|
+
flickr_attribute :icon_farm, :from => 'person@iconfarm'
|
55
|
+
flickr_attribute :pro, :from => 'person@ispro'
|
56
|
+
flickr_attribute :admin, :from => 'person@isadmin'
|
57
|
+
|
58
|
+
has_many :sets, :groups, :photos, :contacts, :tags
|
59
|
+
|
60
|
+
find_one :by_username, :call => 'people.findByUsername'
|
61
|
+
find_one :by_email, :using => :find_email, :call => 'people.findByEmail'
|
62
|
+
find_one :by_id, :using => :user_id, :call => 'people.getInfo'
|
63
|
+
|
64
|
+
lazily_load :name, :photos_url, :profile_url, :photos_count, :with => :load_info
|
65
|
+
lazily_load :icon_server, :icon_farm, :pro, :admin, :with => :load_info
|
66
|
+
|
67
|
+
scoped_search
|
68
|
+
|
69
|
+
# Is this a pro account?
|
70
|
+
def pro?
|
71
|
+
(self.pro.to_i == 0) ? false : true
|
72
|
+
end
|
73
|
+
|
74
|
+
# Is this user an admin?
|
75
|
+
def admin?
|
76
|
+
(self.admin.to_i == 0) ? false : true
|
77
|
+
end
|
78
|
+
|
79
|
+
# This user's buddy icon
|
80
|
+
def icon_url
|
81
|
+
if self.icon_server.to_i > 0
|
82
|
+
"http://farm#{self.icon_farm}.static.flickr.com/#{self.icon_server}/buddyicons/#{self.id}.jpg"
|
83
|
+
else
|
84
|
+
'http://www.flickr.com/images/buddyicon.jpg'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def load_info # :nodoc:
|
89
|
+
response = Fleakr::Api::MethodRequest.with_response!('people.getInfo', :user_id => self.id)
|
90
|
+
self.populate_from(response.body)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'fleakr/objects/authentication_token'
|
2
|
+
require 'fleakr/objects/contact'
|
3
|
+
require 'fleakr/objects/error'
|
4
|
+
require 'fleakr/objects/group'
|
5
|
+
require 'fleakr/objects/image'
|
6
|
+
require 'fleakr/objects/photo_context'
|
7
|
+
require 'fleakr/objects/photo'
|
8
|
+
require 'fleakr/objects/comment'
|
9
|
+
require 'fleakr/objects/tag'
|
10
|
+
require 'fleakr/objects/search'
|
11
|
+
require 'fleakr/objects/set'
|
12
|
+
require 'fleakr/objects/user'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Support # :nodoc:all
|
3
|
+
class Attribute
|
4
|
+
|
5
|
+
# TODO: Refactor the location / attribute logic into a Source class
|
6
|
+
|
7
|
+
attr_reader :name, :sources
|
8
|
+
|
9
|
+
def initialize(name, sources = nil)
|
10
|
+
@name = name.to_sym
|
11
|
+
|
12
|
+
@sources = Array(sources)
|
13
|
+
@sources << @name.to_s if @sources.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def split(source)
|
17
|
+
location, attribute = source.split('@')
|
18
|
+
location = self.name.to_s if location.blank?
|
19
|
+
|
20
|
+
[location, attribute]
|
21
|
+
end
|
22
|
+
|
23
|
+
def node_for(document, source)
|
24
|
+
document.at(location(source)) || document.search("//[@#{attribute(source)}]").first
|
25
|
+
end
|
26
|
+
|
27
|
+
def attribute(source)
|
28
|
+
location, attribute = source.split('@')
|
29
|
+
attribute || location
|
30
|
+
end
|
31
|
+
|
32
|
+
def location(source)
|
33
|
+
split(source).first
|
34
|
+
end
|
35
|
+
|
36
|
+
def value_from(document)
|
37
|
+
values = sources.map do |source|
|
38
|
+
node = node_for(document, source)
|
39
|
+
(node.attributes[attribute(source)] || node.inner_text) unless node.nil?
|
40
|
+
end
|
41
|
+
values.compact.first
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Fleakr
|
2
|
+
module Support # :nodoc:all
|
3
|
+
module Object
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def attributes
|
8
|
+
@attributes ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def flickr_attribute(*names_and_options)
|
12
|
+
options = names_and_options.extract_options!
|
13
|
+
|
14
|
+
names_and_options.each do |name|
|
15
|
+
self.attributes << Attribute.new(name, options[:from])
|
16
|
+
class_eval "attr_accessor :#{name}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_many(*attributes)
|
21
|
+
class_name = self.name
|
22
|
+
|
23
|
+
attributes.each do |attribute|
|
24
|
+
target = "Fleakr::Objects::#{attribute.to_s.classify}"
|
25
|
+
finder_attribute = "#{class_name.demodulize.underscore}_id"
|
26
|
+
|
27
|
+
class_eval <<-CODE
|
28
|
+
def #{attribute}
|
29
|
+
@#{attribute} ||= #{target}.send("find_all_by_#{finder_attribute}".to_sym, self.id)
|
30
|
+
end
|
31
|
+
CODE
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_all(condition, options)
|
36
|
+
attribute = options[:using].nil? ? condition.to_s.sub(/^by_/, '') : options[:using]
|
37
|
+
target_class = options[:class_name].nil? ? self.name : "Fleakr::Objects::#{options[:class_name]}"
|
38
|
+
|
39
|
+
class_eval <<-CODE
|
40
|
+
def self.find_all_#{condition}(value, options = {})
|
41
|
+
options.merge!(:#{attribute} => value)
|
42
|
+
|
43
|
+
response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', options)
|
44
|
+
(response.body/'rsp/#{options[:path]}').map {|e| #{target_class}.new(e) }
|
45
|
+
end
|
46
|
+
CODE
|
47
|
+
end
|
48
|
+
|
49
|
+
def find_one(condition, options)
|
50
|
+
attribute = options[:using].nil? ? condition.to_s.sub(/^by_/, '') : options[:using]
|
51
|
+
|
52
|
+
class_eval <<-CODE
|
53
|
+
def self.find_#{condition}(value, options = {})
|
54
|
+
options.merge!(:#{attribute} => value)
|
55
|
+
|
56
|
+
response = Fleakr::Api::MethodRequest.with_response!('#{options[:call]}', options)
|
57
|
+
#{self.name}.new(response.body)
|
58
|
+
end
|
59
|
+
CODE
|
60
|
+
end
|
61
|
+
|
62
|
+
def scoped_search
|
63
|
+
key = "#{self.name.demodulize.underscore.downcase}_id".to_sym
|
64
|
+
|
65
|
+
class_eval <<-CODE
|
66
|
+
def search(search_text)
|
67
|
+
Fleakr::Objects::Search.new(:text => search_text, :#{key} => self.id).results
|
68
|
+
end
|
69
|
+
CODE
|
70
|
+
end
|
71
|
+
|
72
|
+
def lazily_load(*attributes)
|
73
|
+
options = attributes.extract_options!
|
74
|
+
|
75
|
+
attributes.each do |attribute|
|
76
|
+
class_eval <<-CODE
|
77
|
+
def #{attribute}_with_loading
|
78
|
+
self.send(:#{options[:with]}) if @#{attribute}.nil?
|
79
|
+
#{attribute}_without_loading
|
80
|
+
end
|
81
|
+
alias_method_chain :#{attribute}, :loading
|
82
|
+
CODE
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
module InstanceMethods
|
89
|
+
|
90
|
+
def initialize(document = nil)
|
91
|
+
self.populate_from(document) unless document.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
def populate_from(document)
|
95
|
+
self.class.attributes.each do |attribute|
|
96
|
+
value = attribute.value_from(document)
|
97
|
+
self.send("#{attribute.name}=".to_sym, value) unless value.nil?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.included(other)
|
104
|
+
other.send(:extend, Fleakr::Support::Object::ClassMethods)
|
105
|
+
other.send(:include, Fleakr::Support::Object::InstanceMethods)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|