picasa 0.5.0 → 0.5.1

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