picasa 0.4.1 → 0.4.2

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/lib/picasa.rb CHANGED
@@ -6,6 +6,7 @@ require "picasa/exceptions"
6
6
  require "picasa/connection"
7
7
  require "picasa/client"
8
8
  require "picasa/api/album"
9
+ require "picasa/api/tag"
9
10
 
10
11
  require "picasa/presenter/album"
11
12
  require "picasa/presenter/album_list"
@@ -14,6 +15,8 @@ require "picasa/presenter/content"
14
15
  require "picasa/presenter/link"
15
16
  require "picasa/presenter/media"
16
17
  require "picasa/presenter/photo"
18
+ require "picasa/presenter/tag"
19
+ require "picasa/presenter/tag_list"
17
20
  require "picasa/presenter/thumbnail"
18
21
 
19
22
  module Picasa
@@ -34,6 +34,7 @@ module Picasa
34
34
  # @option options [String] :tag include photos with given tag only
35
35
  #
36
36
  # @return [Presenter::Album]
37
+ # @raise [NotFoundError] raised when album cannot be found
37
38
  def show(album_id, options = {})
38
39
  uri = URI.parse("/data/feed/api/user/#{user_id}/albumid/#{album_id}")
39
40
  parsed_body = Connection.new(credentials).get(uri.path, options)
@@ -0,0 +1,41 @@
1
+ module Picasa
2
+ module API
3
+ class Tag
4
+ attr_reader :user_id, :credentials
5
+
6
+ # @param [Hash] credentials
7
+ # @option credentials [String] :user_id google username/email
8
+ # @option credentials [String] :password password for given username/email
9
+ def initialize(credentials)
10
+ if MultiXml.parser.to_s == "MultiXml::Parsers::Ox"
11
+ raise StandardError, "MultiXml parser is set to :ox - picasa gem will not work with it currently, use one of: :libxml, :nokogiri, :rexml"
12
+ end
13
+ @user_id = credentials.fetch(:user_id)
14
+ @credentials = credentials
15
+ end
16
+
17
+ # Returns tag list - when album_id is not specified, list of user tags will be returned
18
+ #
19
+ # @param [Hash] options additional options included in request
20
+ # @option option [String] :album_id retrieve tags for given album
21
+ # @option option [String] :photo_id retrieve tags for given photo (album_id must be provided)
22
+ #
23
+ # @return [Presenter::TagList]
24
+ def list(options = {})
25
+ album_id = options[:album_id]
26
+ photo_id = options[:photo_id]
27
+ raise(ArgumentError, "You must specify album_id when providing photo_id") if photo_id && !album_id
28
+
29
+ path = "/data/feed/api/user/#{user_id}"
30
+ path << "/albumid/#{album_id}" if album_id
31
+ path << "/photoid/#{photo_id}" if photo_id
32
+
33
+ uri = URI.parse(path)
34
+
35
+ parsed_body = Connection.new(credentials).get(uri.path, options.merge(:kind => "tag"))
36
+
37
+ Presenter::TagList.new(parsed_body["feed"])
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/picasa/client.rb CHANGED
@@ -20,5 +20,16 @@ module Picasa
20
20
  def album
21
21
  API::Album.new(credentials)
22
22
  end
23
+
24
+ # @return [API::Tag]
25
+ #
26
+ # @example
27
+ # client = Picasa::Client.new(user_id: "my.email@google.com")
28
+ # tag_list = client.tag.list(album_id: "988", photo_id: "123")
29
+ # tag_list.title
30
+ # # => "holidays"
31
+ def tag
32
+ API::Tag.new(credentials)
33
+ end
23
34
  end
24
35
  end
@@ -4,7 +4,7 @@ require "uri"
4
4
 
5
5
  module Picasa
6
6
  class Connection
7
- attr_reader :user_id, :password, :response
7
+ attr_reader :user_id, :password
8
8
 
9
9
  def initialize(credentials = {})
10
10
  @user_id = credentials.fetch(:user_id)
@@ -23,12 +23,7 @@ module Picasa
23
23
 
24
24
  path = path_with_params(path, params)
25
25
  request = Net::HTTP::Get.new(path, headers)
26
- @response = http.request(request)
27
- parsed_body
28
- end
29
-
30
- def parsed_body
31
- @parsed_body ||= MultiXml.parse(response.body)
26
+ handle_response(http.request(request))
32
27
  end
33
28
 
34
29
  def inline_params(params)
@@ -45,6 +40,17 @@ module Picasa
45
40
 
46
41
  private
47
42
 
43
+ def handle_response(response)
44
+ case response.code.to_i
45
+ when 200...300
46
+ MultiXml.parse(response.body)
47
+ when 404
48
+ raise NotFoundError.new(response.body, response)
49
+ else
50
+ raise ResponseError.new(reponse.body, response)
51
+ end
52
+ end
53
+
48
54
  def headers
49
55
  {"User-Agent" => "ruby-gem-v#{Picasa::VERSION}", "GData-Version" => API_VERSION}.tap do |headers|
50
56
  headers["Authorization"] = "GoogleLogin auth=#{@auth_key}" if @auth_key
@@ -62,7 +68,6 @@ module Picasa
62
68
  end
63
69
 
64
70
  def authenticate
65
- return @auth_key if defined?(@auth_key)
66
71
  validate_email!
67
72
 
68
73
  data = inline_params({"accountType" => "HOSTED_OR_GOOGLE",
@@ -14,4 +14,6 @@ module Picasa
14
14
  super(message)
15
15
  end
16
16
  end
17
+
18
+ class NotFoundError < ResponseError; end
17
19
  end
@@ -22,7 +22,7 @@ module Picasa
22
22
 
23
23
  def methods_to_inspect
24
24
  # Ruby 1.8.7 workaround
25
- (public_methods - Object.methods).map { |m| m.to_sym } - [:parsed_body]
25
+ (public_methods - Object.methods).map { |m| m.to_sym } - [:parsed_body, :entries]
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,42 @@
1
+ require "picasa/presenter/base"
2
+
3
+ module Picasa
4
+ module Presenter
5
+ class Tag < Base
6
+ # @return [Presenter::Author]
7
+ def author
8
+ @author ||= Author.new(safe_retrieve(parsed_body, "author"))
9
+ end
10
+
11
+ # @return [Array<Presenter::Link>]
12
+ def links
13
+ @links ||= safe_retrieve(parsed_body, "link").map { |link| Link.new(link) }
14
+ end
15
+
16
+ # @return [DateTime]
17
+ def updated
18
+ @updated ||= map_to_date(safe_retrieve(parsed_body, "updated"))
19
+ end
20
+
21
+ # @return [String]
22
+ def title
23
+ @title ||= safe_retrieve(parsed_body, "title")
24
+ end
25
+
26
+ # @return [String]
27
+ def summary
28
+ @summary ||= safe_retrieve(parsed_body, "summary")
29
+ end
30
+
31
+ # @return [String]
32
+ def id
33
+ @id ||= safe_retrieve(parsed_body, "id")
34
+ end
35
+
36
+ # @return [Integer]
37
+ def weight
38
+ @weight ||= map_to_integer(safe_retrieve(parsed_body, "weight"))
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,73 @@
1
+ require "picasa/presenter/base"
2
+
3
+ module Picasa
4
+ module Presenter
5
+ class TagList < Base
6
+ # @return [Presenter::Author]
7
+ def author
8
+ @author ||= Author.new(safe_retrieve(parsed_body, "author"))
9
+ end
10
+
11
+ # @return [Array<Presenter::Tag>]
12
+ def entries
13
+ @entries ||= array_wrap(safe_retrieve(parsed_body, "entry")).map { |entry| Tag.new(entry) }
14
+ end
15
+ alias :tags :entries
16
+
17
+ # @return [Array<Presenter::Link>]
18
+ def links
19
+ @links ||= safe_retrieve(parsed_body, "link").map { |link| Link.new(link) }
20
+ end
21
+
22
+ # @return [String]
23
+ def title
24
+ @title ||= safe_retrieve(parsed_body, "title")
25
+ end
26
+
27
+ # @return [DateTime]
28
+ def updated
29
+ @updated ||= map_to_date(safe_retrieve(parsed_body, "updated"))
30
+ end
31
+
32
+ # @return [String]
33
+ def icon
34
+ @icon ||= safe_retrieve(parsed_body, "icon")
35
+ end
36
+
37
+ # @return [String]
38
+ def generator
39
+ @generator ||= safe_retrieve(parsed_body, "generator", "__content__")
40
+ end
41
+
42
+ # @return [Integer]
43
+ def total_results
44
+ @total_results ||= map_to_integer(safe_retrieve(parsed_body, "totalResults"))
45
+ end
46
+
47
+ # @return [Integer]
48
+ def start_index
49
+ @start_index ||= map_to_integer(safe_retrieve(parsed_body, "startIndex"))
50
+ end
51
+
52
+ # @return [Integer]
53
+ def items_per_page
54
+ @items_per_page ||= map_to_integer(safe_retrieve(parsed_body, "itemsPerPage"))
55
+ end
56
+
57
+ # @return [String]
58
+ def user
59
+ @user ||= safe_retrieve(parsed_body, "user")
60
+ end
61
+
62
+ # @return [String]
63
+ def nickname
64
+ @nickname ||= safe_retrieve(parsed_body, "nickname")
65
+ end
66
+
67
+ # @return [String]
68
+ def thumbnail
69
+ @thumbnail ||= safe_retrieve(parsed_body, "thumbnail")
70
+ end
71
+ end
72
+ end
73
+ end
@@ -1,3 +1,3 @@
1
1
  module Picasa
2
- VERSION = "0.4.1"
2
+ VERSION = "0.4.2"
3
3
  end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "helper"
3
+
4
+ describe Picasa::API::Tag do
5
+ describe "#list" do
6
+ it "throws ArgumentErro when photo_id provided without album_id" do
7
+ tag = Picasa::API::Tag.new(:user_id => "w.wnetrzak")
8
+
9
+ assert_raises Picasa::ArgumentError, /album_id/ do
10
+ tag.list(:photo_id => "12343")
11
+ end
12
+ end
13
+
14
+ it "gives correct parsed body fragment" do
15
+ stub_request(:get, "https://picasaweb.google.com/data/feed/api/user/w.wnetrzak?kind=tag").to_return(fixture("tag/tag-list.txt"))
16
+
17
+ tag_list = Picasa::API::Tag.new(:user_id => "w.wnetrzak").list
18
+
19
+ assert_equal 2, tag_list.entries.size
20
+ end
21
+ end
22
+ end
@@ -37,6 +37,17 @@ describe Picasa::Connection do
37
37
  end
38
38
  end
39
39
 
40
+ it "raises NotFound exception when 404 returned" do
41
+ connection = Picasa::Connection.new(:user_id => "john.doe@domain.com")
42
+ uri = URI.parse("/data/feed/api/user/#{connection.user_id}/albumid/non-existing")
43
+
44
+ stub_request(:get, "https://picasaweb.google.com" + uri.path).to_return(fixture("not_found.txt"))
45
+
46
+ assert_raises Picasa::NotFoundError, "Invalid entity id: non-existing" do
47
+ connection.get(uri.path)
48
+ end
49
+ end
50
+
40
51
  describe "authentication" do
41
52
  it "successfully authenticates" do
42
53
  connection = Picasa::Connection.new(:user_id => "john.doe@domain.com", :password => "secret")
@@ -0,0 +1,14 @@
1
+ HTTP/1.1 404 Not Found
2
+ Expires: Fri, 24 Aug 2012 16:04:24 GMT
3
+ Date: Fri, 24 Aug 2012 16:04:24 GMT
4
+ Cache-Control: private, max-age=0, must-revalidate
5
+ Set-Cookie: _rtok=3st0A7QFPEFO; Path=/; Secure; HttpOnly
6
+ Set-Cookie: S=photos_html=o2mfdle_g_-wK1WAJoo1Lw; Domain=.google.com; Path=/; Secure; HttpOnly
7
+ Content-Type: text/html; charset=UTF-8
8
+ X-Content-Type-Options: nosniff
9
+ X-Frame-Options: SAMEORIGIN
10
+ X-XSS-Protection: 1; mode=block
11
+ Server: GSE
12
+ Transfer-Encoding: chunked
13
+
14
+ Invalid entity id: non-existing
@@ -0,0 +1,51 @@
1
+ <?xml version='1.0' encoding='UTF-8'?>
2
+ <feed xmlns='http://www.w3.org/2005/Atom' xmlns:gphoto='http://schemas.google.com/photos/2007' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
3
+ <id>https://picasaweb.google.com/data/feed/user/106136347770555028022</id>
4
+ <updated>2012-08-17T08:40:24.986Z</updated>
5
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#user'/>
6
+ <title>106136347770555028022</title>
7
+ <subtitle/>
8
+ <icon>https://lh3.googleusercontent.com/-6ezHc54U8x0/AAAAAAAAAAI/AAAAAAAAAAA/PBuxm7Ehn6E/s64-c/106136347770555028022.jpg</icon>
9
+ <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022'/>
10
+ <link rel='alternate' type='text/html' href='https://picasaweb.google.com/106136347770555028022'/>
11
+ <link rel='http://schemas.google.com/photos/2007#slideshow' type='application/x-shockwave-flash' href='https://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F106136347770555028022%3Falt%3Drss'/>
12
+ <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022?start-index=1&amp;max-results=500&amp;kind=tag'/>
13
+ <author>
14
+ <name>Wojciech Wnętrzak</name>
15
+ <uri>https://picasaweb.google.com/106136347770555028022</uri>
16
+ </author>
17
+ <generator version='1.00' uri='http://picasaweb.google.com/'>Picasaweb</generator>
18
+ <openSearch:totalResults>2</openSearch:totalResults>
19
+ <openSearch:startIndex>1</openSearch:startIndex>
20
+ <openSearch:itemsPerPage>500</openSearch:itemsPerPage>
21
+ <gphoto:user>106136347770555028022</gphoto:user>
22
+ <gphoto:nickname>Wojciech Wnętrzak</gphoto:nickname>
23
+ <gphoto:thumbnail>https://lh3.googleusercontent.com/-6ezHc54U8x0/AAAAAAAAAAI/AAAAAAAAAAA/PBuxm7Ehn6E/s64-c/106136347770555028022.jpg</gphoto:thumbnail>
24
+ <entry gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
25
+ <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/nice</id>
26
+ <updated>2012-08-17T08:40:24.986Z</updated>
27
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
28
+ <title>nice</title>
29
+ <summary>nice</summary>
30
+ <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=nice&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
31
+ <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/tag/nice'/>
32
+ <author>
33
+ <name>Wojciech Wnętrzak</name>
34
+ <uri>https://picasaweb.google.com/106136347770555028022</uri>
35
+ </author>
36
+ <gphoto:weight>2</gphoto:weight>
37
+ </entry>
38
+ <entry gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
39
+ <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/ziemniaki</id>
40
+ <updated>2012-08-17T08:40:24.986Z</updated>
41
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
42
+ <title>ziemniaki</title>
43
+ <summary>ziemniaki</summary>
44
+ <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=ziemniaki&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
45
+ <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/tag/ziemniaki'/>
46
+ <author>
47
+ <name>Wojciech Wnętrzak</name>
48
+ <uri>https://picasaweb.google.com/106136347770555028022</uri>
49
+ </author>
50
+ </entry>
51
+ </feed>
@@ -1,24 +1,24 @@
1
- HTTP/1.1 200 OK
2
- Expires: Mon, 05 Dec 2011 20:17:24 GMT
3
- Date: Mon, 05 Dec 2011 20:17:24 GMT
4
- Cache-Control: private, max-age=0, must-revalidate, no-transform
5
- Set-Cookie: _rtok=seW2VfBeMWcR; Path=/; Secure; HttpOnly
6
- Set-Cookie: S=photos_html=p8GDlXoFVlE58t0I2YhTkA; Domain=.google.com; Path=/; Secure; HttpOnly
7
- Content-Type: application/atom+xml; charset=UTF-8; type=feed
8
- Vary: Accept, X-GData-Authorization, GData-Version, Cookie
9
- GData-Version: 2.0
10
- ETag: W/"CUUGRXc9cCp7ImA9WhRQEUw."
11
- Last-Modified: Mon, 05 Dec 2011 19:27:04 GMT
12
- X-Content-Type-Options: nosniff
13
- X-Frame-Options: SAMEORIGIN
14
- X-XSS-Protection: 1; mode=block
15
- Server: GSE
16
- Transfer-Encoding: chunked
17
-
1
+ HTTP/1.1 200 OK
2
+ Expires: Fri, 24 Aug 2012 16:49:12 GMT
3
+ Date: Fri, 24 Aug 2012 16:49:12 GMT
4
+ Cache-Control: private, max-age=0, must-revalidate, no-transform
5
+ Set-Cookie: _rtok=K94BmWQbwPpS; Path=/; Secure; HttpOnly
6
+ Set-Cookie: S=photos_html=HoT1z5c0-FHu3mvDkW-BiA; Domain=.google.com; Path=/; Secure; HttpOnly
7
+ Content-Type: application/atom+xml; charset=UTF-8; type=feed
8
+ Vary: Accept, X-GData-Authorization, GData-Version, Cookie
9
+ GData-Version: 2.0
10
+ ETag: W/"CE8GRXczfip7ImA9WhJWEUQ."
11
+ Last-Modified: Fri, 17 Aug 2012 08:40:24 GMT
12
+ X-Content-Type-Options: nosniff
13
+ X-Frame-Options: SAMEORIGIN
14
+ X-XSS-Protection: 1; mode=block
15
+ Server: GSE
16
+ Transfer-Encoding: chunked
17
+
18
18
  <?xml version='1.0' encoding='UTF-8'?>
19
- <feed xmlns='http://www.w3.org/2005/Atom' xmlns:gphoto='http://schemas.google.com/photos/2007' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;CUUGRXc9cCp7ImA9WhRQEUw.&quot;'>
19
+ <feed xmlns='http://www.w3.org/2005/Atom' xmlns:gphoto='http://schemas.google.com/photos/2007' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
20
20
  <id>https://picasaweb.google.com/data/feed/user/106136347770555028022</id>
21
- <updated>2011-12-05T19:27:04.968Z</updated>
21
+ <updated>2012-08-17T08:40:24.986Z</updated>
22
22
  <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#user'/>
23
23
  <title>106136347770555028022</title>
24
24
  <subtitle/>
@@ -38,22 +38,9 @@ Transfer-Encoding: chunked
38
38
  <gphoto:user>106136347770555028022</gphoto:user>
39
39
  <gphoto:nickname>Wojciech Wnętrzak</gphoto:nickname>
40
40
  <gphoto:thumbnail>https://lh3.googleusercontent.com/-6ezHc54U8x0/AAAAAAAAAAI/AAAAAAAAAAA/PBuxm7Ehn6E/s64-c/106136347770555028022.jpg</gphoto:thumbnail>
41
- <entry gd:etag='W/&quot;CUUGRXc9cCp7ImA9WhRQEUw.&quot;'>
42
- <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/ziemniaki</id>
43
- <updated>2011-12-05T19:27:04.968Z</updated>
44
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
45
- <title>ziemniaki</title>
46
- <summary>ziemniaki</summary>
47
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=ziemniaki&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
48
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/tag/ziemniaki'/>
49
- <author>
50
- <name>Wojciech Wnętrzak</name>
51
- <uri>https://picasaweb.google.com/106136347770555028022</uri>
52
- </author>
53
- </entry>
54
- <entry gd:etag='W/&quot;CUUGRXc9cCp7ImA9WhRQEUw.&quot;'>
41
+ <entry gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
55
42
  <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/nice</id>
56
- <updated>2011-12-05T19:27:04.968Z</updated>
43
+ <updated>2012-08-17T08:40:24.986Z</updated>
57
44
  <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
58
45
  <title>nice</title>
59
46
  <summary>nice</summary>
@@ -65,4 +52,17 @@ Transfer-Encoding: chunked
65
52
  </author>
66
53
  <gphoto:weight>2</gphoto:weight>
67
54
  </entry>
68
- </feed>
55
+ <entry gd:etag='W/&quot;CE8GRXczfip7ImA9WhJWEUQ.&quot;'>
56
+ <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/ziemniaki</id>
57
+ <updated>2012-08-17T08:40:24.986Z</updated>
58
+ <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
59
+ <title>ziemniaki</title>
60
+ <summary>ziemniaki</summary>
61
+ <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=ziemniaki&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
62
+ <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/tag/ziemniaki'/>
63
+ <author>
64
+ <name>Wojciech Wnętrzak</name>
65
+ <uri>https://picasaweb.google.com/106136347770555028022</uri>
66
+ </author>
67
+ </entry>
68
+ </feed>
@@ -1,27 +1,50 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  require "helper"
3
3
 
4
- class TestPresenter < Picasa::Presenter::Base
5
- def body
6
- parsed_body[:body]
4
+ class TestAttributePresenter < Picasa::Presenter::Base
5
+ def attribute
6
+ parsed_body[:attribute]
7
7
  end
8
+ end
8
9
 
9
- def nil_value
10
+ class TestNilAttributePresenter < Picasa::Presenter::Base
11
+ def nil_attribute
10
12
  nil
11
13
  end
12
14
  end
13
15
 
16
+ class TestEntriesAliasPresenter < Picasa::Presenter::Base
17
+ def entries
18
+ ["entries"]
19
+ end
20
+ alias :elements :entries
21
+ end
22
+
14
23
  describe Picasa::Presenter::Base do
15
- before do
16
- @presenter = TestPresenter.new({:body => "presented body"})
24
+ it "has attribute" do
25
+ presenter = TestAttributePresenter.new({:attribute => "presented body"})
26
+
27
+ assert_equal presenter.parsed_body, {:attribute => "presented body"}
17
28
  end
18
29
 
19
- it "has parsed_body" do
20
- assert_equal @presenter.parsed_body, {:body => "presented body"}
30
+ it "has inspect with class name and defined attribute" do
31
+ presenter = TestAttributePresenter.new({:attribute => "presented body"})
32
+ expected = %q{#<TestAttributePresenter attribute: "presented body">}
33
+
34
+ assert_equal expected, presenter.inspect
21
35
  end
22
36
 
23
- it "has inspect with class name and defined methods" do
24
- expected = %q{#<TestPresenter body: "presented body", nil_value: nil>}
25
- assert_equal expected, @presenter.inspect
37
+ it "has inspect with nil attribute" do
38
+ presenter = TestNilAttributePresenter.new({:attribute => "presented body"})
39
+ expected = %q{#<TestNilAttributePresenter nil_attribute: nil>}
40
+
41
+ assert_equal expected, presenter.inspect
42
+ end
43
+
44
+ it "has aliased method to entries" do
45
+ presenter = TestEntriesAliasPresenter.new({:attribute => "presented body"})
46
+ expected = %q{#<TestEntriesAliasPresenter elements: ["entries"]>}
47
+
48
+ assert_equal expected, presenter.inspect
26
49
  end
27
50
  end
@@ -0,0 +1,67 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "helper"
3
+
4
+ describe Picasa::Presenter::TagList do
5
+ before do
6
+ body = MultiXml.parse(fixture("presenters/tag_list.xml"))
7
+ @tag_list = Picasa::Presenter::TagList.new(body["feed"])
8
+ end
9
+
10
+ it "has author name" do
11
+ assert_equal "Wojciech Wnętrzak", @tag_list.author.name
12
+ end
13
+
14
+ it "has author uri" do
15
+ assert_equal "https://picasaweb.google.com/106136347770555028022", @tag_list.author.uri
16
+ end
17
+
18
+ it "has links" do
19
+ assert_equal 4, @tag_list.links.size
20
+ end
21
+
22
+ it "has title" do
23
+ assert_equal "106136347770555028022", @tag_list.title
24
+ end
25
+
26
+ it "has updated" do
27
+ assert_equal "2012-08-17T08:40:24+00:00", @tag_list.updated.to_s
28
+ end
29
+
30
+ it "has icon" do
31
+ expected = "https://lh3.googleusercontent.com/-6ezHc54U8x0/AAAAAAAAAAI/AAAAAAAAAAA/PBuxm7Ehn6E/s64-c/106136347770555028022.jpg"
32
+ assert_equal expected, @tag_list.icon
33
+ end
34
+
35
+ it "has generator" do
36
+ assert_equal "Picasaweb", @tag_list.generator
37
+ end
38
+
39
+ it "has total_results" do
40
+ assert_equal 2, @tag_list.total_results
41
+ end
42
+
43
+ it "has start_index" do
44
+ assert_equal 1, @tag_list.start_index
45
+ end
46
+
47
+ it "has items_per_page" do
48
+ assert_equal 500, @tag_list.items_per_page
49
+ end
50
+
51
+ it "has user" do
52
+ assert_equal "106136347770555028022", @tag_list.user
53
+ end
54
+
55
+ it "has nickname" do
56
+ assert_equal "Wojciech Wnętrzak", @tag_list.nickname
57
+ end
58
+
59
+ it "has thumbnail" do
60
+ expected = "https://lh3.googleusercontent.com/-6ezHc54U8x0/AAAAAAAAAAI/AAAAAAAAAAA/PBuxm7Ehn6E/s64-c/106136347770555028022.jpg"
61
+ assert_equal expected, @tag_list.thumbnail
62
+ end
63
+
64
+ it "has entries" do
65
+ assert_equal 2, @tag_list.entries.size
66
+ end
67
+ end
@@ -0,0 +1,44 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require "helper"
3
+
4
+ describe Picasa::Presenter::Tag do
5
+ describe "album from album list" do
6
+ before do
7
+ body = MultiXml.parse(fixture("presenters/tag_list.xml"))
8
+ @tag = Picasa::Presenter::Tag.new(body["feed"]["entry"][0])
9
+ end
10
+
11
+ it "has author name" do
12
+ assert_equal "Wojciech Wnętrzak", @tag.author.name
13
+ end
14
+
15
+ it "has author uri" do
16
+ assert_equal "https://picasaweb.google.com/106136347770555028022", @tag.author.uri
17
+ end
18
+
19
+ it "has links" do
20
+ assert_equal 2, @tag.links.size
21
+ end
22
+
23
+ it "has updated" do
24
+ assert_equal "2012-08-17T08:40:24+00:00", @tag.updated.to_s
25
+ end
26
+
27
+ it "has title" do
28
+ assert_equal "nice", @tag.title
29
+ end
30
+
31
+ it "has summary" do
32
+ assert_equal "nice", @tag.summary
33
+ end
34
+
35
+ it "has id" do
36
+ expected = "https://picasaweb.google.com/data/entry/user/106136347770555028022/tag/nice"
37
+ assert_equal expected, @tag.id
38
+ end
39
+
40
+ it "has weight" do
41
+ assert_equal 2, @tag.weight
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picasa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-23 00:00:00.000000000 Z
12
+ date: 2012-08-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: multi_xml
@@ -74,6 +74,7 @@ files:
74
74
  - Rakefile
75
75
  - lib/picasa.rb
76
76
  - lib/picasa/api/album.rb
77
+ - lib/picasa/api/tag.rb
77
78
  - lib/picasa/client.rb
78
79
  - lib/picasa/connection.rb
79
80
  - lib/picasa/exceptions.rb
@@ -85,11 +86,14 @@ files:
85
86
  - lib/picasa/presenter/link.rb
86
87
  - lib/picasa/presenter/media.rb
87
88
  - lib/picasa/presenter/photo.rb
89
+ - lib/picasa/presenter/tag.rb
90
+ - lib/picasa/presenter/tag_list.rb
88
91
  - lib/picasa/presenter/thumbnail.rb
89
92
  - lib/picasa/utils.rb
90
93
  - lib/picasa/version.rb
91
94
  - picasa.gemspec
92
95
  - test/api/album_test.rb
96
+ - test/api/tag_test.rb
93
97
  - test/client_test.rb
94
98
  - test/connection_test.rb
95
99
  - test/fixtures/album/album-list-with-tag.txt
@@ -101,14 +105,14 @@ files:
101
105
  - test/fixtures/auth/failure.txt
102
106
  - test/fixtures/auth/success.txt
103
107
  - test/fixtures/json.txt
108
+ - test/fixtures/not_found.txt
104
109
  - test/fixtures/photo/photo-list-all-with-q.txt
105
110
  - test/fixtures/photo/photo-list-all.txt
106
111
  - test/fixtures/photo/photo-list-user.txt
107
112
  - test/fixtures/presenters/album_list.xml
108
113
  - test/fixtures/presenters/album_show.xml
109
114
  - test/fixtures/presenters/album_show_with_one_photo.xml
110
- - test/fixtures/tag/tag-list-album.txt
111
- - test/fixtures/tag/tag-list-photo.txt
115
+ - test/fixtures/presenters/tag_list.xml
112
116
  - test/fixtures/tag/tag-list.txt
113
117
  - test/helper.rb
114
118
  - test/presenter/album_list_test.rb
@@ -119,6 +123,8 @@ files:
119
123
  - test/presenter/link_test.rb
120
124
  - test/presenter/media_test.rb
121
125
  - test/presenter/photo_test.rb
126
+ - test/presenter/tag_list_test.rb
127
+ - test/presenter/tag_test.rb
122
128
  - test/presenter/thumbnail_test.rb
123
129
  - test/utils_test.rb
124
130
  homepage: https://github.com/morgoth/picasa
@@ -1,77 +0,0 @@
1
- HTTP/1.1 200 OK
2
- Expires: Fri, 16 Dec 2011 21:30:40 GMT
3
- Date: Fri, 16 Dec 2011 21:30:40 GMT
4
- Cache-Control: private, max-age=0, must-revalidate, no-transform
5
- Set-Cookie: _rtok=m86aNMszMxZo; Path=/; Secure; HttpOnly
6
- Set-Cookie: S=photos_html=cb2m9-vV3-J0tLmmzMNNeQ; Domain=.google.com; Path=/; Secure; HttpOnly
7
- Content-Type: application/atom+xml; charset=UTF-8; type=feed
8
- Vary: Accept, X-GData-Authorization, GData-Version, Cookie
9
- GData-Version: 2.0
10
- ETag: W/"Ck8FRH04fCp7ImA9WhRXEEo."
11
- Last-Modified: Fri, 16 Dec 2011 21:26:55 GMT
12
- X-Content-Type-Options: nosniff
13
- X-Frame-Options: SAMEORIGIN
14
- X-XSS-Protection: 1; mode=block
15
- Server: GSE
16
- Transfer-Encoding: chunked
17
-
18
- <?xml version='1.0' encoding='UTF-8'?>
19
- <feed xmlns='http://www.w3.org/2005/Atom' xmlns:gphoto='http://schemas.google.com/photos/2007' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;Ck8FRH04fCp7ImA9WhRXEEo.&quot;'>
20
- <id>https://picasaweb.google.com/data/feed/user/106136347770555028022/albumid/5243667126168669553</id>
21
- <updated>2011-12-16T21:26:55.334Z</updated>
22
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#album'/>
23
- <title>test2</title>
24
- <subtitle/>
25
- <rights>public</rights>
26
- <icon>https://lh6.googleusercontent.com/-u_2FJXbbliU/SMU_eBetTXE/AAAAAAAAAmQ/sMUp4PrT-Qg/s160-c/Test2.jpg</icon>
27
- <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022/albumid/5243667126168669553'/>
28
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/106136347770555028022/Test2'/>
29
- <link rel='http://schemas.google.com/photos/2007#slideshow' type='application/x-shockwave-flash' href='https://picasaweb.google.com/s/c/bin/slideshow.swf?host=picasaweb.google.com&amp;RGB=0x000000&amp;feed=https%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2F106136347770555028022%2Falbumid%2F5243667126168669553%3Falt%3Drss'/>
30
- <link rel='http://schemas.google.com/photos/2007#report' type='text/html' href='https://picasaweb.google.com/lh/reportAbuse?uname=106136347770555028022&amp;aid=5243667126168669553'/>
31
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022/albumid/5243667126168669553?start-index=1&amp;max-results=500&amp;kind=tag'/>
32
- <author>
33
- <name>Wojciech Wnętrzak</name>
34
- <uri>https://picasaweb.google.com/106136347770555028022</uri>
35
- </author>
36
- <generator version='1.00' uri='http://picasaweb.google.com/'>Picasaweb</generator>
37
- <openSearch:totalResults>2</openSearch:totalResults>
38
- <openSearch:startIndex>1</openSearch:startIndex>
39
- <openSearch:itemsPerPage>500</openSearch:itemsPerPage>
40
- <gphoto:id>5243667126168669553</gphoto:id>
41
- <gphoto:name>Test2</gphoto:name>
42
- <gphoto:location/>
43
- <gphoto:access>public</gphoto:access>
44
- <gphoto:timestamp>1220857200000</gphoto:timestamp>
45
- <gphoto:numphotos>4</gphoto:numphotos>
46
- <gphoto:user>106136347770555028022</gphoto:user>
47
- <gphoto:nickname>Wojciech Wnętrzak</gphoto:nickname>
48
- <gphoto:allowPrints>true</gphoto:allowPrints>
49
- <gphoto:allowDownloads>true</gphoto:allowDownloads>
50
- <entry gd:etag='W/&quot;Ck8FRH04fCp7ImA9WhRXEEo.&quot;'>
51
- <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/albumid/5243667126168669553/tag/nice</id>
52
- <updated>2011-12-16T21:26:55.334Z</updated>
53
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
54
- <title>nice</title>
55
- <summary>nice</summary>
56
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=nice&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
57
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/albumid/5243667126168669553/tag/nice'/>
58
- <author>
59
- <name>Wojciech Wnętrzak</name>
60
- <uri>https://picasaweb.google.com/106136347770555028022</uri>
61
- </author>
62
- <gphoto:weight>2</gphoto:weight>
63
- </entry>
64
- <entry gd:etag='W/&quot;Ck8FRH04fCp7ImA9WhRXEEo.&quot;'>
65
- <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/albumid/5243667126168669553/tag/ziemniaki</id>
66
- <updated>2011-12-16T21:26:55.334Z</updated>
67
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
68
- <title>ziemniaki</title>
69
- <summary>ziemniaki</summary>
70
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=ziemniaki&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
71
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/albumid/5243667126168669553/tag/ziemniaki'/>
72
- <author>
73
- <name>Wojciech Wnętrzak</name>
74
- <uri>https://picasaweb.google.com/106136347770555028022</uri>
75
- </author>
76
- </entry>
77
- </feed>
@@ -1,72 +0,0 @@
1
- HTTP/1.1 200 OK
2
- Expires: Fri, 16 Dec 2011 21:33:47 GMT
3
- Date: Fri, 16 Dec 2011 21:33:47 GMT
4
- Cache-Control: private, max-age=0, must-revalidate, no-transform
5
- Set-Cookie: _rtok=FmHRbgk4VV6P; Path=/; Secure; HttpOnly
6
- Set-Cookie: S=photos_html=cae0NlLGoySoeaqWcgY1pg; Domain=.google.com; Path=/; Secure; HttpOnly
7
- Content-Type: application/atom+xml; charset=UTF-8; type=feed
8
- Vary: Accept, X-GData-Authorization, GData-Version, Cookie
9
- GData-Version: 2.0
10
- ETag: W/"Ck8FRH04fCp7ImA9WhRXEEo."
11
- Last-Modified: Fri, 16 Dec 2011 21:26:55 GMT
12
- X-Content-Type-Options: nosniff
13
- X-Frame-Options: SAMEORIGIN
14
- X-XSS-Protection: 1; mode=block
15
- Server: GSE
16
- Transfer-Encoding: chunked
17
-
18
- <?xml version='1.0' encoding='UTF-8'?>
19
- <feed xmlns='http://www.w3.org/2005/Atom' xmlns:exif='http://schemas.google.com/photos/exif/2007' xmlns:gphoto='http://schemas.google.com/photos/2007' xmlns:media='http://search.yahoo.com/mrss/' xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/' xmlns:gd='http://schemas.google.com/g/2005' gd:etag='W/&quot;Ck8FRH04fCp7ImA9WhRXEEo.&quot;'>
20
- <id>https://picasaweb.google.com/data/feed/user/106136347770555028022/albumid/5243667126168669553/photoid/5634470303146876834</id>
21
- <updated>2011-12-16T21:26:55.334Z</updated>
22
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#photo'/>
23
- <title>pink_floyd_ladies.jpg</title>
24
- <subtitle/>
25
- <icon>https://lh3.googleusercontent.com/-k2SAcZgBGQc/TjGo41SOn6I/AAAAAAAAAmQ/JsDZRk0qL7E/s288/pink_floyd_ladies.jpg</icon>
26
- <link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022/albumid/5243667126168669553/photoid/5634470303146876834'/>
27
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/photo/gipEdejdx4mYdBP57zti6dMTjNZETYmyPJy0liipFm0'/>
28
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/feed/api/user/106136347770555028022/albumid/5243667126168669553/photoid/5634470303146876834?start-index=1&amp;max-results=500&amp;kind=tag'/>
29
- <generator version='1.00' uri='http://picasaweb.google.com/'>Picasaweb</generator>
30
- <openSearch:totalResults>1</openSearch:totalResults>
31
- <openSearch:startIndex>1</openSearch:startIndex>
32
- <openSearch:itemsPerPage>500</openSearch:itemsPerPage>
33
- <gphoto:id>5634470303146876834</gphoto:id>
34
- <gphoto:albumid>5243667126168669553</gphoto:albumid>
35
- <gphoto:access>public</gphoto:access>
36
- <gphoto:width>1024</gphoto:width>
37
- <gphoto:height>768</gphoto:height>
38
- <gphoto:size>140724</gphoto:size>
39
- <gphoto:checksum/>
40
- <gphoto:timestamp>1311877347000</gphoto:timestamp>
41
- <gphoto:imageVersion>612</gphoto:imageVersion>
42
- <gphoto:commentingEnabled>true</gphoto:commentingEnabled>
43
- <gphoto:commentCount>0</gphoto:commentCount>
44
- <gphoto:license id='0' name='All Rights Reserved' url=''>ALL_RIGHTS_RESERVED</gphoto:license>
45
- <gphoto:viewCount>11</gphoto:viewCount>
46
- <exif:tags>
47
- <exif:imageUniqueID>26875afdfa1eb82ab62d6ef7ccea95ab</exif:imageUniqueID>
48
- </exif:tags>
49
- <media:group>
50
- <media:content url='https://lh3.googleusercontent.com/-k2SAcZgBGQc/TjGo41SOn6I/AAAAAAAAAmQ/JsDZRk0qL7E/pink_floyd_ladies.jpg' height='768' width='1024' type='image/jpeg' medium='image'/>
51
- <media:credit>Wojciech Wnętrzak</media:credit>
52
- <media:description type='plain'/>
53
- <media:keywords>nice</media:keywords>
54
- <media:thumbnail url='https://lh3.googleusercontent.com/-k2SAcZgBGQc/TjGo41SOn6I/AAAAAAAAAmQ/JsDZRk0qL7E/s72/pink_floyd_ladies.jpg' height='54' width='72'/>
55
- <media:thumbnail url='https://lh3.googleusercontent.com/-k2SAcZgBGQc/TjGo41SOn6I/AAAAAAAAAmQ/JsDZRk0qL7E/s144/pink_floyd_ladies.jpg' height='108' width='144'/>
56
- <media:thumbnail url='https://lh3.googleusercontent.com/-k2SAcZgBGQc/TjGo41SOn6I/AAAAAAAAAmQ/JsDZRk0qL7E/s288/pink_floyd_ladies.jpg' height='216' width='288'/>
57
- <media:title type='plain'>pink_floyd_ladies.jpg</media:title>
58
- </media:group>
59
- <entry gd:etag='W/&quot;Ck8FRH04fCp7ImA9WhRXEEo.&quot;'>
60
- <id>https://picasaweb.google.com/data/entry/user/106136347770555028022/albumid/5243667126168669553/photoid/5634470303146876834/tag/nice</id>
61
- <updated>2011-12-16T21:26:55.334Z</updated>
62
- <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#tag'/>
63
- <title>nice</title>
64
- <summary>nice</summary>
65
- <link rel='alternate' type='text/html' href='https://picasaweb.google.com/lh/searchbrowse?q=nice&amp;psc=G&amp;uname=106136347770555028022&amp;filter=0'/>
66
- <link rel='self' type='application/atom+xml' href='https://picasaweb.google.com/data/entry/api/user/106136347770555028022/albumid/5243667126168669553/photoid/5634470303146876834/tag/nice'/>
67
- <author>
68
- <name>Wojciech Wnętrzak</name>
69
- <uri>https://picasaweb.google.com/106136347770555028022</uri>
70
- </author>
71
- </entry>
72
- </feed>