reagent-fleakr 0.1.2 → 0.1.3

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.markdown CHANGED
@@ -55,9 +55,18 @@ You can also grab photos for a particular set:
55
55
  >> user.sets.first.photos.first.title
56
56
  => "Untitled1"
57
57
 
58
+ If you would prefer to just search photos, you can do that by tag for now:
59
+
60
+ >> search = Fleakr::Search.new(:tags => %w(macro))
61
+ => [#<Fleakr::Photo:0x118bc70 @title="Demure", @id="3076049945">,
62
+ #<Fleakr::Photo:0x118b7d4 @title="Bark fly on Bay leaf", @id="3076052409">, ...
63
+ >> search.results.first.title
64
+ => "Demure"
65
+ >> search.results.first.id
66
+ => "3076049945"
67
+
58
68
  ## TODO
59
69
 
60
- * Refactor the attribute retrieval to something more reusable
61
70
  * Implement remaining bits of person, photoset, and photo-releated APIs
62
71
 
63
72
  ## License
@@ -0,0 +1,26 @@
1
+ module Fleakr
2
+ class Attribute
3
+
4
+ attr_reader :name, :xpath, :attribute
5
+
6
+ def initialize(name, options = {})
7
+ @name = name.to_sym
8
+ @attribute = options[:attribute]
9
+
10
+ @xpath = options[:xpath]
11
+ @xpath ||= @name.to_s unless @attribute
12
+ end
13
+
14
+ def value_from(document)
15
+ node = document
16
+
17
+ begin
18
+ node = document.at(self.xpath) if self.xpath
19
+ self.attribute.nil? ? node.inner_text : node[self.attribute]
20
+ rescue NoMethodError
21
+ nil
22
+ end
23
+ end
24
+
25
+ end
26
+ end
data/lib/fleakr/error.rb CHANGED
@@ -3,8 +3,8 @@ module Fleakr
3
3
 
4
4
  include Fleakr::Object
5
5
 
6
- flickr_attribute :code, :from => 'rsp/err', :attribute => 'code'
7
- flickr_attribute :message, :from => 'rsp/err', :attribute => 'msg'
6
+ flickr_attribute :code, :xpath => 'rsp/err', :attribute => 'code'
7
+ flickr_attribute :message, :xpath => 'rsp/err', :attribute => 'msg'
8
8
 
9
9
  end
10
10
  end
data/lib/fleakr/object.rb CHANGED
@@ -2,23 +2,30 @@ module Fleakr
2
2
  module Object
3
3
 
4
4
  module ClassMethods
5
+
6
+ def attributes
7
+ @attributes ||= []
8
+ end
9
+
5
10
  def flickr_attribute(name, options = {})
6
- class_eval <<-CODE
7
- def #{name}
8
- if @#{name}.nil?
9
- node = @response.at('#{options[:from]}')
10
- @#{name} = #{options[:attribute].nil?} ? node.inner_text : node['#{options[:attribute]}']
11
- end
12
- @#{name}
13
- end
14
- CODE
11
+ self.attributes << Attribute.new(name, options)
12
+ class_eval "attr_reader :#{name}"
15
13
  end
14
+
16
15
  end
17
16
 
18
17
  module InstanceMethods
19
- def initialize(response)
20
- @response = response
18
+
19
+ def initialize(document = nil)
20
+ self.populate_from(document) unless document.nil?
21
+ end
22
+
23
+ def populate_from(document)
24
+ self.class.attributes.each do |attribute|
25
+ instance_variable_set("@#{attribute.name}".to_sym, attribute.value_from(document))
26
+ end
21
27
  end
28
+
22
29
  end
23
30
 
24
31
  def self.included(other)
data/lib/fleakr/photo.rb CHANGED
@@ -4,6 +4,7 @@ module Fleakr
4
4
  include Fleakr::Object
5
5
 
6
6
  flickr_attribute :title, :attribute => 'title'
7
+ flickr_attribute :id, :attribute => 'id'
7
8
 
8
9
  def self.find_all_by_photoset_id(photoset_id)
9
10
  response = Request.with_response!('photosets.getPhotos', :photoset_id => photoset_id)
@@ -0,0 +1,21 @@
1
+ module Fleakr
2
+ class Search
3
+
4
+ attr_reader :tags
5
+
6
+ def initialize(parameters)
7
+ @tags = parameters[:tags]
8
+ end
9
+
10
+ def results
11
+ if @results.nil?
12
+ response = Request.with_response!('photos.search', :tags => self.tags.join(','))
13
+ @results = (response.body/'rsp/photos/photo').map do |flickr_photo|
14
+ Photo.new(flickr_photo)
15
+ end
16
+ end
17
+ @results
18
+ end
19
+
20
+ end
21
+ end
data/lib/fleakr/set.rb CHANGED
@@ -4,8 +4,8 @@ module Fleakr
4
4
  include Fleakr::Object
5
5
 
6
6
  flickr_attribute :id, :attribute => 'id'
7
- flickr_attribute :title, :from => 'title'
8
- flickr_attribute :description, :from => 'description'
7
+ flickr_attribute :title
8
+ flickr_attribute :description
9
9
 
10
10
  def self.find_all_by_user_id(user_id)
11
11
  response = Request.with_response!('photosets.getList', :user_id => user_id)
data/lib/fleakr/user.rb CHANGED
@@ -3,8 +3,8 @@ module Fleakr
3
3
 
4
4
  include Fleakr::Object
5
5
 
6
- flickr_attribute :id, :from => 'rsp/user', :attribute => 'nsid'
7
- flickr_attribute :username, :from => 'rsp/user/username'
6
+ flickr_attribute :id, :xpath => 'rsp/user', :attribute => 'nsid'
7
+ flickr_attribute :username, :xpath => 'rsp/user/username'
8
8
 
9
9
  def self.find_by_username(username)
10
10
  response = Request.with_response!('people.findByUsername', :username => username)
@@ -3,7 +3,7 @@ module Fleakr
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- TINY = 2
6
+ TINY = 3
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, TINY].join('.')
data/lib/fleakr.rb CHANGED
@@ -6,6 +6,7 @@ require 'net/http'
6
6
  require 'hpricot'
