picasa-downloader 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -4,4 +4,5 @@ task :default => 'test'
4
4
  desc "Run tests"
5
5
  task :test do
6
6
  sh "bundle exec rspec"
7
+ sh "bundle exec cucumber"
7
8
  end
data/TODO.md CHANGED
@@ -1,4 +1,7 @@
1
1
  # TODO
2
2
 
3
- * Persist albums into year directiories
3
+ * Possibility to determine the target root directory via CLI
4
+ * Cucumber tests for happy paths
5
+ * Use median year to determine the target directory
4
6
  * Video download
7
+ * Allow synchronising with online albums
@@ -6,28 +6,58 @@ require 'gli'
6
6
 
7
7
  include GLI
8
8
 
9
- default_download_dir=ENV['HOME'] + '/Picasa-albums'
9
+ @default_download_dir=ENV['HOME'] + '/Picasa-albums'
10
10
 
11
11
  program_desc 'Picasa downloader'
12
12
 
13
13
  desc 'Download all albums'
14
- long_desc "Download all Picasa albums into #{default_download_dir}"
14
+ long_desc "Download all Picasa albums into #{@default_download_dir}"
15
15
  command [:all] do |c|
16
16
  c.action do |global_options,options,args|
17
+ client = authenticate
18
+ albums = list_albums(client)
19
+ puts "Downloading #{albums.length} albums into #{@default_download_dir}..."
20
+ albums.each { |album|
21
+ download(album, client)
22
+ }
23
+ end
24
+ end
25
+
26
+ desc 'Download one album'
27
+ command [:album] do |c|
28
+ c.action do |global_options,options,args|
29
+ if args.length == 0
30
+ raise PicasaDownloader::AlbumNameNotSpecified
31
+ end
32
+ album_regex = args[0]
33
+ client = authenticate
34
+ albums = list_albums(client)
35
+ albums_to_download = albums.select { |album|
36
+ album.title.match(album_regex)
37
+ }
38
+ albums_to_download.each { |album|
39
+ download(album, client)
40
+ }
41
+ end
42
+ end
43
+
44
+ def download(album, client)
45
+ puts " downloading #{album.title}..."
46
+ PicasaDownloader::AlbumPersister.
47
+ new(client, album, @default_download_dir).download
48
+ end
49
+
50
+ def authenticate
17
51
  credentials = PicasaDownloader::EnvCredentials.new
18
52
  raise PicasaDownloader::EnvironmentalCredentialsNotSet unless
19
53
  credentials.is_configured?
20
54
  puts "Authenticating..."
21
55
  client = PicasaDownloader::Client.new(credentials)
56
+ end
57
+
58
+ def list_albums(client)
22
59
  puts "Fetching the album list..."
23
60
  albums = client.list_albums
24
- puts "Downloading #{albums.length} albums into #{default_download_dir}..."
25
- albums.each { |album|
26
- puts " downloading #{album.title}..."
27
- PicasaDownloader::AlbumPersister.
28
- new(client, album, default_download_dir).download
29
- }
30
- end
31
61
  end
32
62
 
33
63
  exit GLI.run(ARGV)
@@ -0,0 +1,21 @@
1
+ Feature: Picasa downloader
2
+
3
+ In order to conveniently download my photos from Google Picasa
4
+ As a geek
5
+ I want to run picasa-downloader and see photo albums appearing on my local disk
6
+
7
+ Scenario: Run picasa-downloader without arguments
8
+ When I run `picasa-downloader`
9
+ Then the output should contain:
10
+ """
11
+ Picasa downloader
12
+
13
+ usage: picasa-downloader [global options] command [command options]
14
+ """
15
+
16
+ Scenario: Try downloading single album with insufficient CLI arguments
17
+ When I run `picasa-downloader album`
18
+ Then the output should contain:
19
+ """
20
+ error: Album name is not specified.
21
+ """
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ Bundler.require
5
+
6
+ require 'aruba/cucumber'
7
+ require 'cucumber/rspec/doubles'
8
+
9
+ # Following from 'aruba/cucumber'
10
+ Before do
11
+ @__aruba_original_paths = (ENV['PATH'] || '').split(File::PATH_SEPARATOR)
12
+ ENV['PATH'] = ([File.expand_path('bin')] + @__aruba_original_paths).join(File::PATH_SEPARATOR)
13
+ end
14
+
15
+ After do
16
+ ENV['PATH'] = @__aruba_original_paths.join(File::PATH_SEPARATOR)
17
+ end
18
+ # End of following from 'aruba/cucumber'
19
+
20
+ Then /^the file "([^"]*)" should contain:$/ do |file, exact_content|
21
+ check_file_content(file, exact_content, true)
22
+ end
@@ -19,30 +19,50 @@ module PicasaDownloader
19
19
  doc = to_xml(
20
20
  "https://picasaweb.google.com/data/feed/api/user/default/albumid/#{album_id}?imgmax=d")
