reagent-fleakr 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|