reagent-fleakr 0.1.0 → 0.1.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.
- data/README.markdown +40 -2
- data/lib/fleakr/error.rb +12 -0
- data/lib/fleakr/photo.rb +20 -0
- data/lib/fleakr/request.rb +12 -1
- data/lib/fleakr/response.rb +7 -0
- data/lib/fleakr/set.rb +8 -3
- data/lib/fleakr/user.rb +17 -7
- data/lib/fleakr/version.rb +1 -1
- data/lib/fleakr.rb +1 -0
- data/test/fixtures/photosets.getList.xml +10 -10
- data/test/fixtures/photosets.getPhotos.xml +7 -0
- data/test/fleakr/error_test.rb +19 -0
- data/test/fleakr/photo_test.rb +28 -0
- data/test/fleakr/request_test.rb +21 -0
- data/test/fleakr/response_test.rb +13 -0
- data/test/fleakr/set_test.rb +35 -11
- data/test/fleakr/user_test.rb +2 -3
- data/test/test_helper.rb +6 -1
- metadata +6 -1
data/README.markdown
CHANGED
@@ -6,12 +6,50 @@ A teeny tiny gem to interface with Flickr photostreams
|
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
-
sudo gem install fleakr
|
9
|
+
sudo gem install reagent-fleakr --source=http://gems.github.com
|
10
|
+
|
11
|
+
Or ...
|
12
|
+
|
13
|
+
$ git clone git://github.com/reagent/fleakr.git
|
14
|
+
$ cd fleakr
|
15
|
+
$ rake gem && sudo gem install pkg/fleakr-<version>.gem
|
10
16
|
|
11
17
|
## Usage
|
12
18
|
|
13
|
-
|
19
|
+
Before doing anything, require the library:
|
20
|
+
|
21
|
+
>> require 'rubygems'
|
22
|
+
>> require 'fleakr'
|
23
|
+
|
24
|
+
Then, set your API key (only need to do this once per session):
|
25
|
+
|
26
|
+
>> Fleakr::Request.api_key = '<your api key here>'
|
27
|
+
|
28
|
+
Find a user by username:
|
29
|
+
|
30
|
+
>> user = Fleakr::User.find_by_username('the decapitator')
|
31
|
+
=> #<Fleakr::User:0x692648 @username="the decapitator", @id="21775151@N06">
|
32
|
+
|
33
|
+
And that user's associated sets:
|
34
|
+
|
35
|
+
>> user.sets
|
36
|
+
=> [#<Fleakr::Set:0x671358 @title="The Decapitator", @description="">,
|
37
|
+
#<Fleakr::Set:0x66d898 @title="londonpaper hijack", ...
|
38
|
+
|
39
|
+
You can also grab photos for a particular set:
|
40
|
+
|
41
|
+
>> user.sets.first
|
42
|
+
=> #<Fleakr::Set:0x1195bbc @title="The Decapitator", @id="72157603480986566", @description="">
|
43
|
+
>> user.sets.first.photos.first
|
44
|
+
=> #<Fleakr::Photo:0x1140108 ... >
|
45
|
+
>> user.sets.first.photos.first.title
|
46
|
+
=> "Untitled1"
|
47
|
+
|
48
|
+
## TODO
|
14
49
|
|
50
|
+
* Refactor the attribute retrieval to something more reusable
|
51
|
+
* Implement remaining bits of person, photoset, and photo-releated APIs
|
52
|
+
|
15
53
|
## License
|
16
54
|
|
17
55
|
Copyright (c) 2008 Patrick Reagan (reaganpr@gmail.com)
|
data/lib/fleakr/error.rb
ADDED
data/lib/fleakr/photo.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Fleakr
|
2
|
+
class Photo
|
3
|
+
|
4
|
+
def self.find_all_by_photoset_id(photoset_id)
|
5
|
+
response = Request.with_response!('photosets.getPhotos', :photoset_id => photoset_id)
|
6
|
+
(response.body/'rsp/photoset/photo').map do |photo_body|
|
7
|
+
Photo.new(photo_body)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(photo_body)
|
12
|
+
@response_body = photo_body
|
13
|
+
end
|
14
|
+
|
15
|
+
def title
|
16
|
+
(@response_body).attributes['title']
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/lib/fleakr/request.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Fleakr
|
2
2
|
class Request
|
3
3
|
|
4
|
+
class ApiError < StandardError; end
|
5
|
+
|
4
6
|
def self.api_key=(key)
|
5
7
|
@api_key = key
|
6
8
|
end
|
@@ -9,6 +11,15 @@ module Fleakr
|
|
9
11
|
@api_key
|
10
12
|
end
|
11
13
|
|
14
|
+
def self.with_response!(method, additional_parameters = {})
|
15
|
+
request = Request.new(method, additional_parameters)
|
16
|
+
response = request.send
|
17
|
+
|
18
|
+
raise(ApiError, "Code: #{response.error.code} - #{response.error.message}") if response.error?
|
19
|
+
|
20
|
+
response
|
21
|
+
end
|
22
|
+
|
12
23
|
def endpoint_uri
|
13
24
|
uri = URI.parse('http://api.flickr.com/services/rest/')
|
14
25
|
uri.query = self.query_parameters
|
@@ -16,7 +27,7 @@ module Fleakr
|
|
16
27
|
end
|
17
28
|
|
18
29
|
def query_parameters
|
19
|
-
@parameters.map {|key,value| "#{key}=#{value}" }.join('&')
|
30
|
+
@parameters.map {|key,value| "#{key}=#{CGI.escape(value)}" }.join('&')
|
20
31
|
end
|
21
32
|
|
22
33
|
def initialize(method, additional_parameters = {})
|
data/lib/fleakr/response.rb
CHANGED
data/lib/fleakr/set.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
module Fleakr
|
2
2
|
class Set
|
3
3
|
|
4
|
-
attr_accessor :title, :description
|
4
|
+
attr_accessor :id, :title, :description
|
5
5
|
|
6
6
|
def self.find_all_by_user_id(user_id)
|
7
|
-
response = Request.
|
7
|
+
response = Request.with_response!('photosets.getList', :user_id => user_id)
|
8
8
|
|
9
|
-
(response.body/'photosets/photoset').map do |flickr_set|
|
9
|
+
(response.body/'rsp/photosets/photoset').map do |flickr_set|
|
10
10
|
set = Set.new
|
11
|
+
set.id = (flickr_set).attributes['id']
|
11
12
|
set.title = (flickr_set/'title').inner_text
|
12
13
|
set.description = (flickr_set/'description').inner_text
|
13
14
|
set
|
@@ -15,5 +16,9 @@ module Fleakr
|
|
15
16
|
|
16
17
|
end
|
17
18
|
|
19
|
+
def photos
|
20
|
+
@photos ||= Photo.find_all_by_photoset_id(self.id)
|
21
|
+
end
|
22
|
+
|
18
23
|
end
|
19
24
|
end
|
data/lib/fleakr/user.rb
CHANGED
@@ -4,13 +4,23 @@ module Fleakr
|
|
4
4
|
attr_accessor :id, :username
|
5
5
|
|
6
6
|
def self.find_by_username(username)
|
7
|
-
response =
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
response = Request.with_response!('people.findByUsername', :username => username)
|
8
|
+
User.new(response.body)
|
9
|
+
end
|
10
|
+
|
11
|
+
# flickr_attribute :id, :from => 'user', :attribute => 'nsid'
|
12
|
+
# flickr_attribute :username, :from => 'user/username', :text => true
|
13
|
+
|
14
|
+
def initialize(response_body)
|
15
|
+
@response_body = (response_body/'rsp')
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
(@response_body/'user').attr('id')
|
20
|
+
end
|
21
|
+
|
22
|
+
def username
|
23
|
+
(@response_body/'user/username').inner_text
|
14
24
|
end
|
15
25
|
|
16
26
|
def sets
|
data/lib/fleakr/version.rb
CHANGED
data/lib/fleakr.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
<?xml version="1.0" encoding="utf-8"?>
|
2
2
|
<rsp stat="ok">
|
3
|
-
<photosets>
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
</photosets>
|
3
|
+
<photosets>
|
4
|
+
<photoset videos="0" primary="3044180117" farm="4" photos="138" id="72157609490909659" server="3012" secret="01cd1a741d">
|
5
|
+
<title>Second Set</title>
|
6
|
+
<description>This is the second set.</description>
|
7
|
+
</photoset>
|
8
|
+
<photoset videos="0" primary="2988511085" farm="4" photos="139" id="72157608538140671" server="3241" secret="a7b90926ba">
|
9
|
+
<title>First Set</title>
|
10
|
+
<description>This is the first set.</description>
|
11
|
+
</photoset>
|
12
|
+
</photosets>
|
13
13
|
</rsp>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" ?>
|
2
|
+
<rsp stat="ok">
|
3
|
+
<photoset id="72157609490909659" primary="3044180117" owner="31066442@N69" ownername="frootpantz" page="1" per_page="500" perpage="500" pages="1" total="138">
|
4
|
+
<photo id="3044163577" secret="fa27e5a824" server="3153" farm="4" title="Photo #1" isprimary="0" />
|
5
|
+
<photo id="3045001128" secret="a8c0e51b39" server="3204" farm="4" title="Photo #2" isprimary="0" />
|
6
|
+
</photoset>
|
7
|
+
</rsp>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
module Fleakr
|
4
|
+
class ErrorTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
describe "An instance of the Error class" do
|
7
|
+
|
8
|
+
it "should have a code and a message" do
|
9
|
+
error = Error.new('1', 'User not found')
|
10
|
+
|
11
|
+
error.code.should == '1'
|
12
|
+
error.message.should == 'User not found'
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
module Fleakr
|
4
|
+
class PhotoTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
describe "The Photo class" do
|
7
|
+
|
8
|
+
context "when finding all photos by photoset ID" do
|
9
|
+
|
10
|
+
before do
|
11
|
+
mock_request_cycle :for => 'photosets.getPhotos', :with => {:photoset_id => '1'}
|
12
|
+
@photos = Photo.find_all_by_photoset_id('1')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should have the correct number of items" do
|
16
|
+
@photos.length.should == 2
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have the proper title" do
|
20
|
+
@photos.map {|p| p.title}.should == ['Photo #1', 'Photo #2']
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/test/fleakr/request_test.rb
CHANGED
@@ -29,6 +29,11 @@ module Fleakr
|
|
29
29
|
|
30
30
|
request.query_parameters.split('&').sort.should == expected
|
31
31
|
end
|
32
|
+
|
33
|
+
it "should escape the keys and values in the parameter list" do
|
34
|
+
request = Request.new('flickr.people.findByUsername', :username => 'the decapitator')
|
35
|
+
request.query_parameters.split('&').include?("username=#{CGI.escape('the decapitator')}").should be(true)
|
36
|
+
end
|
32
37
|
|
33
38
|
it "should translate a shorthand API call" do
|
34
39
|
request = Request.new('people.findByUsername')
|
@@ -71,6 +76,22 @@ module Fleakr
|
|
71
76
|
request.send.should == response_stub
|
72
77
|
end
|
73
78
|
|
79
|
+
it "should be able to make a full request and response cycle" do
|
80
|
+
response = stub(:error? => false)
|
81
|
+
Response.expects(:new).with(kind_of(String)).returns(response)
|
82
|
+
|
83
|
+
Request.with_response!('flickr.people.findByUsername', :username => 'foobar').should == response
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should raise an exception when the full request / response cycle has errors" do
|
87
|
+
response = stub(:error? => true, :error => stub(:code => '1', :message => 'User not found'))
|
88
|
+
Response.stubs(:new).with(kind_of(String)).returns(response)
|
89
|
+
|
90
|
+
lambda do
|
91
|
+
Request.with_response!('flickr.people.findByUsername', :username => 'foobar')
|
92
|
+
end.should raise_error(Fleakr::Request::ApiError)
|
93
|
+
end
|
94
|
+
|
74
95
|
end
|
75
96
|
|
76
97
|
end
|
@@ -29,6 +29,19 @@ module Fleakr
|
|
29
29
|
|
30
30
|
response.error?.should be(true)
|
31
31
|
end
|
32
|
+
|
33
|
+
it "should not have an error if there are no errors in the XML" do
|
34
|
+
response = Response.new(read_fixture('people.findByUsername'))
|
35
|
+
response.error.should be(nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should have an error if there is an error in the response" do
|
39
|
+
response_xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<rsp stat=\"fail\">\n\t<err code=\"1\" msg=\"User not found\" />\n</rsp>\n"
|
40
|
+
response = Response.new(response_xml)
|
41
|
+
|
42
|
+
response.error.code.should == '1'
|
43
|
+
response.error.message.should == 'User not found'
|
44
|
+
end
|
32
45
|
|
33
46
|
end
|
34
47
|
|
data/test/fleakr/set_test.rb
CHANGED
@@ -2,35 +2,59 @@ require File.dirname(__FILE__) + '/../test_helper'
|
|
2
2
|
|
3
3
|
module Fleakr
|
4
4
|
class SetTest < Test::Unit::TestCase
|
5
|
-
|
6
|
-
def mock_request_cycle(options)
|
7
|
-
response = stub(:body => read_fixture(options[:for]))
|
8
|
-
Request.expects(:new).with(options[:for], options[:with]).returns(stub(:send => response))
|
9
|
-
end
|
10
|
-
|
5
|
+
|
11
6
|
describe "The Set class" do
|
12
|
-
|
13
7
|
context "When finding all sets for a user_id" do
|
14
8
|
before do
|
15
9
|
user_id = '31066442@N69'
|
16
10
|
mock_request_cycle :for => 'photosets.getList', :with => {:user_id => user_id}
|
17
|
-
|
11
|
+
|
18
12
|
@sets = Set.find_all_by_user_id(user_id)
|
19
13
|
end
|
20
|
-
|
14
|
+
|
21
15
|
it "should return an array with the expected number of elements" do
|
22
16
|
@sets.length.should == 2
|
23
17
|
end
|
24
|
-
|
18
|
+
|
25
19
|
it "should have the proper titles for each set in the collection" do
|
26
20
|
@sets.map {|s| s.title }.should == ["Second Set", "First Set"]
|
27
21
|
end
|
28
|
-
|
22
|
+
|
29
23
|
it "should have the proper descriptions for each set in the collection" do
|
30
24
|
@sets.map {|s| s.description }.should == ['This is the second set.', 'This is the first set.']
|
31
25
|
end
|
26
|
+
|
27
|
+
it "should have the correct IDs for each of the sets" do
|
28
|
+
@sets.map {|s| s.id }.should == %w(72157609490909659 72157608538140671)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "An instance of the Set class" do
|
35
|
+
context "when accessing its list of photos" do
|
36
|
+
|
37
|
+
before do
|
38
|
+
@set = Set.new()
|
39
|
+
@set.stubs(:id).with().returns('1')
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should retrieve a list of photos" do
|
43
|
+
photos = [stub()]
|
44
|
+
|
45
|
+
Photo.expects(:find_all_by_photoset_id).with('1').returns(photos)
|
46
|
+
|
47
|
+
@set.photos.should == photos
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should memoize the list of photos retrieved" do
|
51
|
+
Photo.expects(:find_all_by_photoset_id).once.returns([])
|
52
|
+
2.times { @set.photos }
|
53
|
+
end
|
32
54
|
|
33
55
|
end
|
56
|
+
|
34
57
|
end
|
58
|
+
|
35
59
|
end
|
36
60
|
end
|
data/test/fleakr/user_test.rb
CHANGED
@@ -6,8 +6,7 @@ module Fleakr
|
|
6
6
|
describe "The User class" do
|
7
7
|
|
8
8
|
it "should be able to find a user by his username" do
|
9
|
-
|
10
|
-
Request.expects(:new).with('people.findByUsername', :username => 'frootpantz').returns(stub(:send => response))
|
9
|
+
mock_request_cycle :for => 'people.findByUsername', :with => {:username => 'frootpantz'}
|
11
10
|
|
12
11
|
user = User.find_by_username('frootpantz')
|
13
12
|
|
@@ -22,7 +21,7 @@ module Fleakr
|
|
22
21
|
before do
|
23
22
|
@user_id = '1'
|
24
23
|
|
25
|
-
@user = User.new
|
24
|
+
@user = User.new(Hpricot.XML(read_fixture('people.findByUsername')))
|
26
25
|
@user.stubs(:id).with().returns(@user_id)
|
27
26
|
end
|
28
27
|
|
data/test/test_helper.rb
CHANGED
@@ -11,7 +11,12 @@ class Test::Unit::TestCase
|
|
11
11
|
|
12
12
|
def read_fixture(method_call)
|
13
13
|
fixture_path = File.dirname(__FILE__) + '/fixtures'
|
14
|
-
|
14
|
+
File.read("#{fixture_path}/#{method_call}.xml")
|
15
|
+
end
|
16
|
+
|
17
|
+
def mock_request_cycle(options)
|
18
|
+
response = stub(:body => Hpricot.XML(read_fixture(options[:for])))
|
19
|
+
Fleakr::Request.expects(:with_response!).with(options[:for], options[:with]).returns(response)
|
15
20
|
end
|
16
21
|
|
17
22
|
end
|
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.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Reagan
|
@@ -33,6 +33,8 @@ files:
|
|
33
33
|
- README.markdown
|
34
34
|
- Rakefile
|
35
35
|
- lib/fleakr
|
36
|
+
- lib/fleakr/error.rb
|
37
|
+
- lib/fleakr/photo.rb
|
36
38
|
- lib/fleakr/request.rb
|
37
39
|
- lib/fleakr/response.rb
|
38
40
|
- lib/fleakr/set.rb
|
@@ -42,7 +44,10 @@ files:
|
|
42
44
|
- test/fixtures
|
43
45
|
- test/fixtures/people.findByUsername.xml
|
44
46
|
- test/fixtures/photosets.getList.xml
|
47
|
+
- test/fixtures/photosets.getPhotos.xml
|
45
48
|
- test/fleakr
|
49
|
+
- test/fleakr/error_test.rb
|
50
|
+
- test/fleakr/photo_test.rb
|
46
51
|
- test/fleakr/request_test.rb
|
47
52
|
- test/fleakr/response_test.rb
|
48
53
|
- test/fleakr/set_test.rb
|