21
21
  doc.css("entry").map { |e|
22
+ timestamp = e.css("tags time")
23
+ timestamp = e.css("timestamp") unless timestamp
22
24
  Photo.new(
23
25
  e.xpath("group/content/@url").to_s,
24
26
  # Google includes the milliseconds in the timestamp:
25
- e.css("timestamp").inner_text.to_i / 1000,
27
+ timestamp.inner_text.to_i / 1000,
26
28
  e.css("size").inner_text.to_i,
27
29
  e.css("title").first.inner_text)
28
30
  }
29
31
  end
30
32
 
31
33
  def download_photo(photo)
32
- unless photo.url.include?"googlevideo"
33
- uri = URI.parse(photo.url)
34
- http = Net::HTTP.new(uri.host, uri.port)
35
- request = Net::HTTP::Get.new(uri.request_uri)
36
- http.use_ssl = true
37
- response = http.request(request)
38
- raise "Response not ok, was #{response.code}" unless
39
- response.code.to_i.between? 200, 299
40
- response.body
34
+ if photo.has_video?
35
+ # Downloading videos is not supported yet
36
+ else
37
+ with_retry {
38
+ uri = URI.parse(photo.url)
39
+ http = Net::HTTP.new(uri.host, uri.port)
40
+ request = Net::HTTP::Get.new(uri.request_uri)
41
+ http.use_ssl = true
42
+ response = http.request(request)
43
+ raise "Response not ok, was #{response.code}" unless
44
+ response.code.to_i.between? 200, 299
45
+ response.body
46
+ }
41
47
  end
42
48
  end
43
49
 
44
50
  private
45
51
 
52
+ def with_retry
53
+ retries = [3, 5]
54
+ begin
55
+ yield
56
+ rescue Exception
57
+ if delay = retries.shift
58
+ sleep delay
59
+ retry
60
+ else
61
+ raise
62
+ end
63
+ end
64
+ end
65
+
46
66
  def to_xml(gdata_url)
47
67
  response = @gd.get(gdata_url)
48
68
  xml = response.to_xml.to_s
@@ -3,7 +3,15 @@ module PicasaDownloader
3
3
  end
4
4
 
5
5
  class EnvironmentalCredentialsNotSet < PicasaDownloaderError
6
- def initialize(message = 'Cannot authenticate - environmental settings missing. Please set the environmental values PICASA_USERNAME and PICASA_PASSWORD')
6
+ def initialize(message =
7
+ 'Cannot authenticate - environmental settings missing. Please set the environmental values PICASA_USERNAME and PICASA_PASSWORD.')
8
+ super(message)
9
+ end
10
+ end
11
+
12
+ class AlbumNameNotSpecified < PicasaDownloaderError
13
+ def initialize(message =
14
+ 'Album name is not specified.')
7
15
  super(message)
8
16
  end
9
17
  end
@@ -8,5 +8,9 @@ module PicasaDownloader
8
8
  @size = size
9
9
  @name = name
10
10
  end
11
+
12
+ def has_video?
13
+ @url.include?'googlevideo'
14
+ end
11
15
  end
12
16
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'picasa-downloader'
3
- s.version = '0.0.3'
3
+ s.version = '0.0.4'
4
4
  s.license = 'MIT'
5
5
  s.summary = 'Download your Google Picasa photo albums'
6
6
  s.description =
@@ -26,4 +26,6 @@ Gem::Specification.new do |s|
26
26
  s.add_development_dependency 'rspec'
27
27
  s.add_development_dependency 'vcr'
28
28
  s.add_development_dependency 'webmock'
29
+ s.add_development_dependency 'cucumber'
30
+ s.add_development_dependency 'aruba', '>= 0.4.7'
29
31
  end
data/spec/client_spec.rb CHANGED
@@ -36,13 +36,13 @@ module PicasaDownloader
36
36
 
37
37
  it "downloads photos photos of an album" do
38
38
  with_cassettes {
39
- @albums = @client.list_albums
40
- @photos = @client.list_photos(@albums.first.id)
39
+ albums = @client.list_albums
40
+ photos = @client.list_photos(albums.first.id)
41
41
  def jpeg?(data)
42
42
  # See http://www.astro.keele.ac.uk/oldusers/rno/Computing/File_magic.html
43
43
  return data[0, 4] == "\xff\xd8\xff\xe0"
44
44
  end
45
- bytes = @client.download_photo(@photos.first)
45
+ bytes = @client.download_photo(photos.first)
46
46
  jpeg?(bytes).should be true
47
47
  }
48
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picasa-downloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-21 00:00:00.000000000 Z
12
+ date: 2012-07-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gdata_19
@@ -139,6 +139,38 @@ dependencies:
139
139
  - - ! '>='
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: cucumber
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: aruba
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: 0.4.7
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: 0.4.7
142
174
  description: This Gem makes it convenient to download Picasa albums via command-line
143
175
  interface
144
176
  email: lauri.lehmijoki@iki.fi
@@ -154,6 +186,8 @@ files:
154
186
  - Rakefile
155
187
  - TODO.md
156
188
  - bin/picasa-downloader
189
+ - features/picasa-downloader.feature
190
+ - features/support/env.rb
157
191
  - fixtures/cassettes/google-login.yml
158
192
  - fixtures/cassettes/picasa-album.yml
159
193
  - fixtures/cassettes/picasa-albums.yml