From a32c25e1c8870bf751ed5b3fb7efe94a2d0302d6 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 10 Nov 2022 09:48:22 +0100 Subject: [PATCH] Extract logic into separate files Signed-off-by: Louis Chemineau --- apps/files_versions/src/utils/davClient.js | 34 +++++ apps/files_versions/src/utils/davRequest.js | 33 +++++ apps/files_versions/src/utils/logger.js | 27 ++++ apps/files_versions/src/utils/versions.js | 124 ++++++++++++++++ apps/files_versions/src/views/VersionTab.vue | 141 +++++-------------- 5 files changed, 253 insertions(+), 106 deletions(-) create mode 100644 apps/files_versions/src/utils/davClient.js create mode 100644 apps/files_versions/src/utils/davRequest.js create mode 100644 apps/files_versions/src/utils/logger.js create mode 100644 apps/files_versions/src/utils/versions.js diff --git a/apps/files_versions/src/utils/davClient.js b/apps/files_versions/src/utils/davClient.js new file mode 100644 index 00000000000..e4bfeb10411 --- /dev/null +++ b/apps/files_versions/src/utils/davClient.js @@ -0,0 +1,34 @@ +/** + * @copyright 2022 Louis Chemineau + * + * @author Louis Chemineau + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { createClient, getPatcher } from 'webdav' +import { generateRemoteUrl } from '@nextcloud/router' +import axios from '@nextcloud/axios' + +const rootPath = 'dav' + +// force our axios +const patcher = getPatcher() +patcher.patch('request', axios) + +// init webdav client on default dav endpoint +const remote = generateRemoteUrl(rootPath) +export default createClient(remote) diff --git a/apps/files_versions/src/utils/davRequest.js b/apps/files_versions/src/utils/davRequest.js new file mode 100644 index 00000000000..b77cd150643 --- /dev/null +++ b/apps/files_versions/src/utils/davRequest.js @@ -0,0 +1,33 @@ +/** + * @copyright Copyright (c) 2019 Louis Chmn + * + * @author Louis Chmn + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +export default ` + + + + + + +` diff --git a/apps/files_versions/src/utils/logger.js b/apps/files_versions/src/utils/logger.js new file mode 100644 index 00000000000..4f0356764d9 --- /dev/null +++ b/apps/files_versions/src/utils/logger.js @@ -0,0 +1,27 @@ +/** + * @copyright 2022 Louis Chemineau + * + * @author Louis Chemineau + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { getLoggerBuilder } from '@nextcloud/logger' + +export default getLoggerBuilder() + .setApp('files_version') + .detectUser() + .build() diff --git a/apps/files_versions/src/utils/versions.js b/apps/files_versions/src/utils/versions.js new file mode 100644 index 00000000000..477e7ef65fe --- /dev/null +++ b/apps/files_versions/src/utils/versions.js @@ -0,0 +1,124 @@ +/** + * @copyright 2022 Louis Chemineau + * + * @author Louis Chemineau + * + * @license AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { getCurrentUser } from '@nextcloud/auth' +import client from '../utils/davClient.js' +import davRequest from '../utils/davRequest.js' +import logger from '../utils/logger.js' +import { basename, joinPaths } from '@nextcloud/paths' +import { generateUrl } from '@nextcloud/router' +import { translate } from '@nextcloud/l10n' +import moment from '@nextcloud/moment' + +/** + * @typedef {Object} Version + * @property {string} title - 'Current version' or '' + * @property {string} fileName - File name relative to the version DAV endpoint + * @property {string} mimeType - Empty for the current version, else the actual mime type of the version + * @property {string} size - Human readable size + * @property {string} type - 'file' + * @property {number} mtime - Version creation date as a timestamp + * @property {string} preview - Preview URL of the version + * @property {string} url - Download URL of the version + * @property {string|null} fileVersion - The version id, null for the current version + * @property {boolean} isCurrent - Whether this is the current version of the file + */ + +/** + * @param fileInfo + * @return {Promise} + */ +export async function fetchVersions(fileInfo) { + const path = `/versions/${getCurrentUser()?.uid}/versions/${fileInfo.id}` + + try { + /** @type {import('webdav').FileStat[]} */ + const response = await client.getDirectoryContents(path, { + data: davRequest, + }) + return response.map(version => formatVersion(version, fileInfo)) + } catch (exception) { + logger.error('Could not fetch version', { exception }) + throw exception + } +} + +/** + * Restore the given version + * + * @param {Version} version + * @param {object} fileInfo + */ +export async function restoreVersion(version, fileInfo) { + try { + logger.debug('Restoring version', { url: version.url }) + await client.moveFile( + `/versions/${getCurrentUser()?.uid}/versions/${fileInfo.id}/${version.fileVersion}`, + `/versions/${getCurrentUser()?.uid}/restore/target` + ) + } catch (exception) { + logger.error('Could not restore version', { exception }) + throw exception + } +} + +/** + * Format version + * + * @param {object} version - raw version received from the versions DAV endpoint + * @param {object} fileInfo - file properties received from the files DAV endpoint + * @return {Version} + */ +function formatVersion(version, fileInfo) { + const isCurrent = version.mime === '' + const fileVersion = isCurrent ? null : basename(version.filename) + + let url = null + let preview = null + + if (isCurrent) { + // https://nextcloud_server2.test/remote.php/webdav/welcome.txt?downloadStartSecret=hl5awd7tbzg + url = joinPaths('/remote.php/webdav', fileInfo.path, fileInfo.name) + preview = generateUrl('/core/preview?fileId={fileId}&c={fileEtag}&x=250&y=250&forceIcon=0&a=0', { + fileId: fileInfo.id, + fileEtag: fileInfo.etag, + }) + } else { + url = joinPaths('/remote.php/dav', version.filename) + preview = generateUrl('/apps/files_versions/preview?file={file}&version={fileVersion}', { + file: joinPaths(fileInfo.path, fileInfo.name), + fileVersion, + }) + } + + return { + title: isCurrent ? translate('files_versions', 'Current version') : '', + fileName: version.filename, + mimeType: version.mime, + size: isCurrent ? fileInfo.size : version.size, + type: version.type, + mtime: moment(isCurrent ? fileInfo.mtime : version.lastmod).unix(), + preview, + url, + fileVersion, + isCurrent, + } +} diff --git a/apps/files_versions/src/views/VersionTab.vue b/apps/files_versions/src/views/VersionTab.vue index 90664491941..8159415dfc7 100644 --- a/apps/files_versions/src/views/VersionTab.vue +++ b/apps/files_versions/src/views/VersionTab.vue @@ -19,7 +19,7 @@
    @@ -29,25 +29,25 @@ alt="" height="256" width="256" - class="version-image"> + class="version__image"> -