picasaweb-backup 0.4.0 → 0.5.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65b528a9faea826628aa1501f2eb4fecd1a4859b
4
+ data.tar.gz: 5cdbe52dd1e524d088415b036ad20e38886f47ba
5
+ SHA512:
6
+ metadata.gz: 7b8acd1ddb8fe26302564dfdb8ff1fd269bc693ba238e9caf366e593498587e30b8f50e9d4fe90f39db79a807c75f412ec1f8018c78a4d2616d02c62ee37f5c5
7
+ data.tar.gz: 15365bbb6f58c8c2b98cb5416e0df10d01ac69f014a4c4057846724018da538b3ed7cafe5733d1f6da93e22afdbd6f53c5febf1fe6072bbae5a74e12bbd4cb84
data/.gitignore CHANGED
@@ -15,3 +15,7 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+
19
+ tokens.yaml
20
+ client_id.json
21
+ Albums
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
- gem "gdata_19", "~> 1.1.5"
3
- gem "artii", "~> 2.0.1"
4
- gem "colored", "~> 1.2"
2
+ gem 'artii', '~> 2.1', '>= 2.1.1'
3
+ gem 'colored', '~> 1.2'
4
+ gem 'googleauth', '~> 0.5.1'
5
+ gem 'http'
@@ -29,15 +29,23 @@ opt_parser = OptionParser.new('Backing up your Picasaweb photos') do |opt|
29
29
  end
30
30
 
31
31
  opt_parser.parse!(ARGV)
32
- cli = Picasaweb::CLI.new opts
33
32
 
34
- begin
33
+ if !File.exists?("client_id.json")
34
+ puts("No file client_id.json found. \n" \
35
+ "Please go to https://console.developers.google.com/apis/credentials "\
36
+ "to generate an OAuth CLI app and download, client_id.json file and "\
37
+ "place it in the directory where you run picasaweb-backup.")
35
38
 
36
- cli.start_backup
39
+ else
37
40
 
38
- rescue => e
39
- cli.print "ERROR: #{e.message}".red
40
- cli.print ""
41
- cli.print opt_parser
42
- end
41
+ begin
42
+
43
+ cli = Picasaweb::CLI.new opts
44
+ cli.start_backup
43
45
 
46
+ rescue => e
47
+ puts "ERROR: #{e.message}".red
48
+ puts e.backtrace
49
+ end
50
+
51
+ end
@@ -8,9 +8,11 @@
8
8
 
9
9
  require "version"
10
10
  require "yaml"
11
- require "rubygems"
12
- require "gdata"
13
11
  require "logger"
12
+ require 'googleauth'
13
+ require 'googleauth/stores/file_token_store'
14
+ require 'http'
15
+ require 'nokogiri'
14
16
 
15
17
  #monkey-patch logger formatting
16
18
  class Logger
@@ -20,24 +22,93 @@ class Logger
20
22
  end
21
23
 
22
24
  module Picasaweb
25
+ class Client
26
+
27
+ OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
28
+
29
+ def initialize
30
+ scope = 'https://picasaweb.google.com/data/'
31
+ client_id = Google::Auth::ClientId.from_file('client_id.json')
32
+ token_store = Google::Auth::Stores::FileTokenStore.new(:file => 'tokens.yaml')
33
+ authorizer = Google::Auth::UserAuthorizer.new(client_id, scope, token_store)
34
+
35
+ user_id = "picasaweb-backup"
36
+
37
+ credentials = authorizer.get_credentials(user_id)
38
+
39
+ if credentials.nil?
40
+ url = authorizer.get_authorization_url(base_url: OOB_URI )
41
+ puts "Open #{url} in your browser and enter the resulting code:"
42
+ code = gets
43
+ @credentials = authorizer.get_and_store_credentials_from_code(
44
+ user_id: user_id, code: code, base_url: OOB_URI)
45
+ else
46
+ puts "Found token #{credentials.access_token}. Refreshing..."
47
+ credentials.fetch_access_token!
48
+ @credentials = credentials
49
+ end
50
+ end
51
+
52
+ # Retrieves all albums for a user.
53
+ def get_albums
54
+ uri = "https://picasaweb.google.com/data/feed/api/user/default"
55
+ feed = get(uri)
56
+ entries = feed.css("entry")
57
+
58
+ entries.map do |entry|
59
+ { :id => entry.css('gphoto|id').text,
60
+ :user => entry.css('gphoto|user').text,
61
+ :title => entry.css('title').text }
62
+ end
63
+ end
64
+
65
+ # Retrieves all photos from an album.
66
+ def get_photos(album)
67
+ uri = "https://picasaweb.google.com/data/feed/api/user/" +
68
+ "default/albumid/#{album[:id]}?kind=photo&imgmax=d"
69
+
70
+ entries = get(uri).css("entry")
71
+
72
+ entries.map do |entry|
73
+ url = entry.css('media|group > media|content[url]').first.attribute("url").value
74
+ photo = { :id => entry.css('gphoto|id').text,
75
+ :album_id => entry.css('gphoto|albumid').text,
76
+ :title => entry.css('title').text,
77
+ :url => url
78
+ }
79
+ end
80
+ end
81
+
82
+
83
+ def get(url)
84
+ res = HTTP[:authorization => "Bearer #{@credentials.access_token}"].get(url)
85
+ Nokogiri::XML(res.body)
86
+ end
87
+
88
+ def download(photo)
89
+ response = HTTP.get(photo[:url])
90
+ File.open(photo[:title], 'w') { |f| f.write response.body }
91
+ end
92
+
93
+ end
94
+
23
95
  class CLI
