gdata-backup 0.0.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.
@@ -0,0 +1,5 @@
1
+ /bin/stubs
2
+ /.bundle
3
+ /Gemfile.lock
4
+ /pkg/
5
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
@@ -0,0 +1,53 @@
1
+ gdata-backup
2
+ ============
3
+ Make a local copy of Google Docs via the command line.
4
+
5
+ This program makes it easy to download your Google Docs for backup, e.g. via a cron job.
6
+
7
+ Installation
8
+ ============
9
+
10
+ ```
11
+ bundle
12
+ ```
13
+
14
+ Configuration
15
+ =============
16
+ This gem uses the imap-backup gem's command line inetrface to configure the GMail
17
+ accounts that you want to back up. imap-backup is installed when you run bundle (above).
18
+
19
+ ```shell
20
+ $ imap-backup setup
21
+ ```
22
+
23
+ See the imap-backup README for fuller instructions.
24
+
25
+ Usage
26
+ =====
27
+
28
+ ```
29
+ gdata-backup EMAIL DIRECTORY
30
+ ```
31
+
32
+ Alternatives
33
+ ============
34
+
35
+ There are various other applications available which download Google Docs:
36
+
37
+ * You can download a zipped bundle from the Google Docs web interface,
38
+ * There are some Open Source,
39
+ * There are various commercial products.
40
+
41
+ Open Source:
42
+
43
+ * http://gdocs-backup.com/source
44
+ * http://gs.fhtino.it/gdocbackup - .net/mono
45
+ * http://1st-soft.net/gdd/ - greasemonkey
46
+
47
+ Commercial:
48
+
49
+ * http://www.backupgoo.com/en/index.html
50
+ * http://www.workflow.ae/Google-Docs-Backup-Utility/
51
+ * http://www.gladinet.com/
52
+ * http://www.syncdocs.com/
53
+
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/gem_tasks'
3
+
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ root = File.expand_path('../..', __FILE__)
4
+ $: << File.join(root, 'lib')
5
+
6
+ require 'gdata/backup'
7
+
8
+ def usage
9
+ puts <<EOT
10
+ Usage:
11
+ $ #{__FILE__} email@gmail.com destination_directory
12
+ EOT
13
+ end
14
+
15
+ if ARGV.size < 2
16
+ usage
17
+ exit
18
+ end
19
+
20
+ @user, @path = ARGV
21
+
22
+ Gdata::Backup.new(@user, @path).run
23
+
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ load File.expand_path('lib/gdata/backup/version.rb', File.dirname(__FILE__))
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ['Joe Yates']
6
+ gem.email = ['joe.g.yates@gmail.com']
7
+ gem.description = 'Google Drive backup'
8
+ gem.summary = <<-EOT
9
+ Backup Google Drive documents as Open Document Format files.
10
+ EOT
11
+ gem.homepage = 'https://github.com/joeyates/gdata-backup'
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^spec/})
16
+ gem.name = 'gdata-backup'
17
+ gem.require_paths = ['lib']
18
+ gem.version = Gdata::Backup::VERSION
19
+
20
+ gem.add_runtime_dependency 'gdata'
21
+ gem.add_runtime_dependency 'imap-backup'
22
+
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'pry'
25
+ gem.add_development_dependency 'pry-doc'
26
+ gem.add_development_dependency 'rspec'
27
+ end
28
+
@@ -0,0 +1,91 @@
1
+ require 'gdata/client'
2
+ require 'gdata/http'
3
+ require 'gdata/auth'
4
+ require 'logger'
5
+
6
+ require 'imap/backup'
7
+
8
+ module Gdata
9
+ class Backup
10
+ def initialize(account_username, path)
11
+ @path = path
12
+ store = Imap::Backup::Configuration::Store.new
13
+ @config = store.data
14
+ @account = @config[:accounts].find { |a| a[:username] == account_username }
15
+ raise 'account unknown' if @account.nil?
16
+ @log = Logger.new(STDOUT)
17
+ @log.level = Logger::INFO
18
+ end
19
+
20
+ def run
21
+ raise "The supplied path '#{@path}' does not exist" unless File.directory?(@path)
22
+ documents.each do |document|
23
+ @log.info document[:file_name]
24
+ begin
25
+ response = spreadsheet_client.get(document[:url])
26
+ rescue => e
27
+ @log.error "Download of #{document[:file_name]} failed: #{e}"
28
+ next
29
+ end
30
+ File.open(File.join(@path, document[:file_name]), 'wb' ) do |file|
31
+ file.write response.body
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def documents
39
+ return @documents if @documents
40
+
41
+ doc = doc_list_client.get('https://docs.google.com/feeds/documents/private/full')
42
+ list = doc.to_xml
43
+
44
+ @documents = []
45
+ list.elements.each( 'entry' ) do | entry |
46
+ src = entry.elements[ 'content' ].attributes[ 'src' ]
47
+ title = entry.elements[ 'title' ].text
48
+ format = download_format( src, title )
49
+ if format == ''
50
+ @log.info "Skipping '#{title}'"
51
+ next
52
+ end
53
+ url = src + '&exportFormat=' + format
54
+ clean_title = title.gsub(/[^a-z0-9\s\-\_]/i, '_')
55
+ file_name = clean_title + '.' + format
56
+ @documents << { :file_name => file_name,
57
+ :url => url }
58
+ end
59
+
60
+ @documents
61
+ end
62
+
63
+ def doc_list_client
64
+ return @doc_list_client if @doc_list_client
65
+ @doc_list_client = GData::Client::DocList.new
66
+ @doc_list_client.clientlogin(@account[:username], @account[:password])
67
+ @doc_list_client
68
+ end
69
+
70
+ def spreadsheet_client
71
+ return @spreadsheet_client if @spreadsheet_client
72
+ @spreadsheet_client = GData::Client::Spreadsheets.new
73
+ @spreadsheet_client.clientlogin(@account[:username], @account[:password])
74
+ @spreadsheet_client
75
+ end
76
+
77
+ def download_format( url, title )
78
+ case
79
+ when title =~ %r(\.pdf$)
80
+ ''
81
+ when url =~ %r(feeds/download/presentations)
82
+ ''
83
+ when url =~ /spreadsheets/
84
+ 'ods'
85
+ else
86
+ 'odt'
87
+ end
88
+ end
89
+ end
90
+ end
91
+
@@ -0,0 +1,9 @@
1
+ module Gdata
2
+ class Backup
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ REVISION = 1
6
+ VERSION = [MAJOR, MINOR, REVISION].map(&:to_s).join('.')
7
+ end
8
+ end
9
+
@@ -0,0 +1,91 @@
1
+ $: << '../lib'
2
+
3
+ require 'gdata/download'
4
+ require "rexml/document"
5
+
6
+ describe Gdata::Download do
7
+
8
+ def canned_doc_list_response
9
+ s = <<EOT
10
+ <feed xmlns='http://www.w3.org/2005/Atom'>
11
+ <entry>
12
+ <title>Doc1</title>
13
+ <content src='https://docs.google.com/feeds/download/documents/export/Export?id=XXXXXXXX' type='text/html'/>
14
+ </entry>
15
+ <entry>
16
+ <title>Doc2</title>
17
+ <content src='https://docs.google.com/feeds/download/documents/export/Export?id=YYYYYYYY' type='text/html'/>
18
+ </entry>
19
+ </feed>
20
+ EOT
21
+ @rexml = REXML::Document.new(s)
22
+ stub('GData_HTTP_Response', :to_xml => @rexml.root)
23
+ end
24
+
25
+ context '#initialize' do
26
+ before :each do
27
+ @config = stub('Imap::Backup::Configuration::Store')
28
+ Imap::Backup::Configuration::Store.stub!(:new).and_return(@config)
29
+ @data = {:accounts => [{:username => 'account_username'}]}
30
+ @config.stub!(:data).and_return(@data)
31
+ end
32
+
33
+ it 'should load config' do
34
+ Imap::Backup::Configuration::Store.should_receive(:new).and_return(@config)
35
+ @config.should_receive(:data).and_return(@data)
36
+
37
+ Gdata::Download.new('account_username', '/a/path')
38
+ end
39
+
40
+ it 'should fail if the account is not configured' do
41
+ expect do
42
+ Gdata::Download.new('unknown_username', '/a/path')
43
+ end.to raise_error(/unknown/)
44
+ end
45
+
46
+ end
47
+
48
+ context '#documents' do
49
+
50
+ before :each do
51
+ @data = {:accounts => [{:username => 'jdoe@example.com', :password => 'secret'}]}
52
+ @config = stub('Imap::Backup::Configuration::Store', :data => @data)
53
+ Imap::Backup::Configuration::Store.stub!(:new).and_return(@config)
54
+ @doc_list_client = stub('GData::Client::DocList')
55
+ @doc_list_client.stub!(:clientlogin => true)
56
+ GData::Client::DocList.stub!(:new => @doc_list_client)
57
+ @doc_list_client.stub!(:get).
58
+ with('https://docs.google.com/feeds/documents/private/full').
59
+ and_return(canned_doc_list_response)
60
+ end
61
+
62
+ subject { Gdata::Download.new('jdoe@example.com', '/a/path') }
63
+
64
+ it 'should log in' do
65
+ @doc_list_client. should_receive(:clientlogin).
66
+ with('jdoe@example.com', 'secret').
67
+ and_return(true)
68
+
69
+ subject.documents
70
+ end
71
+
72
+ it 'should list documents' do
73
+ @doc_list_client. should_receive(:get).
74
+ and_return(canned_doc_list_response)
75
+
76
+ subject.documents
77
+ end
78
+
79
+ it 'should return document information' do
80
+ documents = subject.documents
81
+
82
+ documents. should == [{:file_name => 'Doc1.odt',
83
+ :url => 'https://docs.google.com/feeds/download/documents/export/Export?id=XXXXXXXX&exportFormat=odt'},
84
+ {:file_name => 'Doc2.odt',
85
+ :url => 'https://docs.google.com/feeds/download/documents/export/Export?id=YYYYYYYY&exportFormat=odt'}]
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gdata-backup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joe Yates
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gdata
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: imap-backup
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: pry
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: pry-doc
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Google Drive backup
111
+ email:
112
+ - joe.g.yates@gmail.com
113
+ executables:
114
+ - gdata-backup
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - Gemfile
120
+ - README.md
121
+ - Rakefile
122
+ - bin/gdata-backup
123
+ - gdata-backup.gemspec
124
+ - lib/gdata/backup.rb
125
+ - lib/gdata/backup/version.rb
126
+ - spec/download_spec.rb
127
+ homepage: https://github.com/joeyates/gdata-backup
128
+ licenses: []
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ segments:
140
+ - 0
141
+ hash: -2792609340228659123
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ! '>='
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ segments:
149
+ - 0
150
+ hash: -2792609340228659123
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 1.8.23
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: Backup Google Drive documents as Open Document Format files.
157
+ test_files:
158
+ - spec/download_spec.rb
159
+ has_rdoc: