summaryrefslogtreecommitdiffstats
path: root/apps/files_versions/src/utils/versions.js
blob: 8fe258119f7a6858af9929b9349bfeb9e90000cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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,
	}
}