aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_versions/src/utils
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2022-11-10 09:48:22 +0100
committerLouis Chemineau <louis@chmn.me>2022-11-28 17:31:27 +0100
commita32c25e1c8870bf751ed5b3fb7efe94a2d0302d6 (patch)
tree9fe68fae86d9daf5c6f20719cc0773b6c4be77e3 /apps/files_versions/src/utils
parenta28838b8667645fda47df8a0d3911614fd601c35 (diff)
downloadnextcloud-server-a32c25e1c8870bf751ed5b3fb7efe94a2d0302d6.tar.gz
nextcloud-server-a32c25e1c8870bf751ed5b3fb7efe94a2d0302d6.zip
Extract logic into separate files
Signed-off-by: Louis Chemineau <louis@chmn.me>
Diffstat (limited to 'apps/files_versions/src/utils')
-rw-r--r--apps/files_versions/src/utils/davClient.js34
-rw-r--r--apps/files_versions/src/utils/davRequest.js33
-rw-r--r--apps/files_versions/src/utils/logger.js27
-rw-r--r--apps/files_versions/src/utils/versions.js124
4 files changed, 218 insertions, 0 deletions
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 <mlouis@chmn.me>
+ *
+ * @author Louis Chemineau <mlouis@chmn.me>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <louis@chmn.me>
+ *
+ * @author Louis Chmn <louis@chmn.me>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+export default `<?xml version="1.0"?>
+<d:propfind xmlns:d="DAV:"
+ xmlns:oc="http://owncloud.org/ns"
+ xmlns:nc="http://nextcloud.org/ns"
+ xmlns:ocs="http://open-collaboration-services.org/ns">
+ <d:prop>
+ <d:getcontentlength />
+ <d:getcontenttype />
+ <d:getlastmodified />
+ </d:prop>
+</d:propfind>`
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 <mlouis@chmn.me>
+ *
+ * @author Louis Chemineau <mlouis@chmn.me>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+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 <mlouis@chmn.me>
+ *
+ * @author Louis Chemineau <mlouis@chmn.me>
+ *
+ * @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 <http://www.gnu.org/licenses/>.
+ */
+
+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<Version[]>}
+ */
+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,
+ }
+}