Stackedit/src/services/providers/googleDriveProvider.js
2018-09-19 09:59:22 +01:00

217 lines
7.0 KiB
JavaScript

import store from '../../store';
import googleHelper from './helpers/googleHelper';
import Provider from './common/Provider';
import utils from '../utils';
import workspaceSvc from '../workspaceSvc';
export default new Provider({
id: 'googleDrive',
name: 'Google Drive',
getToken({ sub }) {
const token = store.getters['data/googleTokensBySub'][sub];
return token && token.isDrive ? token : null;
},
getLocationUrl({ driveFileId }) {
return `https://docs.google.com/file/d/${driveFileId}/edit`;
},
getLocationDescription({ driveFileId }) {
return driveFileId;
},
async initAction() {
const state = googleHelper.driveState || {};
if (state.userId) {
// Try to find the token corresponding to the user ID
let token = store.getters['data/googleTokensBySub'][state.userId];
// If not found or not enough permission, popup an OAuth2 window
if (!token || !token.isDrive) {
await store.dispatch('modal/open', { type: 'googleDriveAccount' });
token = await googleHelper.addDriveAccount(
!store.getters['data/localSettings'].googleDriveRestrictedAccess,
state.userId,
);
}
const openWorkspaceIfExists = (file) => {
const folderId = file
&& file.appProperties
&& file.appProperties.folderId;
if (folderId) {
// See if we have the corresponding workspace
const workspaceParams = {
providerId: 'googleDriveWorkspace',
folderId,
};
const workspaceId = utils.makeWorkspaceId(workspaceParams);
const workspace = store.getters['workspace/workspacesById'][workspaceId];
// If we have the workspace, open it by changing the current URL
if (workspace) {
utils.setQueryParams(workspaceParams);
}
}
};
switch (state.action) {
case 'create':
default:
// See if folder is part of a workspace we can open
try {
const folder = await googleHelper.getFile(token, state.folderId);
folder.appProperties = folder.appProperties || {};
googleHelper.driveActionFolder = folder;
openWorkspaceIfExists(folder);
} catch (err) {
if (!err || err.status !== 404) {
throw err;
}
// We received an HTTP 404 meaning we have no permission to read the folder
googleHelper.driveActionFolder = { id: state.folderId };
}
break;
case 'open': {
await utils.awaitSequence(state.ids || [], async (id) => {
const file = await googleHelper.getFile(token, id);
file.appProperties = file.appProperties || {};
googleHelper.driveActionFiles.push(file);
});
// Check if first file is part of a workspace
openWorkspaceIfExists(googleHelper.driveActionFiles[0]);
}
}
}
},
async performAction() {
const state = googleHelper.driveState || {};
const token = store.getters['data/googleTokensBySub'][state.userId];
switch (token && state.action) {
case 'create': {
const file = await workspaceSvc.createFile({}, true);
store.commit('file/setCurrentId', file.id);
// Return a new syncLocation
return this.makeLocation(token, null, googleHelper.driveActionFolder.id);
}
case 'open':
store.dispatch(
'queue/enqueue',
() => this.openFiles(token, googleHelper.driveActionFiles),
);
return null;
default:
return null;
}
},
async downloadContent(token, syncLocation) {
const content = await googleHelper.downloadFile(token, syncLocation.driveFileId);
return Provider.parseContent(content, `${syncLocation.fileId}/content`);
},
async uploadContent(token, content, syncLocation, ifNotTooLate) {
const file = store.state.file.itemsById[syncLocation.fileId];
const name = utils.sanitizeName(file && file.name);
const parents = [];
if (syncLocation.driveParentId) {
parents.push(syncLocation.driveParentId);
}
const driveFile = await googleHelper.uploadFile({
token,
name,
parents,
media: Provider.serializeContent(content),
fileId: syncLocation.driveFileId,
ifNotTooLate,
});
return {
...syncLocation,
driveFileId: driveFile.id,
};
},
async publish(token, html, metadata, publishLocation) {
const driveFile = await googleHelper.uploadFile({
token,
name: metadata.title,
parents: [],
media: html,
mediaType: publishLocation.templateId ? 'text/html' : undefined,
fileId: publishLocation.driveFileId,
});
return {
...publishLocation,
driveFileId: driveFile.id,
};
},
async openFiles(token, driveFiles) {
return utils.awaitSequence(driveFiles, async (driveFile) => {
// Check if the file exists and open it
if (!Provider.openFileWithLocation({
providerId: this.id,
driveFileId: driveFile.id,
})) {
// Download content from Google Drive
const syncLocation = {
driveFileId: driveFile.id,
providerId: this.id,
sub: token.sub,
};
let content;
try {
content = await this.downloadContent(token, syncLocation);
} catch (e) {
store.dispatch('notification/error', `Could not open file ${driveFile.id}.`);
return;
}
// Create the file
const item = await workspaceSvc.createFile({
name: driveFile.name,
parentId: store.getters['file/current'].parentId,
text: content.text,
properties: content.properties,
discussions: content.discussions,
comments: content.comments,
}, true);
store.commit('file/setCurrentId', item.id);
workspaceSvc.addSyncLocation({
...syncLocation,
fileId: item.id,
});
store.dispatch('notification/info', `${store.getters['file/current'].name} was imported from Google Drive.`);
}
});
},
makeLocation(token, fileId, folderId) {
const location = {
providerId: this.id,
sub: token.sub,
};
if (fileId) {
location.driveFileId = fileId;
}
if (folderId) {
location.driveParentId = folderId;
}
return location;
},
async listFileRevisions({ token, syncLocation }) {
const revisions = await googleHelper.getFileRevisions(token, syncLocation.driveFileId);
return revisions.map(revision => ({
id: revision.id,
sub: `${googleHelper.subPrefix}:${revision.lastModifyingUser.permissionId}`,
created: new Date(revision.modifiedTime).getTime(),
}));
},
async loadFileRevision() {
// Revision are already loaded
return false;
},
async getFileRevisionContent({
token,
contentId,
syncLocation,
revisionId,
}) {
const content = await googleHelper
.downloadFileRevision(token, syncLocation.driveFileId, revisionId);
return Provider.parseContent(content, contentId);
},
});