7
7
 
8
8
  require 'fleakr/object'
9
+ require 'fleakr/attribute'
9
10
  require 'fleakr/photo'
10
11
  require 'fleakr/request'
11
12
  require 'fleakr/response'
@@ -13,3 +14,4 @@ require 'fleakr/error'
13
14
  require 'fleakr/set'
14
15
  require 'fleakr/user'
15
16
  require 'fleakr/group'
17
+ require 'fleakr/search'
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <photos page="1" pages="385" perpage="100" total="38424">
4
+ <photo id="3076020861" owner="31987693@N05" secret="b956549c07" server="3278" farm="4" title="Mona and Lisa" ispublic="1" isfriend="0" isfamily="0" />
5
+ <photo id="3075386827" owner="9377349@N05" secret="4e40291b2d" server="3151" farm="4" title="IMG_0055 1.JPG" ispublic="1" isfriend="0" isfamily="0" />
6
+ </photos>
7
+ </rsp>
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ module Fleakr
4
+ class AttributeTest < Test::Unit::TestCase
5
+ describe "An instance of the Attribute class" do
6
+
7
+ it "should know the name of the attribute" do
8
+ attr = Attribute.new('foo')
9
+ attr.name.should == :foo
10
+ end
11
+
12
+ it "should infer the xpath information from the attribute name" do
13
+ attr = Attribute.new('foo')
14
+ attr.xpath.should == 'foo'
15
+ end
16
+
17
+ it "should use a string value for the xpath from the inferred attribute name" do
18
+ attr = Attribute.new(:foo)
19
+ attr.xpath.should == 'foo'
20
+ end
21
+
22
+ it "should allow the setting of the xpath information" do
23
+ attr = Attribute.new('foo', :xpath => 'bar')
24
+ attr.xpath.should == 'bar'
25
+ end
26
+
27
+ it "should have a default attribute value of nil" do
28
+ attr = Attribute.new('foo')
29
+ attr.attribute.should be(nil)
30
+ end
31
+
32
+ it "should allow the setting of the attribute value" do
33
+ attr = Attribute.new('foo', :attribute => 'bogon')
34
+ attr.attribute.should == 'bogon'
35
+ end
36
+
37
+ it "should not infer the xpath value when the attribute is set" do
38
+ attr = Attribute.new(:foo, :attribute => 'bogon')
39
+ attr.xpath.should be(nil)
40
+ end
41
+
42
+ it "should be able to pull simple values from an XML document" do
43
+ document = Hpricot.XML('<name>Bassdrive</name>')
44
+ attr = Attribute.new('name')
45
+ attr.value_from(document).should == 'Bassdrive'
46
+ end
47
+
48
+ it "should be able to pull an attribute value from the current XML node" do
49
+ document = Hpricot.XML('<user id="1337" />').at('user')
50
+ attr = Attribute.new(:id, :attribute => 'id')
51
+ attr.value_from(document).should == '1337'
52
+ end
53
+
54
+ it "should be able to pull an attribute value for a node and attribute" do
55
+ document = Hpricot.XML('<station><genre slug="dnb">Drum & Bass</genre></station>')
56
+ attr = Attribute.new(:slug, :xpath => 'station/genre', :attribute => 'slug')
57
+ attr.value_from(document).should == 'dnb'
58
+ end
59
+
60
+ it "should return nil if it cannot find the specified node" do
61
+ document = Hpricot.XML('<user id="1" />')
62
+ attr = Attribute.new(:photoset, :attribute => 'id')
63
+ attr.value_from(document).should be(nil)
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class EmptyObject
4
+ include Fleakr::Object
5
+ end
6
+
7
+ class FlickrObject
8
+
9
+ include Fleakr::Object
10
+
11
+ flickr_attribute :name
12
+ flickr_attribute :description, :xpath => 'desc'
13
+ flickr_attribute :id, :attribute => 'nsid'
14
+ flickr_attribute :photoset_id, :xpath => 'photoset', :attribute => 'id'
15
+
16
+ end
17
+
18
+ module Fleakr
19
+ class ObjectTest < Test::Unit::TestCase
20
+
21
+ describe "A class method provided by the Flickr::Object module" do
22
+
23
+ it "should have an empty list of attributes if none are supplied" do
24
+ EmptyObject.attributes.should == []
25
+ end
26
+
27
+ it "should know the names of all its attributes" do
28
+ FlickrObject.attributes.map {|a| a.name.to_s }.should == %w(name description id photoset_id)
29
+ end
30
+
31
+ end
32
+
33
+ describe "An instance method provided by the Flickr::Object module" do
34
+
35
+ it "should have default reader methods" do
36
+ [:name, :description, :id, :photoset_id].each do |method_name|
37
+ FlickrObject.new.respond_to?(method_name).should == true
38
+ end
39
+ end
40
+
41
+ context "when populating data from an XML document" do
42
+ before do
43
+ xml = <<-XML
44
+ <name>Fleakr</name>
45
+ <desc>Awesome</desc>
46
+ <photoset id="1" />
47
+ XML
48
+
49
+ @object = FlickrObject.new
50
+ @object.populate_from(Hpricot.XML(xml))
51
+ end
52
+
53
+ it "should have the correct value for :name" do
54
+ @object.name.should == 'Fleakr'
55
+ end
56
+
57
+ it "should have the correct value for :description" do
58
+ @object.description.should == 'Awesome'
59
+ end
60
+
61
+ it "should have the correct value for :photoset_id" do
62
+ @object.photoset_id.should == '1'
63
+ end
64
+
65
+ it "should have the correct value for :id" do
66
+ document = Hpricot.XML('<object nsid="1" />').at('object')
67
+ @object.populate_from(document)
68
+
69
+ @object.id.should == '1'
70
+ end
71
+ end
72
+
73
+ it "should populate its data from an XML document when initializing" do
74
+ document = stub()
75
+ FlickrObject.any_instance.expects(:populate_from).with(document)
76
+
77
+ FlickrObject.new(document)
78
+ end
79
+
80
+ it "should not attempt to populate itself from an XML document if one is not available" do
81
+ FlickrObject.any_instance.expects(:populate_from).never
82
+ FlickrObject.new
83
+ end
84
+
85
+
86
+ end
87
+
88
+ end
89
+ end
@@ -19,6 +19,10 @@ module Fleakr
19
19
  it "should have the proper title" do