96
+
24
97
  ALBUM_DIR = "Albums"
98
+
25
99
  def initialize opts
26
100
  @opts = opts
101
+ @client = Client.new
27
102
 
28
103
  if opts[:dir]
29
104
  Dir.chdir opts[:dir]
105
+ self.print "Changing working directory to #{opts[:dir]}"
30
106
  end
31
107
 
32
108
  if @opts[:log]
33
109
  @logger = Logger.new "picasaweb-backup.log", shift_age = "monthly"
34
110
  end
35
111
 
36
- if opts[:dir]
37
- self.print "Changing working directory to #{opts[:dir]}"
38
- end
39
-
40
- @account = File.open("account.yml", 'r') { |f| YAML.load f }
41
112
  end
42
113
 
43
114
  def print msg
@@ -48,67 +119,26 @@ module Picasaweb
48
119
  end
49
120
  end
50
121
 
51
- def verify_account account
52
- if account["username"].nil?
53
- raise "Please add your username to account.yml"
54
- elsif account["password"].nil?
55
- raise "Please add your password to account.yml"
56
- end
57
- end
58
-
59
- def picasa_client(username, password)
60
- client = GData::Client::Photos.new
61
- client.clientlogin(username, password)
62
- client
63
- end
64
-
65
- def ensure_exists dir
122
+ def ensure_exists(dir)
66
123
  if !File.directory? dir
67
124
  Dir.mkdir dir
68
125
  self.print "Creating directory '#{dir}'"
69
126
  end
70
127
  end
71
128
 
72
- # Retrieves all albums for a user.
73
- def get_albums(client, user = nil)
74
- uri = "http://picasaweb.google.com/data/feed/api/user/#{user || 'default'}"
75
- feed = client.get(uri).to_xml
76
- albums = []
77
- feed.elements.each('entry') do |entry|
78
- next unless entry.elements['gphoto:id']
79
- albums << { :id => entry.elements['gphoto:id'].text,
80
- :user => entry.elements['gphoto:user'].text,
81
- :title => entry.elements['title'].text }
82
- end
83
- albums
84
- end
85
-
86
- def download_album client, album
129
+ def download_album(client, album)
87
130
  Dir.chdir album[:title] do
88
131
  self.print "Checking for new photos in '#{album[:title]}'"
89
132
  photos = nil
90
133
  until photos
91
- begin
92
- photos = get_photos client, album
93
- rescue GData::Client::ServerError
94
- "Server error, retrying\n"
95
- end
134
+ photos = client.get_photos(album)
96
135
  end
97
136
 
98
137
  downloaded_photos = 0
99
138
  photos.each do |photo|
100
139
  if !File.exists? photo[:title]
101
140
  self.print " ==> #{photo[:title]}"
102
- response = nil
103
- until response
104
- begin
105
- response = client.get photo[:url]
106
- rescue GData::Client::ServerError
107
- "Server error, retrying\n"
108
- end
109
- end
110
-
111
- File.open(photo[:title], 'w') { |f| f.write response.body }
141
+ client.download(photo)
112
142
  downloaded_photos += 1
113
143
  end
114
144
  end
@@ -118,38 +148,17 @@ module Picasaweb
118
148
  end
119
149
  end
120
150
 
121
- # Retrieves all photos from an album.
122
- def get_photos(client, album)
123
- uri = "http://picasaweb.google.com/data/feed/api/user/" +
124
- "#{album[:user] || 'default'}/albumid/#{album[:id]}?kind=photo&imgmax=d"
125
-
126
- feed = client.get(uri).to_xml
127
- photos = []
128
- feed.elements.each('entry') do |entry|
129
- next unless entry.elements['gphoto:id']
130
- next unless entry.elements['media:group']
131
- photo = { :id => entry.elements['gphoto:id'].text,
132
- :album_id => entry.elements['gphoto:albumid'].text,
133
- :title => entry.elements['title'].text }
134
- entry.elements['media:group'].elements.each('media:content') do |content|
135
- photo[:url] = content.attribute('url').value
136
- end
137
- photos << photo
138
- end
139
- photos
140
- end
141
-
142
151
  def start_backup
