fleakr 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,10 +44,15 @@ user by his username:
44
44
  >> user = Fleakr.user('the decapitator')
45
45
  => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
46
46
 
47
- Or by email:
47
+ By email:
48
48
 
49
49
  >> user = Fleakr.user('user@host.com')
50
50
  => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
51
+
52
+ Or even by URL:
53
+
54
+ >> user = Fleakr.user('http://www.flickr.com/photos/the_decapitator/')
55
+ => #<Fleakr::Objects::User:0x113440c @username="the decapitator", @id="21775151@N06">
51
56
 
52
57
  Once you have a user, you can find his associated sets:
53
58
 
@@ -201,6 +206,26 @@ All comments have additional information:
201
206
 
202
207
  See Fleakr::Objects::Comment for more information.
203
208
 
209
+ === Collections
210
+
211
+ An individual can have zero or more collections associated with his account. These collections,
212
+ in turn, can have either collections or sets associated with them. For example:
213
+
214
+ >> user = Fleakr.user('username')
215
+ >> user.collections.length
216
+ => 1
217
+ >> user.collections.first.title
218
+ => "The Year in Pictures"
219
+ >> user.collections.first.collections.length
220
+ => 2
221
+ >> user.collections.first.collections.first.sets.length
222
+ => 3
223
+ >> user.collections.first.collections.first.sets.first.title
224
+ => "A Trip to Yosemite"
225
+
226
+ Note that collections are limited to Flickr pro members. See Fleakr::Objects::Collection for more
227
+ information.
228
+
204
229
  === Saving Images
205
230
 
206
231
  If a photo interests you, save it down to a directory of your choosing:
@@ -327,29 +352,40 @@ just the requests you need to tune the log level:
327
352
  Even if something doesn't go wrong, this is a good way to get a sense for when you're making
328
353
  API requests.
329
354
 
355
+ == Contributing
356
+
357
+ If there is a feature that you would like to contribute, I gladly accept pull requests. There
358
+ are a few things that make my life easier when integrating your changes:
359
+
360
+ * Verify that all tests are passing (run `rake` from the project root)
361
+ * Keep your commits small, focused, and tested - this allows me to apply changes cleanly
362
+ * Leave the Rakefile and version information intact - if you really want to make changes,
363
+ please do so in a separate commit.
364
+
365
+ Once your changes are applied, I will add you to the list of contributors.
366
+
330
367
  == Contributors
331
368
 
332
369
  While Fleakr started as a labor of love for me, I'm glad that others have been interested
333
370
  in this project enough to contribute their ideas and code:
334
371
 