20
20
  @photos.map {|p| p.title}.should == ['Photo #1', 'Photo #2']
21
21
  end
22
+
23
+ it "should have the proper id" do
24
+ @photos.map {|p| p.id }.should == %w(3044163577 3045001128)
25
+ end
22
26
 
23
27
  end
24
28
 
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ module Fleakr
4
+ class SearchTest < Test::Unit::TestCase
5
+
6
+ describe "An instance of the Search class" do
7
+
8
+ it "should be able to search photos based on tags" do
9
+ response = mock_request_cycle :for => 'photos.search', :with => {:tags => 'one,two'}
10
+
11
+ photo_1, photo_2 = [stub(), stub()]
12
+ photo_1_doc, photo_2_doc = (response.body/'rsp/photos/photo').map {|doc| doc }
13
+
14
+ Photo.expects(:new).with(photo_1_doc).returns(photo_1)
15
+ Photo.expects(:new).with(photo_2_doc).returns(photo_2)
16
+
17
+ search = Search.new(:tags => %w(one two))
18
+ search.results.should == [photo_1, photo_2]
19
+ end
20
+
21
+ should "memoize the search results" do
22
+ response = stub(:body => Hpricot.XML(read_fixture('photos.search')))
23
+ Request.expects(:with_response!).with(kind_of(String), kind_of(Hash)).once.returns(response)
24
+
25
+ (response.body/'rsp/photos/photo').each do |doc|
26
+ Photo.expects(:new).with(doc).once
27
+ end
28
+
29
+ search = Search.new(:tags => %w(foo))
30
+
31
+ 2.times { search.results }
32
+ end
33
+
34
+
35
+ end
36
+
37
+ end
38
+ end
@@ -35,7 +35,7 @@ module Fleakr
35
35
  context "when accessing its list of photos" do
