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 +1 -0
- data/README.md +13 -0
- data/example/add_tags_to_photo.rb +20 -0
- data/example/create_new_album.rb +13 -0
- data/example/delete_all_photos.rb +20 -0
- data/example/get_some_albums.rb +12 -0
- data/example/get_some_photos.rb +16 -0
- data/example/upload_photo.rb +23 -0
- data/extra/Thorfile +36 -13
- data/lib/picasa/api/album.rb +3 -2
- data/lib/picasa/api/photo.rb +19 -0
- data/lib/picasa/api/tag.rb +22 -2
- data/lib/picasa/presenter/album.rb +1 -1
- data/lib/picasa/presenter/photo.rb +2 -2
- data/lib/picasa/templates/new_tag.xml.erb +4 -0
- data/lib/picasa/version.rb +1 -1
- data/test/api/tag_test.rb +24 -1
- metadata +8 -1
data/Gemfile
CHANGED
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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(
|
30
|
-
|
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
|
data/lib/picasa/api/album.rb
CHANGED
@@ -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}")
|
data/lib/picasa/api/photo.rb
CHANGED
@@ -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
|
data/lib/picasa/api/tag.rb
CHANGED
@@ -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
|
@@ -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"))
|
23
|
+
@id ||= array_wrap(safe_retrieve(parsed_body, "id")).last
|
24
24
|
end
|
25
25
|
|
26
26
|
# @return [String]
|
data/lib/picasa/version.rb
CHANGED
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
|
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.
|
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
|