latompa-fleakr 0.5.1

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/api/file_parameter.rb +47 -0
  4. data/lib/fleakr/api/method_request.rb +66 -0
  5. data/lib/fleakr/api/option.rb +175 -0
  6. data/lib/fleakr/api/parameter.rb +35 -0
  7. data/lib/fleakr/api/parameter_list.rb +97 -0
  8. data/lib/fleakr/api/response.rb +35 -0
  9. data/lib/fleakr/api/upload_request.rb +75 -0
  10. data/lib/fleakr/api/value_parameter.rb +36 -0
  11. data/lib/fleakr/api.rb +8 -0
  12. data/lib/fleakr/core_ext/false_class.rb +7 -0
  13. data/lib/fleakr/core_ext/hash.rb +22 -0
  14. data/lib/fleakr/core_ext/true_class.rb +7 -0
  15. data/lib/fleakr/core_ext.rb +3 -0
  16. data/lib/fleakr/objects/authentication_token.rb +60 -0
  17. data/lib/fleakr/objects/comment.rb +49 -0
  18. data/lib/fleakr/objects/contact.rb +37 -0
  19. data/lib/fleakr/objects/error.rb +22 -0
  20. data/lib/fleakr/objects/group.rb +36 -0
  21. data/lib/fleakr/objects/image.rb +50 -0
  22. data/lib/fleakr/objects/photo.rb +148 -0
  23. data/lib/fleakr/objects/photo_context.rb +49 -0
  24. data/lib/fleakr/objects/search.rb +30 -0
  25. data/lib/fleakr/objects/set.rb +50 -0
  26. data/lib/fleakr/objects/tag.rb +56 -0
  27. data/lib/fleakr/objects/user.rb +95 -0
  28. data/lib/fleakr/objects.rb +12 -0
  29. data/lib/fleakr/support/attribute.rb +46 -0
  30. data/lib/fleakr/support/object.rb +110 -0
  31. data/lib/fleakr/support.rb +2 -0
  32. data/lib/fleakr/version.rb +13 -0
  33. data/lib/fleakr.rb +171 -0
  34. data/test/fixtures/auth.checkToken.xml +8 -0
  35. data/test/fixtures/auth.getFullToken.xml +8 -0
  36. data/test/fixtures/auth.getToken.xml +8 -0
  37. data/test/fixtures/contacts.getPublicList.xml +7 -0
  38. data/test/fixtures/groups.pools.getPhotos.xml +7 -0
  39. data/test/fixtures/people.findByEmail.xml +6 -0
  40. data/test/fixtures/people.findByUsername.xml +6 -0
  41. data/test/fixtures/people.getInfo.xml +18 -0
  42. data/test/fixtures/people.getPublicGroups.xml +7 -0
  43. data/test/fixtures/people.getPublicPhotos.xml +7 -0
  44. data/test/fixtures/photos.comments.getList.xml +7 -0
  45. data/test/fixtures/photos.getContext.xml +6 -0
  46. data/test/fixtures/photos.getInfo.xml +20 -0
  47. data/test/fixtures/photos.getSizes.xml +10 -0
  48. data/test/fixtures/photos.search.xml +7 -0
  49. data/test/fixtures/photosets.comments.getList.xml +7 -0
  50. data/test/fixtures/photosets.getList.xml +13 -0
  51. data/test/fixtures/photosets.getPhotos.xml +7 -0
  52. data/test/fixtures/tags.getListPhoto.xml +9 -0
  53. data/test/fixtures/tags.getListUser.xml +10 -0
  54. data/test/fixtures/tags.getRelated.xml +9 -0
  55. data/test/test_helper.rb +141 -0
  56. data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
  57. data/test/unit/fleakr/api/method_request_test.rb +94 -0
  58. data/test/unit/fleakr/api/option_test.rb +179 -0
  59. data/test/unit/fleakr/api/parameter_list_test.rb +176 -0
  60. data/test/unit/fleakr/api/parameter_test.rb +34 -0
  61. data/test/unit/fleakr/api/response_test.rb +49 -0
  62. data/test/unit/fleakr/api/upload_request_test.rb +149 -0
  63. data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
  64. data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
  65. data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
  66. data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
  67. data/test/unit/fleakr/objects/authentication_token_test.rb +61 -0
  68. data/test/unit/fleakr/objects/comment_test.rb +66 -0
  69. data/test/unit/fleakr/objects/contact_test.rb +70 -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 +247 -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
@@ -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
@@ -0,0 +1,2 @@
1
+ require 'fleakr/support/attribute'
2
+ require 'fleakr/support/object'
@@ -0,0 +1,13 @@
1
+ module Fleakr
2
+ module Version # :nodoc:
3
+
4
+ MAJOR = 0
5
+ MINOR = 5
6
+ TINY = 0
7
+
8
+ def self.to_s
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end