372
+ * {Mark Dickson}[http://github.com/ideaoforder]
335
373
  * {John Guenin}[http://github.com/johng]
336
374
  * {Thomas Olausson}[http://github.com/latompa]
375
+ * {Robert Sköld}[http://github.com/slaskis]
337
376
 
338
377
  Thanks!
339
378
 
340
379
  == Roadmap / TODO
341
380
 
342
- === 0.4.x
343
-
344
- * Implement remaining bits of person and photo-related API calls (read-only)
345
-
346
381
  === 0.5.x
347
382
 
348
- * Implement asynchronous file upload / replacement w/ ticket checking
383
+ * Implement remaining bits of person and photo-related API calls (read-only)
349
384
  * Provide a better searching interface with ruby-like option syntax
350
385
 
351
386
  === Future
352
387
 
388
+ * Implement asynchronous file upload / replacement w/ ticket checking
353
389
  * Implement save-able search results (e.g. Fleakr.search('ponies').save_to('/path', :medium))
354
390
  * Implement deeper associations for core elements (e.g. tags / etc..)
355
391
  * Implement write methods for photos & photosets
data/Rakefile CHANGED
@@ -49,7 +49,7 @@ rescue LoadError
49
49
  end
50
50
 
51
51
  desc 'Generate the gemspec to serve this Gem from Github'
52
- task :github do
52
+ task :gemspec do
53
53
  file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
54
54
  File.open(file, 'w') {|f| f << spec.to_ruby }
55
55
  puts "Created gemspec: #{file}"
@@ -88,18 +88,22 @@ module Fleakr
88
88
  mattr_accessor :api_key, :shared_secret, :mini_token, :auth_token, :frob
89
89
 
90
90
  # Find a user based on some unique user data. This method will try to find
91
- # the user based on username and will fall back to email if that fails. Example:
91
+ # the user based on several methods, starting with username and falling back to email and URL
92
+ # sequentially if these methods fail. Example:
92
93
  #
93
94
  # Fleakr.api_key = 'ABC123'
94
- # Fleakr.user('the decapitator') # => #<Fleakr::Objects::User:0x692648 @username="the decapitator", @id="21775151@N06">
95
- # Fleakr.user('user@host.com') # => #<Fleakr::Objects::User:0x11f484c @username="bckspcr", @id="84481630@N00">
95
+ # Fleakr.user('the decapitator')
96
+ # Fleakr.user('user@host.com')
97
+ # Fleakr.user('http://www.flickr.com/photos/the_decapitator/')
96
98
  #
97
99
  def self.user(user_data)
98
- begin
99
- Objects::User.find_by_username(user_data)
100
- rescue ApiError
101
- Objects::User.find_by_email(user_data)
100
+ user = nil
101
+ [:username, :email, :url].each do |attribute|
102
+ if user.nil?
103
+ user = Objects::User.send("find_by_#{attribute}", user_data) rescue nil
104
+ end
102
105
  end
106
+ user
103
107
  end
104
108
 
105
109
  # Search all photos on the Flickr site. By default, this searches based on text, but you can pass
@@ -1,4 +1,5 @@
1
1
  require 'fleakr/objects/authentication_token'
2
+ require 'fleakr/objects/collection'
2
3
  require 'fleakr/objects/contact'
3
4
  require 'fleakr/objects/error'
4
5
  require 'fleakr/objects/group'
@@ -0,0 +1,57 @@
1
+ module Fleakr
2
+ module Objects # :nodoc:
3
+
4
+ # = Collection
5
+ #
6
+ # == Attributes
7
+ #
8
+ # [id] The ID for this collection
9
+ # [title] The title of this collection
10
+ # [description] The description of this collection
11
+ # [small_icon_url] The URL for the small icon that represents this collection
12
+ # [large_icon_url] The URL for the large icon that represents this collection
13
+ #
14
+ class Collection
15
+
16
+ include Fleakr::Support::Object
17
+
18
+ flickr_attribute :id, :title, :description
19
+ flickr_attribute :created, :from => '@datecreate'
20
+ flickr_attribute :small_icon_url, :from => '@iconsmall'
21
+ flickr_attribute :large_icon_url, :from => '@iconlarge'
22
+
23
+ find_one :by_id, :call => 'collections.getInfo', :path => 'collection'
24
+ find_all :by_user_id, :call => 'collections.getTree', :path => 'collections/collection'
25
+
26
+ # When was this collection created?
27
+ #
28
+ def created_at
29
+ Time.at(created.to_i)
30
+ end
31
+
32
+ # The sets associated with this collection
33
+ #
34
+ def sets
35
+ sibling_nodes_for('set').map {|n| Set.new(n) }
36
+ end
37
+
38
+ # The collections associated with this collection
39
+ #
40
+ def collections
41
+ sibling_nodes_for('collection').map {|n| Collection.new(n) }
42
+ end
43
+
44
+ private
45
+ def sibling_nodes_for(node) # :nodoc:
46
+ nodes = []
47
+ selector = "/collection/#{node}"
48
+
49
+ document = Hpricot.XML(self.document.to_s)
50
+ document.search(selector) {|e| nodes << e }
51
+
52
+ nodes
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -2,9 +2,21 @@ module Fleakr
2
2
  module Objects # :nodoc:
3
3
  class Search
4
4
 
5
+ # attr_reader :search_options
6
+
5
7
  # Create a new search
6
- def initialize(search_options)
7
- @search_options = search_options
8
+ def initialize(*parameters)
9
+ @parameters = Hash.new
10
+ parameters.each {|param| add_parameter(param) }
11
+ end
12
+
13
+ def add_parameter(parameter)
14
+ value = parameter.is_a?(String) ? {:text => parameter} : parameter
15
+ @parameters.merge!(value)
16
+ end
17
+
18
+ def tags
19
+ Array(@parameters[:tags])
8
20
  end
9
21
 
10
22
  # Retrieve search results from the API
@@ -17,12 +29,12 @@ module Fleakr
17
29
 
18
30
  private
19
31
  def tag_list
20
- Array(@search_options[:tags]).join(',')
32
+ tags.join(',')
21
33
  end
22
34
 
23
35
  def parameters
24
- @search_options.merge!(:tags => tag_list) if tag_list.length > 0
25
- @search_options
36
+ @parameters.merge!(:tags => tag_list) if tags.any?
37
+ @parameters
26
38
  end
27
39
 
28
40
  end
@@ -22,6 +22,7 @@ module Fleakr
22
22
  has_many :photos, :comments
23
23
 
24
24
  flickr_attribute :id, :title, :description
25
+ flickr_attribute :primary_photo_id, :from => '@primary'
25
26
  flickr_attribute :count, :from => '@photos'
26
27
 
27
28
  find_all :by_user_id, :call => 'photosets.getList', :path => 'photosets/photoset'
@@ -45,6 +46,10 @@ module Fleakr
45
46
  sprintf("%0#{self.count.length}d_", (index + 1))
46
47
  end
47
48
 
49
+ def primary_photo
50
+ @primary_photo ||= Photo.find_by_id(primary_photo_id)
51
+ end
52
+
48
53
  end
49
54
  end
50
55
  end
@@ -29,6 +29,7 @@ module Fleakr
29
29
  # [photos] A list of this user's public photos (newest first). See Fleakr::Objects::Photo.
30
30
  # [contacts] A list of this user's contacts - these are simply User objects
31
31
  # [tags] The tags associated with this user
32
+ # [collections] The top-level collections that this user has created. See Fleakr::Objects::Collection.
32
33
  #
33
34
  # == Examples
34
35
  #
@@ -44,7 +45,7 @@ module Fleakr
44
45
 
45
46
  include Fleakr::Support::Object
46
47
 
47
- flickr_attribute :id, :from => 'user@nsid'
48
+ flickr_attribute :id, :from => ['user@id', 'user@nsid']
48
49
  flickr_attribute :username, :location
49
50
  flickr_attribute :name, :from => 'person/realname'
50
51
  flickr_attribute :photos_url, :from => 'person/photosurl'
@@ -55,11 +56,12 @@ module Fleakr
55
56
  flickr_attribute :pro, :from => 'person@ispro'
56
57
  flickr_attribute :admin, :from => 'person@isadmin'
57
58
 
58
- has_many :sets, :groups, :photos, :contacts, :tags
59
+ has_many :sets, :groups, :photos, :contacts, :tags, :collections
59
60
 
60
61
  find_one :by_username, :call => 'people.findByUsername'
61
62
  find_one :by_email, :using => :find_email, :call => 'people.findByEmail'
62
63
  find_one :by_id, :using => :user_id, :call => 'people.getInfo'
64
+ find_one :by_url, :call => 'urls.lookupUser'
63
65
 
64
66
  lazily_load :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
65
67
  lazily_load :icon_server, :icon_farm, :pro, :admin, :with => :load_info
@@ -63,8 +63,9 @@ module Fleakr
63
63
  key = "#{self.name.demodulize.underscore.downcase}_id".to_sym
64
64
 
65
65
  class_eval <<-CODE
66
- def search(search_text)
67
- Fleakr::Objects::Search.new(:text => search_text, :#{key} => self.id).results
66
+ def search(*parameters)
67
+ parameters << {:#{key} => self.id}
68
+ Fleakr::Objects::Search.new(*parameters).results
68
69
  end
69
70
  CODE
70
71
  end
@@ -87,11 +88,14 @@ module Fleakr
87
88
 
88
89
  module InstanceMethods
89
90
 
91
+ attr_reader :document
92
+
90
93
  def initialize(document = nil)
91
94
  self.populate_from(document) unless document.nil?
92
95
  end
93
96
 
94
97
  def populate_from(document)
98
+ @document = document
95
99
  self.class.attributes.each do |attribute|
96
100
  value = attribute.value_from(document)
97
101
  self.send("#{attribute.name}=".to_sym, value) unless value.nil?
@@ -3,7 +3,7 @@ module Fleakr
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 5
6
- TINY = 1
6
+ TINY = 2
7
7
 
8
8
  def self.to_s
9
9
  [MAJOR, MINOR, TINY].join('.')
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <collection id="34762917-72157619347181335" child_count="5" datecreate="1244460707" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg" server="3603" secret="30d89a2682">
4
+ <title>Work</title>
5
+ <description>Sample Collection</description>
6
+ <iconphotos>
7
+ <photo id="3509228143" owner="34808239@N06" secret="2ed3119372" server="3637" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
8
+ <photo id="3509261341" owner="34808239@N06" secret="43a07ee13c" server="3638" farm="4" title="Saab 9X Air" ispublic="1" isfriend="0" isfamily="0" />
9
+ <photo id="3488255219" owner="34808239@N06" secret="b94e2c39c1" server="3624" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
10
+ <photo id="3488219705" owner="34808239@N06" secret="d26642a09b" server="3560" farm="4" title="stellaUK_1" ispublic="1" isfriend="0" isfamily="0" />
11
+ <photo id="3489034148" owner="34808239@N06" secret="89d6f94800" server="3577" farm="4" title="abba_kalles_3" ispublic="1" isfriend="0" isfamily="0" />
12
+ <photo id="3488220307" owner="34808239@N06" secret="a96a8acbb0" server="3578" farm="4" title="abba_kalles_1" ispublic="1" isfriend="0" isfamily="0" />
13
+ <photo id="3489034014" owner="34808239@N06" secret="d392cca5d6" server="3124" farm="4" title="abba_kalles_2" ispublic="1" isfriend="0" isfamily="0" />
14
+ <photo id="3489033670" owner="34808239@N06" secret="4f08e7368c" server="3547" farm="4" title="stellaUK_3" ispublic="1" isfriend="0" isfamily="0" />
15
+ <photo id="3488219913" owner="34808239@N06" secret="6bcdeb4bf6" server="3310" farm="4" title="stellaUK_2" ispublic="1" isfriend="0" isfamily="0" />
16
+ <photo id="3509261445" owner="34808239@N06" secret="595cc58f50" server="3313" farm="4" title="Saab 9X Air" ispublic="1" isfriend="0" isfamily="0" />
17
+ <photo id="3488255345" owner="34808239@N06" secret="de5f1b9133" server="3644" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
18
+ <photo id="3509228095" owner="34808239@N06" secret="3b0a661db7" server="3392" farm="4" title="" ispublic="1" isfriend="0" isfamily="0" />
19
+ </iconphotos>
20
+ </collection>
21
+ </rsp>
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <collections>
4
+ <collection id="123-456" title="Top-Level Collection 1" description="Description 1" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
5
+ <collection id="123-457" title="Second-Level Collection 1" description="Description 2" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
6
+ <collection id="123-789" title="Third-Level Collection 1" description="Description 3" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg">
7
+ <set id="1234" title="Set 1" description="" />
8
+ <set id="1235" title="Set 2" description="" />
9
+ </collection>
10
+ <collection id="123-101" title="Third-Level Collection 2" description="Description 4" iconlarge="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg" iconsmall="http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg">
11
+ <set id="1236" title="Set 3" description="" />
12
+ <set id="1237" title="Set 4" description="" />
13
+ </collection>
14
+ </collection>
15
+ </collection>
16
+ <collection id="123-102" title="Top-Level Collection 2" description="Description 5" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
17
+ <set id="1238" title="Set 5" description="" />
18
+ <set id="1239" title="Set 6" description="" />
19
+ </collection>
20
+ </collections>
21
+ </rsp>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8" ?>
2
+ <rsp stat="ok">
3
+ <user id="123456">
4
+ <username>frootpantz</username>
5
+ </user>
6
+ </rsp>
@@ -39,7 +39,7 @@ class Test::Unit::TestCase
39
39
  instance = klass.new
40
40
  instance.stubs(:id).with().returns('1')
41
41
 
42
- Fleakr::Objects::Search.expects(:new).with(:text => 'foo', key => '1').returns(search)
42
+ Fleakr::Objects::Search.expects(:new).with('foo', key => '1').returns(search)
43
43
 
44
44
  instance.search('foo').should == photos
45
45
  end
@@ -0,0 +1,99 @@
1
+ require File.dirname(__FILE__) + '/../../../test_helper'
2
+
3
+ module Fleakr::Objects
4
+ class CollectionTest < Test::Unit::TestCase
5
+
6
+ context "The Collection class" do
7
+
8
+ should_find_one :collections, :by => :id, :call => 'collections.getInfo', :path => 'rsp/collection'
9
+ should_find_all :collections, :by => :user_id, :call => 'collections.getTree', :path => 'rsp/collections/collection'
10
+
11
+ end
12
+
13
+ context "An instance of the Collection class" do
14
+
15
+ context "when populating from a call to collections.getInfo" do
16
+ setup do
17
+ document = Hpricot.XML(read_fixture('collections.getInfo')).at('rsp/collection')
18
+ @object = Collection.new(document)
19
+ end
20
+
21
+ should_have_a_value_for :id => '34762917-72157619347181335'
22
+ should_have_a_value_for :title => 'Work'
23
+ should_have_a_value_for :description => 'Sample Collection'
24
+ should_have_a_value_for :large_icon_url => 'http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_l.jpg'
25
+ should_have_a_value_for :small_icon_url => 'http://farm4.static.flickr.com/3603/cols/72157619347181335_30d89a2682_s.jpg'
26
+ should_have_a_value_for :created => '1244460707'
27
+
28
+ end
29
+
30
+ context "when populating from a call to collections.getTree" do
31
+ setup do
32
+ document = Hpricot.XML(read_fixture('collections.getTree')).at('rsp/collections/collection')
33
+ @object = Collection.new(document)
34
+ end
35
+
36
+ should_have_a_value_for :id => '123-456'
37
+ should_have_a_value_for :title => 'Top-Level Collection 1'
38
+ should_have_a_value_for :description => 'Description 1'
39
+ should_have_a_value_for :large_icon_url => 'http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg'
40
+ should_have_a_value_for :small_icon_url => 'http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg'
41
+
42
+ end
43
+
44
+ context "that contains collections" do
45
+ setup do
46
+ document = Hpricot.XML(read_fixture('collections.getTree')).at('rsp/collections/collection')
47
+ @collection = Collection.new(document)
48
+ end
49
+
50
+ should "have a set of collections" do
51
+ collection_titles = @collection.collections.map {|c| c.title }
52
+ collection_titles.should == ['Second-Level Collection 1']
53
+ end
54
+
55
+ should "not have any associated sets" do
56
+ @collection.sets.should == []
57
+ end
58
+ end
59
+
60
+ context "that contains sets" do
61
+ setup do
62
+ xml = <<-XML
63
+ <collection id="123-102" title="Top-Level Collection 2" description="Description 5" iconlarge="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_l.jpg" iconsmall="http://farm4.static.flickr.com/3573/cols/72157617429277370_1691956f71_s.jpg">
64
+ <set id="1238" title="Set 5" description="" />
65
+ <set id="1239" title="Set 6" description="" />
66
+ </collection>
67
+ XML
68
+
69
+ document = Hpricot.XML(xml).at('collection')
70
+ @collection = Collection.new(document)
71
+ end
72
+
73
+ should "not have any associated collections" do
74
+ @collection.collections.should == []
75
+ end
76
+
77
+ should "have associated sets" do
78
+ set_titles = @collection.sets.map {|s| s.title }
79
+ set_titles.should == ['Set 5', 'Set 6']
80
+ end
81
+
82
+ end
83
+
84
+ context "in general" do
85
+ setup do
86
+ @collection = Collection.new
87
+ @time = Time.parse('2008-08-01 00:00:00')
88
+ end
89
+
90
+ should "have a value for :created_at" do
91
+ @collection.expects(:created).with().returns("#{@time.to_i}")
92
+ @collection.created_at.to_s.should == @time.to_s
93
+ end
94
+
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -5,6 +5,16 @@ module Fleakr::Objects
5
5
 
6
6
  context "An instance of the Search class" do
7
7
 
8
+ should "have a list of tags" do
9
+ search = Search.new(:tags => %w(a b c))
10
+ search.tags.should == %w(a b c)
11
+ end
12
+
13
+ should "have convert tags into an array" do
14
+ search = Search.new(:tags => 'a')
15
+ search.tags.should == ['a']
16
+ end
17
+
8
18
  should "be able to generate a list of tags from a single-valued parameter" do
9
19
  search = Search.new(:tags => 'foo')
10
20
  search.send(:tag_list).should == 'foo'
@@ -35,6 +45,16 @@ module Fleakr::Objects
35
45
  search.send(:parameters).should == {:text => 'foo'}
36
46
  end
37
47
 
48
+ should "convert a single string parameter into a text search" do
49
+ search = Search.new('term')
50
+ search.send(:parameters).should == {:text => 'term'}
51
+ end
52
+
53
+ should "be able to handle a combination of text and options" do
54
+ search = Search.new('term', :tags => %w(a b))
55
+ search.send(:parameters).should == {:text => 'term', :tags => 'a,b'}
56
+ end
57
+
38
58
  should "be able to search photos based on text" do
39
59
  response = mock_request_cycle :for => 'photos.search', :with => {:text => 'foo'}
40
60
  search = Search.new(:text => 'foo')
@@ -18,13 +18,38 @@ module Fleakr::Objects
18
18
  @object = Set.new(Hpricot.XML(read_fixture('photosets.getList')).at('rsp/photosets/photoset'))
19
19
  end
20
20
 
21
- should_have_a_value_for :id => '72157609490909659'
22
- should_have_a_value_for :title => 'Second Set'
23
- should_have_a_value_for :description => 'This is the second set.'
24
- should_have_a_value_for :count => '138'
21
+ should_have_a_value_for :id => '72157609490909659'
22
+ should_have_a_value_for :title => 'Second Set'
23
+ should_have_a_value_for :description => 'This is the second set.'
24
+ should_have_a_value_for :count => '138'
25
+ should_have_a_value_for :primary_photo_id => '3044180117'
25
26
 
26
27
  end
27
28
 
29
+ should "know the primary photo in the set" do
30
+ id = '1'
31
+ photo = stub()
32
+
33
+ Photo.expects(:find_by_id).with(id).returns(photo)
34
+
35
+ set = Set.new
36
+ set.stubs(:primary_photo_id).with().returns(id)
37
+
38
+ set.primary_photo.should == photo
39
+ end
40
+
41
+ should "memoize the primary photo" do
42
+ id = '1'
43
+ photo = stub()
44
+
45
+ Photo.expects(:find_by_id).with(id).once.returns(photo)
46
+
47
+ set = Set.new
48
+ set.stubs(:primary_photo_id).with().returns(id)
49
+
50
+ 2.times { set.primary_photo }
51
+ end
52
+
28
53
  context "when saving the set" do
29
54
  setup do
30
55
  @tmp_dir = create_temp_directory
@@ -5,7 +5,7 @@ module Fleakr::Objects
5
5
 
6
6
  should_search_by :user_id
7
7
 
8
- should_have_many :photos, :groups, :sets, :contacts, :tags
8
+ should_have_many :photos, :groups, :sets, :contacts, :tags, :collections
9
9
 
10
10
  should_autoload_when_accessing :name, :photos_url, :profile_url, :photos_count, :location, :with => :load_info
11
11
  should_autoload_when_accessing :icon_server, :icon_farm, :pro, :admin, :icon_url, :with => :load_info
@@ -15,6 +15,7 @@ module Fleakr::Objects
15
15
  should_find_one :user, :by => :username, :call => 'people.findByUsername', :path => 'rsp/user'
16
16
  should_find_one :user, :by => :email, :with => :find_email, :call => 'people.findByEmail', :path => 'rsp/user'
17
17
  should_find_one :user, :by => :id, :with => :user_id, :call => 'people.getInfo', :path => 'rsp/person'
18
+ should_find_one :user, :by => :url, :call => 'urls.lookupUser', :path => 'rsp/user'
18
19
 
19
20
  end
20
21
 
@@ -38,6 +39,17 @@ module Fleakr::Objects
38
39
  should_have_a_value_for :admin => '0'
39
40
 
40
41
  end
42
+
43
+ context "when populating an object from the urls.lookupUser API call" do
44
+ setup do
45
+ document = Hpricot.XML(read_fixture('urls.lookupUser'))
46
+ @object = User.new(document)
47
+ end
48
+
49
+ should_have_a_value_for :id => '123456'
50
+ should_have_a_value_for :username => 'frootpantz'
51
+
52
+ end
41
53
 
42
54
  context "in general" do
43
55
 
@@ -72,8 +72,10 @@ module Fleakr
72
72
  <category>Category</category>
73
73
  XML
74
74
 
75
+ @document = Hpricot.XML(xml)
76
+
75
77
  @object = FlickrObject.new
76
- @object.populate_from(Hpricot.XML(xml))
78
+ @object.populate_from(@document)
77
79
  end
78
80
 
79
81
  should "have the correct value for :name" do
@@ -102,6 +104,10 @@ module Fleakr
102
104
  should "have the correct value for :category" do
103
105
  @object.category.should == 'Category'
104
106
  end
107
+
108
+ should "maintain a reference to the original document" do
109
+ @object.document.should == @document
110
+ end
105
111
  end
106
112
 
107
113
  should "populate its data from an XML document when initializing" do
@@ -29,6 +29,27 @@ class FleakrTest < Test::Unit::TestCase
29
29
  Fleakr.user(email).should == user
30
30
  end
31
31
 
32
+ should "fall back to finding a user by URL if username and email both fail" do
33
+ user = stub()
34
+ url = 'http://flickr.com/photos/user'
35
+
36
+ Fleakr::Objects::User.stubs(:find_by_username).with(url).raises(Fleakr::ApiError)
37
+ Fleakr::Objects::User.stubs(:find_by_email).with(url).raises(Fleakr::ApiError)
38
+ Fleakr::Objects::User.expects(:find_by_url).with(url).returns(user)
39
+
40
+ Fleakr.user(url).should == user
41
+ end
42
+
43
+ should "not return nil if a user cannot be found" do
44
+ data = 'data'
45
+
46
+ Fleakr::Objects::User.stubs(:find_by_username).with(data).raises(Fleakr::ApiError)
47
+ Fleakr::Objects::User.stubs(:find_by_email).with(data).raises(Fleakr::ApiError)
48
+ Fleakr::Objects::User.stubs(:find_by_url).with(data).raises(Fleakr::ApiError)
49
+
50
+ Fleakr.user(data).should be_nil
51
+ end
52
+
32
53
  should "find all contacts for the authenticated user" do
33
54
  Fleakr::Objects::Contact.expects(:find_all).with({}).returns('contacts')
34
55
  Fleakr.contacts.should == 'contacts'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fleakr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
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: 2009-07-21 00:00:00 -04:00
12
+ date: 2009-10-18 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -67,6 +67,7 @@ files:
67
67
  - lib/fleakr/core_ext/true_class.rb
68
68
  - lib/fleakr/core_ext.rb
69
69
  - lib/fleakr/objects/authentication_token.rb
70
+ - lib/fleakr/objects/collection.rb
70
71
  - lib/fleakr/objects/comment.rb
71
72
  - lib/fleakr/objects/contact.rb
72
73
  - lib/fleakr/objects/error.rb
@@ -87,6 +88,8 @@ files:
87
88
  - test/fixtures/auth.checkToken.xml
88
89
  - test/fixtures/auth.getFullToken.xml
89
90
  - test/fixtures/auth.getToken.xml
91
+ - test/fixtures/collections.getInfo.xml
92
+ - test/fixtures/collections.getTree.xml
90
93
  - test/fixtures/contacts.getList.xml
91
94
  - test/fixtures/contacts.getPublicList.xml
92
95
  - test/fixtures/groups.pools.getPhotos.xml
@@ -106,6 +109,7 @@ files:
106
109
  - test/fixtures/tags.getListPhoto.xml
107
110
  - test/fixtures/tags.getListUser.xml
108
111
  - test/fixtures/tags.getRelated.xml
112
+ - test/fixtures/urls.lookupUser.xml
109
113
  - test/test_helper.rb
110
114
  - test/unit/fleakr/api/file_parameter_test.rb
111
115
  - test/unit/fleakr/api/method_request_test.rb
@@ -119,6 +123,7 @@ files:
119
123
  - test/unit/fleakr/core_ext/hash_test.rb
120
124
  - test/unit/fleakr/core_ext/true_class_test.rb
121
125
  - test/unit/fleakr/objects/authentication_token_test.rb
126
+ - test/unit/fleakr/objects/collection_test.rb
122
127
  - test/unit/fleakr/objects/comment_test.rb
123
128
  - test/unit/fleakr/objects/contact_test.rb
124
129
  - test/unit/fleakr/objects/error_test.rb