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.
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 +31 -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 +147 -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 +164 -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 +61 -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 +246 -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,147 @@
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
+
50
+ # TODO:
51
+ # * visibility
52
+ # * editability
53
+ # * usage
54
+
55
+ find_all :by_set_id, :using => :photoset_id, :call => 'photosets.getPhotos', :path => 'photoset/photo'
56
+ find_all :by_user_id, :call => 'people.getPublicPhotos', :path => 'photos/photo'
57
+ find_all :by_group_id, :call => 'groups.pools.getPhotos', :path => 'photos/photo'
58
+
59
+ find_one :by_id, :using => :photo_id, :call => 'photos.getInfo'
60
+
61
+ lazily_load :posted, :taken, :updated, :comment_count, :url, :description, :with => :load_info
62
+
63
+ has_many :images, :tags, :comments
64
+
65
+ # Upload the photo specified by <tt>filename</tt> to the user's Flickr account. When uploading,
66
+ # there are several options available (none are required):
67
+ #
68
+ # [:title] The title for this photo. Any string is allowed.
69
+ # [:description] The description for this photo. Any string is allowed.
70
+ # [:tags] A collection of tags for this photo. This can be a string or array of strings.
71
+ # [:viewable_by] Who can view this photo? Acceptable values are one of <tt>:everyone</tt>,
72
+ # <tt>:friends</tt> or <tt>:family</tt>. This can also take an array of values
73
+ # (e.g. <tt>[:friends, :family]</tt>) to make it viewable by friends and family.
74
+ # [:level] The safety level of this photo. Acceptable values are one of <tt>:safe</tt>,
75
+ # <tt>:moderate</tt>, or <tt>:restricted</tt>.
76
+ # [:type] The type of image this is. Acceptable values are one of <tt>:photo</tt>,
77
+ # <tt>:screenshot</tt>, or <tt>:other</tt>.
78
+ # [:hide?] Should this photo be hidden from public searches? Takes a boolean.
79
+ #
80
+ def self.upload(filename, options = {})
81
+ response = Fleakr::Api::UploadRequest.with_response!(filename, :create, options)
82
+ photo = Photo.new(response.body)
83
+ Photo.find_by_id(photo.id)
84
+ end
85
+
86
+ # Replace the current photo's image with the one specified by filename. This
87
+ # call requires authentication.
88
+ #
89
+ def replace_with(filename)
90
+ response = Fleakr::Api::UploadRequest.with_response!(filename, :update, :photo_id => self.id)
91
+ self.populate_from(response.body)
92
+ self
93
+ end
94
+
95
+ # TODO: Refactor this to remove duplication w/ User#load_info - possibly in the lazily_load class method
96
+ def load_info # :nodoc:
97
+ response = Fleakr::Api::MethodRequest.with_response!('photos.getInfo', :photo_id => self.id)
98
+ self.populate_from(response.body)
99
+ end
100
+
101
+ def context # :nodoc:
102
+ @context ||= begin
103
+ response = Fleakr::Api::MethodRequest.with_response!('photos.getContext', :photo_id => self.id)
104
+ PhotoContext.new(response.body)
105
+ end
106
+ end
107
+
108
+ # The user who uploaded this photo. See Fleakr::Objects::User for additional information.
109
+ #
110
+ def owner
111
+ @owner ||= User.find_by_id(owner_id)
112
+ end
113
+
114
+ # When was this photo posted?
115
+ #
116
+ def posted_at
117
+ Time.at(posted.to_i)
118
+ end
119
+
120
+ # When was this photo taken?
121
+ #
122
+ def taken_at
123
+ Time.parse(taken)
124
+ end
125
+
126
+ # When was this photo last updated? This includes addition of tags and other metadata.
127
+ #
128
+ def updated_at
129
+ Time.at(updated.to_i)
130
+ end
131
+
132
+ # Create methods to access image sizes by name
133
+ SIZES.each do |size|
134
+ define_method(size) do
135
+ images_by_size[size]
136
+ end
137
+ end
138
+
139
+ private
140
+ def images_by_size
141
+ image_sizes = SIZES.inject({}) {|l,o| l.merge(o => nil)}
142
+ self.images.inject(image_sizes) {|l,o| l.merge!(o.size.downcase.to_sym => o) }
143
+ end
144
+
145
+ end
146
+ end
147
+ 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, :location, :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