Skip to content

Commit

Permalink
feat(gDriveSync): basic saving
Browse files Browse the repository at this point in the history
  • Loading branch information
johannesjo committed Mar 9, 2018
1 parent bc3102e commit 528020c
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app-src/scripts/_app.js
Expand Up @@ -50,7 +50,7 @@
.run(setStartedTime)
.run(checkIfLatestVersion)
.run(showWelcomeDialog)
.run(goToWorkViewIfTasks);
//.run(goToWorkViewIfTasks);

/* @ngInject */
function configMarked(markedProvider) {
Expand Down
121 changes: 120 additions & 1 deletion app-src/scripts/main/global-services/google-api-s.js
Expand Up @@ -7,20 +7,75 @@
*/
(() => {
'use strict';
'use strict';

/**
* Helper for building multipart requests for uploading to Drive.
*/
var MultiPartBuilder = function() {
this.boundary = Math.random().toString(36).slice(2);
this.mimeType = 'multipart/mixed; boundary="' + this.boundary + '"';
this.parts = [];
this.body = null;
};

/**
* Appends a part.
*
* @param {String} mimeType Content type of this part
* @param {Blob|File|String} content Body of this part
*/
MultiPartBuilder.prototype.append = function(mimeType, content) {
if (this.body !== null) {
throw new Error("Builder has already been finalized.");
}
this.parts.push(
"\r\n--", this.boundary, "\r\n",
"Content-Type: ", mimeType, "\r\n\r\n",
content);
return this;
};

/**
* Finalizes building of the multipart request and returns a Blob containing
* the request. Once finalized, appending additional parts will result in an
* error.
*
* @returns {Object} Object containing the mime type (mimeType) & assembled multipart body (body)
*/
MultiPartBuilder.prototype.finish = function() {
if (this.parts.length === 0) {
throw new Error("No parts have been added.");
}
if (this.body === null) {
this.parts.push("\r\n--", this.boundary, "--");
this.body = this.parts.join('');
// TODO - switch to blob once gapi.client.request allows it
// this.body = new Blob(this.parts, {type: this.mimeType});
}
return {
type: this.mimeType,
body: this.body
};
};

const DISCOVERY_DOCS = ['https://sheets.googleapis.com/$discovery/rest?version=v4'];
const SCOPES = '' +
'https://www.googleapis.com/auth/spreadsheets.readonly' +
' https://www.googleapis.com/auth/drive.install' +
' https://www.googleapis.com/auth/drive';

const DEFAULT_FIELDS_FOR_DRIVE = 'id,title,mimeType,userPermission,editable,copyable,shared,fileSize';

class GoogleApi {
/* @ngInject */
constructor(GOOGLE, $q, IS_ELECTRON, $http, $rootScope) {
constructor(GOOGLE, $q, IS_ELECTRON, $http, $rootScope, $cacheFactory) {
this.$q = $q;
this.$http = $http;
this.$rootScope = $rootScope;
this.GOOGLE = GOOGLE;
this.IS_ELECTRON = IS_ELECTRON;
this.cache = $cacheFactory('files');
}

initClientLibraryIfNotDone() {
Expand Down Expand Up @@ -207,6 +262,70 @@

return defer.promise;
}

loadFile(fileId) {
const file = this.cache.get(fileId);
if (file) {
return this.$q.when(file);
}
const metadataRequest = window.gapi.client.drive.files.get({
fileId: fileId,
supportsTeamDrives: true,
fields: DEFAULT_FIELDS_FOR_DRIVE
});
const contentRequest = window.gapi.client.drive.files.get({
fileId: fileId,
supportsTeamDrives: true,
alt: 'media'
});
return this.$q.all([this.$q.when(metadataRequest), this.$q.when(contentRequest)])
.then(function(responses) {
console.log(responses);
//return combineAndStoreResults(responses[0].result, responses[1].body);
});
};

saveFile(metadata, content) {
//window.gapi.client.setApiKey(this.GOOGLE.API_KEY);

if (!angular.isString(content)) {
content = JSON.stringify(content);
}

let path;
let method;

if (metadata.id) {
path = '/upload/drive/v2/files/' + encodeURIComponent(metadata.id);
method = 'PUT';
} else {
path = '/upload/drive/v2/files/';
method = 'POST';
}

const multipart = new MultiPartBuilder()
.append('application/json', JSON.stringify(metadata))
//.append(metadata.mimeType, content)
.append('application/json', content)
.finish();

return this.$http({
method: method,
url: `https://content.googleapis.com/upload/drive/v2/files/`,
//url: `https://content.googleapis.com/${path}`,
params: {
'key': this.GOOGLE.API_KEY,
uploadType: 'multipart',
supportsTeamDrives: true,
fields: DEFAULT_FIELDS_FOR_DRIVE
},
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': multipart.type
},
data: multipart.body
});
}
}

angular
Expand Down
33 changes: 32 additions & 1 deletion app-src/scripts/settings/backup-settings/backup-settings-d.html
Expand Up @@ -33,6 +33,36 @@ <h2 class="md-title">
Import Settings
</md-button>

<section>
<h3 class="md-caption">Sync via Google Drive</h3>
<div>
<md-button class="md-raised md-primary"
ng-show="!vm.isLoggedIn"
ng-click="vm.login()">Login
</md-button>
<md-button class="md-raised md-primary"
ng-show="vm.isLoggedIn"
ng-click="vm.logout()">Logout
</md-button>
<md-button class="md-raised md-primary"
ng-show="vm.isLoggedIn"
external-link
target="_blank"
href="https://myaccount.google.com/permissions">Revoke permissions
</md-button>
<md-button class="md-raised md-primary"
ng-show="vm.isLoggedIn"
ng-click="vm.test()">TEST
</md-button>
</div>
<div>
<md-switch ng-model="vm.settings.isAutoStartNextTask"
aria-label="Auto sync tasks">
Auto sync tasks
</md-switch>
</div>
</section>


<form ng-if="vm.showUploadForm"
ng-submit="vm.importSettings(vm.uploadSettingsTextarea)">
Expand Down Expand Up @@ -86,7 +116,8 @@ <h3 class="md-caption">Automatic Sync</h3>
</md-switch>
</div>

<p><strong>NOTE:</strong> This is <strong>a highly experimental feature!!!</strong> Take care! Make a backup! Changes to the sync settings require you to restart the application to take effect.
<p><strong>NOTE:</strong> This is
<strong>a highly experimental feature!!!</strong> Take care! Make a backup! Changes to the sync settings require you to restart the application to take effect.
</p>

<div ng-show="vm.settings.isSyncEnabled">
Expand Down
31 changes: 30 additions & 1 deletion app-src/scripts/settings/backup-settings/backup-settings-d.js
Expand Up @@ -27,7 +27,7 @@
}

/* @ngInject */
function BackupSettingsCtrl(AppStorage, IS_ELECTRON) {
function BackupSettingsCtrl(AppStorage, IS_ELECTRON, GoogleApi) {
let vm = this;
vm.IS_ELECTRON = IS_ELECTRON;

Expand All @@ -36,6 +36,35 @@
let settings = JSON.parse(uploadSettingsTextarea);
AppStorage.importData(settings);
};

vm.test = () => {
GoogleApi.saveFile({
title: 'SUPER_PRODUCTIVITY_SYNC.json',
id: null,
editable: true
}, {
test: 'DDDDDDDDDDDDDDDDDDDDDDDDD'
})
.then((res) => console.log(res));
};

vm.login = () => {
vm.isLoading = true;
return GoogleApi.login()
.then(() => {
vm.isLoggedIn = true;
vm.isLoading = false;
});
};

vm.logout = () => {
vm.isLoading = true;
GoogleApi.logout()
.then(() => {
vm.isLoggedIn = false;
vm.isLoading = false;
});
};
}

})();

0 comments on commit 528020c

Please sign in to comment.