gdata-backup 0.0.1

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