umanni-picasa 0.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in picasa.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2011 Umanni
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ = picasa
2
+
3
+ A Ruby wrapper for the Picasa Web API.
4
+
5
+ == Getting started
6
+
7
+ gem install umanni-picasa
8
+
9
+ == Copyright
10
+
11
+ Copyright (c) 2011 Umanni. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :default => [:spec]
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ Bundler::GemHelper.install_tasks
data/lib/picasa.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'picasa/client'
2
+ require 'picasa/config'
3
+
4
+ module Picasa
5
+ extend Config
6
+ class << self
7
+ # Alias for Picasa::Client.new
8
+ #
9
+ # @return [Picasa::Client]
10
+ def new(options={})
11
+ Picasa::Client.new(options)
12
+ end
13
+
14
+ # Delegate to Picasa::Client
15
+ def method_missing(method, *args, &block)
16
+ return super unless new.respond_to?(method)
17
+ new.send(method, *args, &block)
18
+ end
19
+
20
+ def respond_to?(method, include_private=false)
21
+ new.respond_to?(method, include_private) || super(method, include_private)
22
+ end
23
+ end
24
+ end
data/lib/picasa/api.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'picasa/authenticatable'
2
+ require 'picasa/config'
3
+ require 'picasa/connection'
4
+ require 'picasa/request'
5
+
6
+ module Picasa
7
+ class API
8
+ include Authenticatable
9
+ include Connection
10
+ include Request
11
+
12
+ attr_accessor *Config::VALID_OPTIONS_KEYS
13
+
14
+ # Creates a new API
15
+ def initialize(options={})
16
+ options = Picasa.options.merge(options)
17
+ Config::VALID_OPTIONS_KEYS.each do |key|
18
+ send("#{key}=", options[key])
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Picasa
2
+ module Authenticatable
3
+
4
+ def credentials
5
+ {
6
+ :refresh_token => refresh_token,
7
+ :access_token => access_token,
8
+ :expires_in => expires_in,
9
+ :issued_at => issued_at
10
+ }
11
+ end
12
+
13
+ # Check whether user is authenticated
14
+ #
15
+ # @return [Boolean]
16
+ def authenticated?
17
+ credentials.values.all?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module Picasa
2
+ class Base
3
+
4
+ def self.lazy_attr_reader(*attributes)
5
+ attributes.each do |attribute|
6
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
7
+ def #{attribute}
8
+ @#{attribute} ||= @attributes[#{attribute.to_s.inspect}]
9
+ end
10
+ RUBY
11
+ end
12
+ end
13
+
14
+ def initialize(attributes = {})
15
+ @attributes = attributes.dup
16
+ end
17
+
18
+ def [](method)
19
+ self.__send__(method.to_sym)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'picasa/api'
2
+
3
+ module Picasa
4
+ class Client < API
5
+
6
+ require 'picasa/client/comments'
7
+ require 'picasa/client/gallery'
8
+ require 'picasa/client/media'
9
+
10
+ alias :api_endpoint :endpoint
11
+
12
+ include Picasa::Client::Comments
13
+ include Picasa::Client::Gallery
14
+ include Picasa::Client::Media
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+ module Picasa
2
+ class Client
3
+ module Base
4
+
5
+ DEFAULT_LANGUAGE = 'pt_BR'
6
+
7
+ def format_response response
8
+ return response.code, response.headers, response.body
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,45 @@
1
+ require 'picasa/error'
2
+ require 'picasa/client/base'
3
+ require 'picasa/constants/fields'
4
+ require 'picasa/constants/group'
5
+ require 'picasa/constants/internal_constants'
6
+ require 'picasa/constants/method_names'
7
+ require 'picasa/constants/params'
8
+ require 'multi_json'
9
+
10
+ module Picasa
11
+ class Client
12
+ module Comments
13
+ include Base
14
+
15
+ def list_photo_comments album_id, photo_id
16
+ response = get("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}?kind=comment")
17
+ status, headers, body = response
18
+ case status
19
+ when 200
20
+ return body
21
+ else
22
+ return body
23
+ end
24
+ end
25
+
26
+ def add_photo_comment album_id, photo_id, comment
27
+ body = "\r\n"
28
+ body += "<entry xmlns='http://www.w3.org/2005/Atom'>"
29
+ body += "<content>#{comment}</content>"
30
+ body += "<category scheme=\"http://schemas.google.com/g/2005#kind\" term=\"http://schemas.google.com/photos/2007#comment\"/>"
31
+ body += "</entry>\r\n"
32
+
33
+ response = post("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}", body)
34
+ status, headers, body = response
35
+ case status
36
+ when 200
37
+ return body
38
+ else
39
+ return body
40
+ #raise(StandardError, "#{status.to_s} - #{body.to_s}")
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,66 @@
1
+ require 'picasa/client/base'
2
+
3
+ module Picasa
4
+ class Client
5
+ module Gallery
6
+ include Base
7
+
8
+ def get_galleries
9
+ response = get('https://picasaweb.google.com/data/feed/api/user/default?alt=json')
10
+ status, headers, body = response
11
+ case status
12
+ when 200
13
+ return body
14
+ else
15
+ raise(StandardError, "#{status.to_s} - #{body.to_s}")
16
+ end
17
+ end
18
+
19
+ def create_gallery(options = {})
20
+ title = options[:title].nil? ? "" : options[:title]
21
+ summary = options[:summary].nil? ? "" : options[:summary]
22
+ location = options[:location].nil? ? "" : options[:location]
23
+ access = options[:access].nil? ? "public" : options[:access]
24
+ commentable = options[:commentable].nil? ? "true" : options[:commentable].to_s
25
+ keywords = options[:keywords].nil? ? "" : options[:keywords]
26
+ time_i = (Time.now).to_i
27
+
28
+ body = "<entry xmlns='http://www.w3.org/2005/Atom'
29
+ xmlns:media='http://search.yahoo.com/mrss/'
30
+ xmlns:gphoto='http://schemas.google.com/photos/2007'>
31
+ <title type='text'>#{title}</title>
32
+ <summary type='text'>#{summary}</summary>
33
+ <gphoto:location>#{location}</gphoto:location>
34
+ <gphoto:access>#{access}</gphoto:access>
35
+ <gphoto:commentingEnabled>#{commentable}</gphoto:commentingEnabled>
36
+ <gphoto:timestamp>#{time_i}</gphoto:timestamp>
37
+ <media:group>
38
+ <media:keywords>#{keywords}</media:keywords>
39
+ </media:group>
40
+ <category scheme='http://schemas.google.com/g/2005#kind'
41
+ term='http://schemas.google.com/photos/2007#album'></category>
42
+ </entry>"
43
+
44
+ response = post("https://picasaweb.google.com/data/feed/api/user/default", body)
45
+ status, headers, body = response
46
+ case status
47
+ when 200
48
+ return body
49
+ else
50
+ return body
51
+ end
52
+ end
53
+
54
+ def get_gallery_tags gallery_id
55
+ response = get("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{gallery_id}?kind=tag")
56
+ status, headers, body = response
57
+ case status
58
+ when 200
59
+ return body
60
+ else
61
+ return body
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,119 @@
1
+ require 'picasa/client/base'
2
+
3
+ module Picasa
4
+ class Client
5
+ module Media
6
+ include Base
7
+
8
+ def list_photo_tags album_id, photo_id
9
+ response = get("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}?kind=tag")
10
+ status, headers, body = response
11
+ case status
12
+ when 200
13
+ return body
14
+ else
15
+ return body
16
+ end
17
+ end
18
+
19
+ def add_photo_tag album_id, photo_id, tag
20
+ body = "\r\n"
21
+ body += "<entry xmlns='http://www.w3.org/2005/Atom'>"
22
+ body += "<title>#{tag}</title>"
23
+ body += "<category scheme=\"http://schemas.google.com/g/2005#kind\" term=\"http://schemas.google.com/photos/2007#tag\"/>"
24
+ body += "</entry>\r\n"
25
+
26
+ response = post("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}", body)
27
+ status, headers, body = response
28
+ case status
29
+ when 200
30
+ return body
31
+ else
32
+ return body
33
+ #raise(StandardError, "#{status.to_s} - #{body.to_s}")
34
+ end
35
+ end
36
+
37
+ def delete_photo album_id, photo_id
38
+ response = delete("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}")
39
+ status, headers, body = response
40
+ case status
41
+ when 200
42
+ return body
43
+ else
44
+ return body
45
+ end
46
+ end
47
+
48
+ def delete_photo_comment album_id, photo_id, comment_id
49
+ response = delete("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}/commentid/#{comment_id}")
50
+ status, headers, body = response
51
+ case status
52
+ when 200
53
+ return body
54
+ else
55
+ return body
56
+ #raise(StandardError, "#{status.to_s} - #{body.to_s}")
57
+ end
58
+ end
59
+
60
+ def delete_photo_tag album_id, photo_id, tag_id
61
+ response = delete("https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}/photoid/#{photo_id}/tag/#{tag_id}")
62
+ status, headers, body = response
63
+ case status
64
+ when 200
65
+ return body
66
+ else
67
+ return body
68
+ #raise(StandardError, "#{status.to_s} - #{body.to_s}")
69
+ end
70
+ end
71
+
72
+ ## Accepted image formats
73
+ # image/bmp
74
+ # image/gif
75
+ # image/jpeg
76
+ # image/png
77
+ def create_photo album_id, options = {}
78
+ title = options[:title].nil? ? "" : options[:title]
79
+ summary = options[:summary].nil? ? "" : options[:summary]
80
+
81
+ string_body = "<entry xmlns='http://www.w3.org/2005/Atom'>
82
+ <title>#{title}</title>
83
+ <summary>#{summary}</summary>
84
+ <category scheme=\"http://schemas.google.com/g/2005#kind\"
85
+ term=\"http://schemas.google.com/photos/2007#photo\"/>
86
+ </entry>
87
+ "
88
+ uri = "https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}"
89
+
90
+ #@xml_io = FileUploadIO.new('/tmp/atom_body_0.atom', "application/atom+xml")
91
+ @xml_io = FileUploadIO.new('/tmp/atom_body.atom', "application/atom+xml", string_body)
92
+
93
+ @photo_io = FileUploadIO.new('/home/trooper/Projetos/Aggregator-Tests/public/images/eu_s2b.jpg', "image/jpeg")
94
+
95
+ headers = {
96
+ 'Content-Type' => 'multipart/related',
97
+ 'GData-Version' => '2',
98
+ 'Authorization' => "OAuth #{@client.access_token}",
99
+ 'MIME-version' => '1.0',
100
+ }
101
+ params = {
102
+ :file_0 => @xml_io,
103
+ :file_1 => @photo_io,
104
+ }
105
+ multipart_post = MultiPart::Post.new(params, headers)
106
+
107
+ res = multipart_post.submit(uri, nil, 'multipart/related')
108
+ status, headers, body = format_response(res)
109
+ case status
110
+ when 201
111
+ return body
112
+ else
113
+ return body
114
+ #raise(StandardError, "#{status.to_s} - #{body.to_s}")
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,86 @@
1
+ require 'picasa/version'
2
+
3
+ module Picasa
4
+ # Defines constants and methods related to configuration
5
+ module Config
6
+ # An array of valid keys in the options hash when configuring a {Picasa::API}
7
+
8
+ VALID_OPTIONS_KEYS = [
9
+ :base_uri,
10
+ :authorization_uri,
11
+ :token_credential_uri,
12
+ :client_id,
13
+ :client_secret,
14
+ :scope,
15
+ :redirect_uri,
16
+ :refresh_token,
17
+ :access_token,
18
+ :expires_in,
19
+ :issued_at,
20
+ :user_agent
21
+ ].freeze
22
+
23
+ DEFAULT_BASE_URI = 'https://picasaweb.google.com/data/'.freeze
24
+
25
+ DEFAULT_AUTHORIZATION_URI = 'https://accounts.google.com/o/oauth2/auth'.freeze
26
+
27
+ DEFAULT_TOKEN_CREDENTIAL_URI = 'https://accounts.google.com/o/oauth2/token'.freeze
28
+
29
+ DEFAULT_CLIENT_ID = nil
30
+
31
+ DEFAULT_CLIENT_SECRET = nil
32
+
33
+ DEFAULT_SCOPE = 'https://picasaweb.google.com/data/'.freeze
34
+
35
+ DEFAULT_REDIRECT_URI = ''
36
+
37
+ DEFAULT_REFRESH_TOKEN = nil
38
+
39
+ DEFAULT_ACCESS_TOKEN = nil
40
+
41
+ DEFAULT_EXPIRES_IN = nil
42
+
43
+ DEFAULT_ISSUED_AT = nil
44
+
45
+ # The value sent in the 'User-Agent' header if none is set
46
+ DEFAULT_USER_AGENT = "Picasa Ruby Gem #{Picasa::Version}".freeze
47
+
48
+ attr_accessor *VALID_OPTIONS_KEYS
49
+
50
+ # When this module is extended, set all configuration options to their default values
51
+ def self.extended(base)
52
+ base.reset
53
+ end
54
+
55
+ # Convenience method to allow configuration options to be set in a block
56
+ def configure
57
+ yield self
58
+ self
59
+ end
60
+
61
+ # Create a hash of options and their values
62
+ def options
63
+ options = {}
64
+ VALID_OPTIONS_KEYS.each{|k| options[k] = send(k)}
65
+ options
66
+ end
67
+
68
+ # Reset all configuration options to defaults
69
+ def reset
70
+ self.base_uri = DEFAULT_BASE_URI
71
+ self.authorization_uri = DEFAULT_AUTHORIZATION_URI
72
+ self.token_credential_uri = DEFAULT_TOKEN_CREDENTIAL_URI
73
+ self.client_id = DEFAULT_CLIENT_ID
74
+ self.client_secret = DEFAULT_CLIENT_SECRET
75
+ self.scope = DEFAULT_SCOPE
76
+ self.redirect_uri = DEFAULT_REDIRECT_URI
77
+ self.refresh_token = DEFAULT_REFRESH_TOKEN
78
+ self.access_token = DEFAULT_ACCESS_TOKEN
79
+ self.expires_in = DEFAULT_EXPIRES_IN
80
+ self.issued_at = DEFAULT_ISSUED_AT
81
+ self.user_agent = DEFAULT_USER_AGENT
82
+ self
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,43 @@
1
+ require 'signet/oauth_2/client'
2
+ require 'picasa/error'
3
+
4
+ module Picasa
5
+ module Connection
6
+
7
+ @client = nil
8
+
9
+ private
10
+ def connection(options={})
11
+ if client.nil?
12
+ client = Signet::OAuth2::Client.new(
13
+ :authorization_uri => authorization_uri,
14
+ :token_credential_uri => token_credential_uri,
15
+ :client_id => client_id,
16
+ :client_secret => client_secret,
17
+ :scope => scope,
18
+ :redirect_uri => redirect_uri,
19
+ :refresh_token => refresh_token,
20
+ :access_token => access_token
21
+ )
22
+ end
23
+ client
24
+ end
25
+
26
+ def update_token_values(object)
27
+ ::Picasa.configure do |config|
28
+ config.refresh_token = object.refresh_token
29
+ config.access_token = object.access_token
30
+ config.expires_in = object.expires_in
31
+ config.issued_at = Time.at(object.issued_at)
32
+ end
33
+ end
34
+
35
+ def get_token_values(object)
36
+ return {:refresh_token => object.refresh_token,
37
+ :access_token => object.access_token,
38
+ :expires_in => object.expires_in,
39
+ :issued_at => Time.at(object.issued_at)
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ module Picasa
2
+ class Error < StandardError
3
+
4
+ end
5
+ end
@@ -0,0 +1,54 @@
1
+ require 'picasa/error'
2
+ module Picasa
3
+ # Defines HTTP request methods
4
+ module Request
5
+
6
+ DEFAULT_HEADERS = {'Content-Type' => 'application/atom+xml', 'GData-Version' => '2'}
7
+ @refreshed = false
8
+
9
+ def get uri, headers = {}
10
+ response = request('GET', uri, nil, headers)
11
+ response
12
+ end
13
+
14
+ def post uri, body, headers = {}
15
+ response = request('POST', uri, body, DEFAULT_HEADERS.merge!(headers))
16
+ response
17
+ end
18
+
19
+ def put uri, body, headers = {}
20
+ response = request('PUT', uri, body, DEFAULT_HEADERS.merge!(headers))
21
+ response
22
+ end
23
+
24
+ def delete uri, headers = {}
25
+ response = request('DELETE', uri, nil, headers)
26
+ response
27
+ end
28
+
29
+ def multipart_post
30
+
31
+ end
32
+
33
+ private
34
+ def request method, uri, body = nil, headers = {}
35
+ begin
36
+ options = {:method => (method || 'GET'), :uri => uri}
37
+ options.merge!({:headers => headers}) unless headers.blank?
38
+ options.merge!({:body => body}) unless body.blank?
39
+
40
+ response = connection.fetch_protected_resource(options)
41
+ status, headers, body = response
42
+ case status
43
+ when 401, 403
44
+ connection.fetch_access_token!
45
+ response = request(method, uri, body, headers)
46
+ end
47
+ rescue Net::HTTPUnauthorized
48
+ connection.fetch_access_token!
49
+ response = request(method, uri, body, headers)
50
+ end
51
+ response
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ module Picasa
2
+ class Version
3
+
4
+ def self.major
5
+ 0
6
+ end
7
+
8
+ def self.minor
9
+ 0
10
+ end
11
+
12
+ def self.patch
13
+ 0
14
+ end
15
+
16
+ def self.pre
17
+ 1 #nil
18
+ end
19
+
20
+ def self.to_s
21
+ [major, minor, patch, pre].compact.join('.')
22
+ end
23
+
24
+ end
25
+ end
data/picasa.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "picasa/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'umanni-picasa'
7
+ s.version = Picasa::Version.to_s
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Umanni']
10
+ s.email = ['contato@umanni.com']
11
+ s.homepage = 'https://github.com/umanni/picasa'
12
+ s.summary = %q{Picasa Web API wrapper}
13
+ s.description = %q{A Ruby wrapper for the Picasa Web API.}
14
+ s.extra_rdoc_files = [
15
+ "LICENSE",
16
+ "README.rdoc"
17
+ ]
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency 'signet', [">= 0.2.4"]
25
+ s.add_dependency 'umanni-multipart-post'
26
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: umanni-picasa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Umanni
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-15 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: signet
16
+ requirement: &10630600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.2.4
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *10630600
25
+ - !ruby/object:Gem::Dependency
26
+ name: umanni-multipart-post
27
+ requirement: &10629780 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *10629780
36
+ description: A Ruby wrapper for the Picasa Web API.
37
+ email:
38
+ - contato@umanni.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - Gemfile
46
+ - LICENSE
47
+ - README.rdoc
48
+ - Rakefile
49
+ - lib/picasa.rb
50
+ - lib/picasa/api.rb
51
+ - lib/picasa/authenticatable.rb
52
+ - lib/picasa/base.rb
53
+ - lib/picasa/client.rb
54
+ - lib/picasa/client/base.rb
55
+ - lib/picasa/client/comments.rb
56
+ - lib/picasa/client/gallery.rb
57
+ - lib/picasa/client/media.rb
58
+ - lib/picasa/config.rb
59
+ - lib/picasa/connection.rb
60
+ - lib/picasa/error.rb
61
+ - lib/picasa/request.rb
62
+ - lib/picasa/version.rb
63
+ - picasa.gemspec
64
+ homepage: https://github.com/umanni/picasa
65
+ licenses: []
66
+ post_install_message:
67
+ rdoc_options: []
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 1.8.11
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Picasa Web API wrapper
88
+ test_files: []