picasa 0.5.0 → 0.5.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/Gemfile CHANGED
@@ -2,6 +2,7 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
+ gem "thor"
5
6
  gem "rake"
6
7
  gem "minitest", :platform => :ruby_18
7
8
  gem "debugger", :platform => :ruby_19
data/README.md CHANGED
@@ -41,12 +41,24 @@ You can install thor script for uploading all photos from given directory:
41
41
  thor install https://github.com/morgoth/picasa/raw/master/extra/Thorfile --as picasa_uploader --force
42
42
  ```
43
43
 
44
+ Updating script can be done by:
45
+
46
+ ```
47
+ thor update picasa_uploader
48
+ ```
49
+
44
50
  And then use it (it will create album taking title from folder name and upload all photos from that directory):
45
51
 
46
52
  ```
47
53
  GOOGLE_USER_ID=your.email@gmail.com GOOGLE_PASSWORD=secret thor picasa_uploader:upload_all path-to-folder-with-photos
48
54
  ```
49
55
 
56
+ If your upload was somehow interrupted, you can resume it by adding `--continue` option:
57
+
58
+ ```
59
+ GOOGLE_USER_ID=your.email@gmail.com GOOGLE_PASSWORD=secret thor picasa_uploader:upload_all --continue path-to-folder-with-photos
60
+ ```
61
+
50
62
  ## Continuous Integration
51
63
  [![Build Status](https://secure.travis-ci.org/morgoth/picasa.png)](http://travis-ci.org/morgoth/picasa)
52
64
 
@@ -56,6 +68,7 @@ GOOGLE_USER_ID=your.email@gmail.com GOOGLE_PASSWORD=secret thor picasa_uploader:
56
68
  * [Rafael Souza](https://github.com/rafaels)
57
69
  * [jsaak](https://github.com/jsaak)
58
70
  * [Javier Guerra](https://github.com/javierg)
71
+ * [Eiichi Takebuchi](https://github.com/GRGSIBERIA)
59
72
 
60
73
  ## Copyright
61
74
 
@@ -0,0 +1,20 @@
1
+ require "picasa"
2
+
3
+ # add tags to your photos in an album.
4
+ begin
5
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
6
+ albums = client.album.list.entries
7
+ album = albums.find { |album| album.title == "New Album" }
8
+
9
+ photos = client.album.show(album.id).entries
10
+
11
+ photos.each do |photo|
12
+ client.tag.create(
13
+ :album_id => album.id,
14
+ :photo_id => photo.id,
15
+ :tag_name => "test")
16
+ end
17
+
18
+ rescue Picasa::ForbiddenError
19
+ puts "You have the wrong user_id or password."
20
+ end
@@ -0,0 +1,13 @@
1
+ require "picasa"
2
+
3
+ begin
4
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
5
+ # create new album.
6
+ client.album.create(
7
+ :title => "New Album",
8
+ :summary => "This is a new album.",
9
+ :access => "protected")
10
+
11
+ rescue Picasa::ForbiddenError
12
+ puts "You have the wrong user_id or password."
13
+ end
@@ -0,0 +1,20 @@
1
+ require "picasa"
2
+
3
+ # delete all photos in an album.
4
+ begin
5
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
6
+ albums = client.album.list.entries
7
+ album = albums.find { |album| album.title == "New Album" }
8
+
9
+ photos = client.album.show(album.id).entries
10
+
11
+ photos.each do |photo|
12
+ if client.tag.delete(album_id, photo.id)
13
+ "#{photo.title} deleted"
14
+ else
15
+ "#{photo.title} failed to delete"
16
+ end
17
+ end
18
+ rescue Picasa::ForbiddenError
19
+ puts "You have the wrong user_id or password."
20
+ end
@@ -0,0 +1,12 @@
1
+ require "picasa"
2
+
3
+ # get some albums.
4
+ begin
5
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
6
+
7
+ albums = client.album.list.entries
8
+ albums.each { |album| puts album.title }
9
+
10
+ rescue Picasa::ForbiddenError
11
+ puts "You have the wrong user_id or password."
12
+ end
@@ -0,0 +1,16 @@
1
+ require "picasa"
2
+
3
+ # get some photos in an album
4
+ begin
5
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
6
+
7
+ albums = client.album.list.entries
8
+ album = albums.find { |album| album.title == "New Album" }
9
+
10
+ photos = client.album.show(album.id).entries
11
+
12
+ photos.each { |photo| puts photo.title }
13
+
14
+ rescue Picasa::ForbiddenError
15
+ puts "You have the wrong user_id or password."
16
+ end
@@ -0,0 +1,23 @@
1
+ require "picasa"
2
+
3
+ # upload photo
4
+ begin
5
+ client = Picasa::Client.new(:user_id => "your_gmail_account", :password => "password")
6
+
7
+ photo_bin = File.binread("./test.jpg")
8
+
9
+ albums = client.album.list.entries
10
+ album = albums.find { |album| album.title == "New Album" }
11
+
12
+ client.photo.create(album.id,
13
+ {
14
+ :binary => photo_bin,
15
+ :content_type => "image/jpeg",
16
+ :title => "Test Photo",
17
+ :summary => "Hoge hoge"
18
+ }
19
+ )
20
+
21
+ rescue Picasa::ForbiddenError
22
+ puts "You have the wrong user_id or password."
23
+ end
data/extra/Thorfile CHANGED
@@ -6,35 +6,58 @@ MultiXml.parser = :libxml
6
6
  class PicasaUploader < Thor
7
7
  include Thor::Actions
8
8
 
9
- desc "upload_all DIR", "Uploads all photos from given directory"
9
+ desc "upload_all DIR", "Uploads all photos from given directory (pass --continue to resume uploading)"
10
+ method_options continue: false
10
11
  def upload_all(dir = File.basename(Dir.getwd))
11
12
  require_credentials
12
- album_presenter = create_album(File.basename(dir))
13
- photos_number = 0
14
- inside(dir, :verbose => true) do
15
- Dir.entries(".").select { |e| e =~ /\.(jpg|jpeg|png|gif|bmp)$/i }.sort.each do |file|
16
- create_photo(album_presenter, file)
13
+
14
+ inside(dir, verbose: true) do
15
+ entries = Dir.entries(".").select { |e| e =~ /\.(jpg|jpeg|png|gif|bmp)$/i }.sort
16
+ album_name = File.basename(dir)
17
+ photos_number = 0
18
+
19
+ if options[:continue]
20
+ # We're looking for existing album and photos already uploaded
21
+ albums = client.album.list(fields: "entry(title,gphoto:id)")
22
+ album = albums.entries.find { |a| a.title == album_name }
23
+ if album
24
+ say "Album #{album_name} found - continuing upload"
25
+ else
26
+ say "Album #{album_name} not found in your collection - aborting" and exit
27
+ end
28
+
29
+ photo_titles = client.album.show(album.id, fields: "entry/title").entries.map &:title
30
+
31
+ entries.reject! { |e| photo_titles.include?(File.basename(e, ".*")) }
32
+ else
33
+ say("Creating album: #{album_name}")
34
+ album = create_album(album_name)
35
+ end
36
+
37
+ entries.each do |file|
17
38
  photos_number += 1
39
+ say("Uploading photo #{file} to album #{album.title} - #{photos_number}/#{entries.size}")
40
+ create_photo(album, file)
18
41
  end
42
+ say "Finished uploading #{photos_number} photos"
19
43
  end
20
- say "Finished uploading #{photos_number} photos"
21
44
  end
22
45
 
23
46
  no_tasks do
47
+ def client
48
+ @client ||= Picasa::Client.new(user_id: ENV["GOOGLE_USER_ID"], password: ENV["GOOGLE_PASSWORD"])
49
+ end
50
+
24
51
  def require_credentials
25
52
  say "You must specify GOOGLE_USER_ID env variable" and exit unless ENV["GOOGLE_USER_ID"]
26
53
  say "You must specify GOOGLE_PASSWORD env variable" and exit unless ENV["GOOGLE_PASSWORD"]
27
54
  end
28
55
 
29
- def create_album(album)
30
- say("Creating album: #{album}")
31
- client = Picasa::Client.new(user_id: ENV["GOOGLE_USER_ID"], password: ENV["GOOGLE_PASSWORD"])
32
- client.album.create(title: album)
56
+ def create_album(title)
57
+ client.album.create(title: title)
33
58
  end
34
59
 
35
60
  def create_photo(album, path)
36
- say("Uploading photo #{path} to album #{album.title}")
37
- client = Picasa::Client.new(user_id: ENV["GOOGLE_USER_ID"], password: ENV["GOOGLE_PASSWORD"])
38
61
  client.photo.create(album.id, file_path: path)
39
62
  end
40
63
  end
@@ -23,6 +23,7 @@ module Picasa
23
23
  #
24
24
  # @param [String] album_id album id
25
25
  # @param [Hash] options additional options included in request
26
+ # @option options [String] :fields which fields should be retrieved https://developers.google.com/gdata/docs/2.0/reference#PartialResponseRequest
26
27
  # @option options [String, Integer] :max_results max number of returned results
27
28
  # @option options [String] :tag include photos with given tag only
28
29
  #
@@ -41,14 +42,14 @@ module Picasa
41
42
  # @option options [String] :title title of album (required)
42
43
  # @option options [String] :summary summary of album
43
44
  # @option options [String] :location location of album photos (i.e. Poland)
44
- # @option options [String] :access [public, private, protected]
45
+ # @option options [String] :access ["public", "private", "protected"] (default to private)
45
46
  # @option options [String] :timestamp timestamp of album (default to now)
46
47
  # @option options [String] :keywords keywords (i.e. "vacation, poland")
47
- #
48
48
  # @return [Presenter::Album]
49
49
  def create(params = {})
50
50
  params[:title] || raise(ArgumentError, "You must specify title")
51
51
  params[:timestamp] ||= Time.now.to_i
52
+ params[:access] ||= "private"
52
53
 
53
54
  template = Template.new(:new_album, params)
54
55
  uri = URI.parse("/data/feed/api/user/#{user_id}")
@@ -18,6 +18,7 @@ module Picasa
18
18
  params[:title] ||= (file && file.name) || raise(ArgumentError.new("title must be specified"))
19
19
  params[:binary] ||= (file && file.binary) || raise(ArgumentError.new("binary must be specified"))
20
20
  params[:content_type] ||= (file && file.content_type) || raise(ArgumentError.new("content_type must be specified"))
21
+
21
22
  template = Template.new(:new_photo, params)
22
23
  headers = {"Content-Type" => "multipart/related; boundary=\"#{params[:boundary]}\""}
23
24
 
@@ -25,6 +26,24 @@ module Picasa
25
26
  parsed_body = Connection.new(credentials).post(uri.path, template.render, headers)
26
27
  Presenter::Photo.new(parsed_body["entry"])
27
28
  end
29
+
30
+ # Destroys given photo
31
+ #
32
+ # @param [String] album_id album id
33
+ # @param [String] photo_id photo id
34
+ # @param [Hash] options request parameters
35
+ # @option options [String] :etag destroys only when ETag matches - protects before destroying other client changes
36
+ #
37
+ # @return [true]
38
+ # @raise [NotFoundError] raised when album or photo cannot be found
39
+ # @raise [PreconditionFailedError] raised when ETag does not match
40
+ def destroy(album_id, photo_id, options = {})
41
+ headers = {"If-Match" => options.fetch(:etag, "*")}
42
+ uri = URI.parse("/data/entry/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}")
43
+ Connection.new(credentials).delete(uri.path, headers)
44
+ true
45
+ end
46
+ alias :delete :destroy
28
47
  end
29
48
  end
30
49
  end
@@ -20,11 +20,31 @@ module Picasa
20
20
  path << "/photoid/#{photo_id}" if photo_id
21
21
 
22
22
  uri = URI.parse(path)
23
-
24
23
  parsed_body = Connection.new(credentials).get(uri.path, options.merge(:kind => "tag"))
25
-
26
24
  Presenter::TagList.new(parsed_body["feed"])
27
25
  end
26
+
27
+ # Creates a tag for a photo.
28
+ #
29
+ # @param [Hash]
30
+ # @option options [String] :album_id id pof album
31
+ # @option options [String] :photo_id id of photo
32
+ # @option options [String] :title name of tag
33
+ #
34
+ # @return [Presenter::Tag]
35
+ def create(params = {})
36
+ album_id = params.delete(:album_id) || raise(ArgumentError, "You must specify album_id")
37
+ photo_id = params.delete(:photo_id) || raise(ArgumentError, "You must specify photo_id")
38
+ params[:title] || raise(ArgumentError, "You must specify title")
39
+
40
+ path = "/data/feed/api/user/#{user_id}/albumid/#{album_id}/photoid/#{photo_id}"
41
+
42
+ template = Template.new("new_tag", params)
43
+
44
+ uri = URI.parse(path)
45
+ parsed_body = Connection.new(credentials).post(uri.path, template.render)
46
+ Presenter::Tag.new(parsed_body["entry"])
47
+ end
28
48
  end
29
49
  end
30
50
  end
@@ -56,7 +56,7 @@ module Picasa
56
56
 
57
57
  # @return [String]
58
58
  def id
59
- @id ||= array_wrap(safe_retrieve(parsed_body, "id"))[1]
59
+ @id ||= array_wrap(safe_retrieve(parsed_body, "id")).last
60
60
  end
61
61
 
62
62
  # @return [String]
@@ -5,7 +5,7 @@ module Picasa
5
5
  class Photo < Base
6
6
  # @return [Array<Presenter::Link>]
7
7
  def links
8
- @links ||= safe_retrieve(parsed_body, "link").map { |link| Link.new(link) }
8
+ @links ||= array_wrap(safe_retrieve(parsed_body, "link")).map { |link| Link.new(link) }
9
9
  end
10
10
 
11
11
  # @return [Presenter::Media]
@@ -20,7 +20,7 @@ module Picasa
20
20
 
21
21
  # @return [String]
22
22
  def id
23
- @id ||= array_wrap(safe_retrieve(parsed_body, "id"))[1]
23
+ @id ||= array_wrap(safe_retrieve(parsed_body, "id")).last
24
24
  end
25
25
 
26
26
  # @return [String]
@@ -0,0 +1,4 @@
1
+ <entry xmlns="http://www.w3.org/2005/Atom">
2
+ <title><%= title %></title>
3
+ <category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/photos/2007#tag"/>
4
+ </entry>
@@ -1,3 +1,3 @@
1
1
  module Picasa
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
data/test/api/tag_test.rb CHANGED
@@ -3,7 +3,7 @@ require "helper"
3
3
 
4
4
  describe Picasa::API::Tag do
5
5
  describe "#list" do
6
- it "throws ArgumentErro when photo_id provided without album_id" do
6
+ it "throws ArgumentError when photo_id provided without album_id" do
7
7
  tag = Picasa::API::Tag.new(:user_id => "w.wnetrzak")
8
8
 
9
9
  assert_raises Picasa::ArgumentError, /album_id/ do
@@ -19,4 +19,27 @@ describe Picasa::API::Tag do
19
19
  assert_equal 2, tag_list.entries.size
20
20
  end
21
21
  end
22
+
23
+ describe "#create" do
24
+ it "raises ArgumentError when no album_id" do
25
+ tag = Picasa::API::Tag.new(:user_id => "w.wnetrzak@gmail.com", :password => "secret")
26
+ assert_raises Picasa::ArgumentError, /album_id/ do
27
+ tag.create(:photo_id => "455", :title => "title")
28
+ end
29
+ end
30
+
31
+ it "raises ArgumentError when no photo_id" do
32
+ tag = Picasa::API::Tag.new(:user_id => "w.wnetrzak@gmail.com", :password => "secret")
33
+ assert_raises Picasa::ArgumentError, /photo_id/ do
34
+ tag.create(:album_id => "123", :title => "title")
35
+ end
36
+ end
37
+
38
+ it "raises ArgumentError when no title" do
39
+ tag = Picasa::API::Tag.new(:user_id => "w.wnetrzak@gmail.com", :password => "secret")
40
+ assert_raises Picasa::ArgumentError, /title/ do
41
+ tag.create(:album_id => "123", :photo_id => "455")
42
+ end
43
+ end
44
+ end
22
45
  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.5.0
4
+ version: 0.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -72,6 +72,12 @@ files:
72
72
  - LICENSE
73
73
  - README.md
74
74
  - Rakefile
75
+ - example/add_tags_to_photo.rb
76
+ - example/create_new_album.rb
77
+ - example/delete_all_photos.rb
78
+ - example/get_some_albums.rb
79
+ - example/get_some_photos.rb
80
+ - example/upload_photo.rb
75
81
  - extra/Thorfile
76
82
  - lib/picasa.rb
77
83
  - lib/picasa/api/album.rb
@@ -96,6 +102,7 @@ files:
96
102
  - lib/picasa/template.rb
97
103
  - lib/picasa/templates/new_album.xml.erb
98
104
  - lib/picasa/templates/new_photo.xml.erb
105
+ - lib/picasa/templates/new_tag.xml.erb
99
106
  - lib/picasa/utils.rb
100
107
  - lib/picasa/version.rb
101
108
  - picasa.gemspec