← Back to team overview

duplicity-team team mailing list archive

[Merge] lp:~bmerry/duplicity/pydrive-regular into lp:duplicity

 

Bruce Merry has proposed merging lp:~bmerry/duplicity/pydrive-regular into lp:duplicity.

Requested reviews:
  duplicity-team (duplicity-team)

For more details, see:
https://code.launchpad.net/~bmerry/duplicity/pydrive-regular/+merge/260645

This implements the proposal made by somebody else (http://lists.gnu.org/archive/html/duplicity-talk/2015-02/msg00037.html) to allow the pydrive backend to work with a normal drive account instead of a service account. It seems to be working for me: I was able to migrate seamlessly from the gdocs backend. It's set up so that a service account can still be used, depending on which environment variable is set. The man page is updated to describe how to use the new functionality.
-- 
Your team duplicity-team is requested to review the proposed merge of lp:~bmerry/duplicity/pydrive-regular into lp:duplicity.
=== modified file 'bin/duplicity.1'
--- bin/duplicity.1	2015-05-08 12:28:47 +0000
+++ bin/duplicity.1	2015-05-30 12:03:43 +0000
@@ -1755,13 +1755,17 @@
 .B REQUIREMENTS
 above.
 
-You need to create a service account in "Google developers console" at https://console.developers.google.com
-
-Make sure Drive API is enabled.
-
-The email address of the account will be used as part of URL. See
-.B URL FORMAT
-above.
+There are two ways to use PyDrive: with a regular account or with a
+"service account". With a service account, a separate account is
+created, that is only accessible with Google APIs and not a web login.
+With a regular account, you can store backups in your normal Google
+Drive.
+
+To use a service account, go to the Google developers
+console at https://console.developers.google.com. Create a project,
+and make sure Drive API is enabled for the project. Under "APIs and
+auth", click Create New Client ID, then select Service Account with P12
+key.
 
 Download the .p12 key file of the account and convert it to the .pem format:
 .br
@@ -1771,6 +1775,37 @@
 .BR GOOGLE_DRIVE_ACCOUNT_KEY
 environment variable for authentification.
 
+The email address of the account will be used as part of URL. See
+.B URL FORMAT
+above.
+
+The alternative is to use a regular account. To do this, start as above,
+but when creating a new Client ID, select "Installed application" of
+type "Other". Create a file with the following content, and pass its
+filename in the
+.BR GOOGLE_DRIVE_SETTINGS
+environment variable:
+.PP
+.nf
+.RS
+client_config_backend: settings
+client_config:
+    client_id: <Client ID from developers' console>
+    client_secret: <Client secret from developers' console>
+save_credentials: True
+save_credentials_backend: file
+save_credentials_file: <filename to cache credentials>
+get_refresh_token: True
+.RE
+.fi
+
+In this scenario, the username and host parts of the URL play no role;
+only the path matters. During the first run, you will be prompted to
+visit an URL in your browser to grant access to your drive. Once
+granted, you will receive a verification code to paste back into
+Duplicity. The credentials are then cached in the file references above
+for future use.
+
 .SH A NOTE ON MULTI BACKEND
 
 The multi backend allows duplicity to combine the storage available in

=== modified file 'duplicity/backends/pydrivebackend.py'
--- duplicity/backends/pydrivebackend.py	2015-01-31 23:30:49 +0000
+++ duplicity/backends/pydrivebackend.py	2015-05-30 12:03:43 +0000
@@ -39,14 +39,17 @@
             raise BackendException('PyDrive backend requires PyDrive installation'
                                    'Please read the manpage to fix.')
 
-        if 'GOOGLE_DRIVE_ACCOUNT_KEY' not in os.environ:
-            raise BackendException('GOOGLE_DRIVE_ACCOUNT_KEY environment variable not set. Please read the manpage to fix.')
-        account_key = os.environ['GOOGLE_DRIVE_ACCOUNT_KEY']
-
-        credentials = SignedJwtAssertionCredentials(parsed_url.username + '@' + parsed_url.hostname, account_key, scope='https://www.googleapis.com/auth/drive')
-        credentials.authorize(httplib2.Http())
-        gauth = GoogleAuth()
-        gauth.credentials = credentials
+        if 'GOOGLE_DRIVE_ACCOUNT_KEY' in os.environ:
+            account_key = os.environ['GOOGLE_DRIVE_ACCOUNT_KEY']
+            credentials = SignedJwtAssertionCredentials(parsed_url.username + '@' + parsed_url.hostname, account_key, scope='https://www.googleapis.com/auth/drive')
+            credentials.authorize(httplib2.Http())
+            gauth = GoogleAuth()
+            gauth.credentials = credentials
+        elif 'GOOGLE_DRIVE_SETTINGS' in os.environ:
+            gauth = GoogleAuth(settings_file=os.environ['GOOGLE_DRIVE_SETTINGS'])
+            gauth.CommandLineAuth()
+        else:
+            raise BackendException('GOOGLE_DRIVE_ACCOUNT_KEY or GOOGLE_DRIVE_SETTINGS environment variable not set. Please read the manpage to fix.')
         self.drive = GoogleDrive(gauth)
 
         # Dirty way to find root folder id


Follow ups