143
- verify_account @account
144
- client = picasa_client @account["username"], @account["password"]
145
- albums = get_albums client
152
+ albums = @client.get_albums.select do |album|
153
+ album[:title].downcase != "auto backup"
154
+ end
146
155
 
147
- ensure_exists ALBUM_DIR
156
+ ensure_exists(ALBUM_DIR)
148
157
  Dir.chdir ALBUM_DIR
149
158
 
150
159
  albums.each do |album|
151
160
  ensure_exists album[:title]
152
- download_album client, album
161
+ download_album(@client, album)
153
162
  end
154
163
 
155
164
  end
@@ -1,5 +1,5 @@
1
1
  module Picasaweb
2
2
  module Backup
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -3,16 +3,17 @@ require File.expand_path('../lib/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Leonard Ehrenfried"]
6
- gem.email = ['leonard.ehrenfried@web.de']
6
+ gem.email = ['leonard.ehrenfried@gmail.com']
7
7
  gem.summary = "Picasa Web Albums backup tool"
8
8
  gem.description = %{Backup all your photos from Google's Picasa Web Albums service,
9
9
  can be run repeatedly on the same folder and only downloads new files.}
10
10
 
11
- gem.homepage = 'http://github.com/lenniboy/picasaweb-backup'
11
+ gem.homepage = 'http://github.com/leonardehrenfried/picasaweb-backup'
12
12
 
13
- gem.add_dependency('gdata_19', '~> 1.1.5')
14
- gem.add_dependency('artii', '~> 2.0.1')
15
- gem.add_dependency('colored', '~> 1.2')
13
+ gem.add_dependency('artii', '~> 2.1')
14
+ gem.add_dependency('colored', '~> 1.2')
15
+ gem.add_dependency('googleauth', '~> 0.5.1')
16
+ gem.add_dependency('http', '~> 2.1')
16
17
 
17
18
  gem.files = `git ls-files`.split($\)
18
19
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
metadata CHANGED
@@ -1,74 +1,82 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picasaweb-backup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Leonard Ehrenfried
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-08 00:00:00.000000000 Z
11
+ date: 2016-12-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- name: gdata_19
14
+ name: artii
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: 1.1.5
19
+ version: '2.1'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
- version: 1.1.5
26
+ version: '2.1'
30
27
  - !ruby/object:Gem::Dependency
31
- name: artii
28
+ name: colored
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
- version: 2.0.1
33
+ version: '1.2'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
- version: 2.0.1
40
+ version: '1.2'
46
41
  - !ruby/object:Gem::Dependency
47
- name: colored
42
+ name: googleauth
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
- version: '1.2'
47
+ version: 0.5.1
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
- version: '1.2'
62
- description: ! "Backup all your photos from Google's Picasa Web Albums service,\n
63
- \ can be run repeatedly on the same folder and only downloads new files."
54
+ version: 0.5.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: http
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.1'
69
+ description: |-
70
+ Backup all your photos from Google's Picasa Web Albums service,
71
+ can be run repeatedly on the same folder and only downloads new files.
64
72
  email:
65
- - leonard.ehrenfried@web.de
73
+ - leonard.ehrenfried@gmail.com
66
74
  executables:
67
75
  - picasaweb-backup
68
76
  extensions: []
69
77
  extra_rdoc_files: []
70
78
  files:
71
- - .gitignore
79
+ - ".gitignore"
72
80
  - Gemfile
73
81
  - Gemfile.lock
74
82
  - LICENSE
@@ -78,28 +86,27 @@ files:
78
86
  - lib/picasaweb-backup.rb
79
87
  - lib/version.rb
80
88
  - picasaweb-backup.gemspec
81
- homepage: http://github.com/lenniboy/picasaweb-backup
89
+ homepage: http://github.com/leonardehrenfried/picasaweb-backup
82
90
  licenses: []
91
+ metadata: {}
83
92
  post_install_message:
84
93
  rdoc_options: []
85
94
  require_paths:
86
95
  - lib
87
96
  required_ruby_version: !ruby/object:Gem::Requirement
88
- none: false
89
97
  requirements:
90
- - - ! '>='
98
+ - - ">="
91
99
  - !ruby/object:Gem::Version
92
100
  version: '0'
93
101
  required_rubygems_version: !ruby/object:Gem::Requirement
94
- none: false
95
102
  requirements:
96
- - - ! '>='
103
+ - - ">="
97
104
  - !ruby/object:Gem::Version
98
105
  version: '0'
99
106
  requirements: []
100
107
  rubyforge_project:
101
- rubygems_version: 1.8.24
108
+ rubygems_version: 2.4.5
102
109
  signing_key:
103
- specification_version: 3
110
+ specification_version: 4
104
111
  summary: Picasa Web Albums backup tool
105
112
  test_files: []