36
36
 
37
37
  before do
38
- @set = Set.new(stub())
38
+ @set = Set.new
39
39
  @set.stubs(:id).with().returns('1')
40
40
  end
41
41
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reagent-fleakr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Patrick Reagan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-11-30 00:00:00 -08:00
12
+ date: 2008-12-02 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -33,12 +33,14 @@ files:
33
33
  - README.markdown
34
34
  - Rakefile
35
35
  - lib/fleakr
36
+ - lib/fleakr/attribute.rb
36
37
  - lib/fleakr/error.rb
37
38
  - lib/fleakr/group.rb
38
39
  - lib/fleakr/object.rb
39
40
  - lib/fleakr/photo.rb
40
41
  - lib/fleakr/request.rb
41
42
  - lib/fleakr/response.rb
43
+ - lib/fleakr/search.rb
42
44
  - lib/fleakr/set.rb
43
45
  - lib/fleakr/user.rb
44
46
  - lib/fleakr/version.rb
@@ -47,14 +49,18 @@ files:
47
49
  - test/fixtures/people.findByEmail.xml
48
50
  - test/fixtures/people.findByUsername.xml
49
51
  - test/fixtures/people.getPublicGroups.xml
52
+ - test/fixtures/photos.search.xml
50
53
  - test/fixtures/photosets.getList.xml
51
54
  - test/fixtures/photosets.getPhotos.xml
52
55
  - test/fleakr
56
+ - test/fleakr/attribute_test.rb
53
57
  - test/fleakr/error_test.rb
54
58
  - test/fleakr/group_test.rb
59
+ - test/fleakr/object_test.rb
55
60
  - test/fleakr/photo_test.rb
56
61
  - test/fleakr/request_test.rb
57
62
  - test/fleakr/response_test.rb
63
+ - test/fleakr/search_test.rb
58
64
  - test/fleakr/set_test.rb
59
65
  - test/fleakr/user_test.rb
60
66
  - test/test_helper.rb