Skip to content

Commit 3f18ec3

Browse files
committed
enh: Migrate to use webdav v5 and @nextcloud/files for DAV handling
Signed-off-by: Ferdinand Thiessen <[email protected]>
1 parent dc24021 commit 3f18ec3

19 files changed

+142
-260
lines changed

src/components/FilesListViewer.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ import { NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'
8484
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
8585
8686
import TiledLayout from '../components/TiledLayout/TiledLayout.vue'
87-
import { fetchFile } from '../services/fileFetcher.js'
87+
import { fetchFile } from '../services/fileFetcher.ts'
8888
import VirtualScrolling from '../components/VirtualScrolling.vue'
8989
import EmptyBox from '../assets/Illustrations/empty.svg'
9090
import UserConfig from '../mixins/UserConfig.js'

src/mixins/FetchFacesMixin.js

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@
2020
*
2121
*/
2222

23-
import { mapActions, mapGetters } from 'vuex'
24-
2523
import { showError } from '@nextcloud/dialogs'
2624
import { getCurrentUser } from '@nextcloud/auth'
25+
import { mapActions, mapGetters } from 'vuex'
26+
import he from 'he'
2727

28-
import client from '../services/DavClient.js'
29-
import logger from '../services/logger.js'
30-
import DavRequest from '../services/DavRequest.js'
3128
import { genFileInfo } from '../utils/fileUtils.js'
29+
import logger from '../services/logger.js'
3230
import AbortControllerMixin from './AbortControllerMixin.js'
33-
import he from 'he'
31+
import { davClient } from '../services/DavClient.ts'
32+
import { getPropFind } from '../services/DavRequest.ts'
3433

3534
export default {
3635
name: 'FetchFacesMixin',
@@ -76,8 +75,8 @@ export default {
7675
this.loadingFaces = true
7776
this.errorFetchingFaces = null
7877

79-
const { data: faces } = await client.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {
80-
data: DavRequest,
78+
const { data: faces } = await davClient.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {
79+
data: getPropFind(),
8180
details: true,
8281
signal: this.abortController.signal,
8382
})
@@ -111,10 +110,10 @@ export default {
111110
this.errorFetchingFiles = null
112111
this.loadingFiles = true
113112

114-
let { data: fetchedFiles } = await client.getDirectoryContents(
113+
let { data: fetchedFiles } = await davClient.getDirectoryContents(
115114
`/recognize/${getCurrentUser()?.uid}/faces/${faceName}`,
116115
{
117-
data: DavRequest,
116+
data: getPropFind(),
118117
details: true,
119118
signal: this.abortController.signal,
120119
}
@@ -163,10 +162,10 @@ export default {
163162
this.errorFetchingFiles = null
164163
this.loadingFiles = true
165164

166-
let { data: fetchedFiles } = await client.getDirectoryContents(
165+
let { data: fetchedFiles } = await davClient.getDirectoryContents(
167166
`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,
168167
{
169-
data: DavRequest,
168+
data: getPropFind(),
170169
details: true,
171170
signal: this.abortController.signal,
172171
}
@@ -204,10 +203,10 @@ export default {
204203

205204
async fetchUnassignedFacesCount() {
206205
try {
207-
const { data: unassignedFacesRoot } = await client.stat(
206+
const { data: unassignedFacesRoot } = await davClient.stat(
208207
`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,
209208
{
210-
data: DavRequest,
209+
data: getPropFind(),
211210
details: true,
212211
signal: this.abortController.signal,
213212
}

src/mixins/FetchFilesMixin.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*
2121
*/
2222

23+
import { showError } from '@nextcloud/dialogs'
2324
import logger from '../services/logger.js'
2425
import getPhotos from '../services/PhotoSearch.js'
2526
import SemaphoreWithPriority from '../utils/semaphoreWithPriority.js'
@@ -107,8 +108,8 @@ export default {
107108
}
108109

109110
// cancelled request, moving on...
110-
logger.error('Error fetching files', { error })
111-
console.error(error)
111+
showError(t('photos', 'Error fetching files'))
112+
logger.error(error)
112113
} finally {
113114
this.loadingFiles = false
114115
this.fetchSemaphore.release(fetchSemaphoreSymbol)

src/services/DavClient.js

Lines changed: 0 additions & 41 deletions
This file was deleted.
Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
2-
* @copyright Copyright (c) 2019 John Molakvoæ <[email protected]>
2+
* @copyright Copyright (c) 2024 Ferdinand Thiessen <[email protected]>
33
*
4-
* @author John Molakvoæ <[email protected]>
4+
* @author Ferdinand Thiessen <[email protected]>
55
*
66
* @license AGPL-3.0-or-later
77
*
@@ -20,25 +20,7 @@
2020
*
2121
*/
2222

23-
import client, { prefixPath } from './DavClient.js'
24-
import request from './DavRequest.js'
25-
import { genFileInfo } from '../utils/fileUtils.js'
23+
import type { WebDAVClient } from 'webdav'
24+
import { davGetClient } from '@nextcloud/files'
2625

27-
/**
28-
* Get a file info
29-
*
30-
* @param {string} path the path relative to the user root
31-
* @return {FileInfo} the file info
32-
*/
33-
export default async function(path) {
34-
// getDirectoryContents doesn't accept / for root
35-
const fixedPath = path === '/' ? '' : path
36-
37-
// fetch listing
38-
const response = await client.stat(prefixPath + fixedPath, {
39-
data: request,
40-
details: true,
41-
})
42-
43-
return genFileInfo(response.data)
44-
}
26+
export const davClient: WebDAVClient = davGetClient()

src/services/DavRequest.js renamed to src/services/DavRequest.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* @copyright Copyright (c) 2019 John Molakvoæ <[email protected]>
33
*
44
* @author John Molakvoæ <[email protected]>
5+
* @author Ferdinand Thiessen <[email protected]>
56
*
67
* @license AGPL-3.0-or-later
78
*
@@ -19,7 +20,7 @@
1920
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2021
*
2122
*/
22-
const props = `
23+
export const davProps = `
2324
<d:getcontentlength />
2425
<d:getcontenttype />
2526
<d:getetag />
@@ -39,13 +40,17 @@ const props = `
3940
<nc:nbItems />
4041
`
4142

42-
export { props }
43-
export default `<?xml version="1.0"?>
43+
/**
44+
* @param extraProps - Extra properties to add to the DAV request.
45+
*/
46+
export function getPropFind(extraProps: string[] = []): string {
47+
return `<?xml version="1.0"?>
4448
<d:propfind xmlns:d="DAV:"
4549
xmlns:oc="http://owncloud.org/ns"
4650
xmlns:nc="http://nextcloud.org/ns"
4751
xmlns:ocs="http://open-collaboration-services.org/ns">
4852
<d:prop>
49-
${props}
53+
${[...davProps, ...extraProps].join('')}
5054
</d:prop>
5155
</d:propfind>`
56+
}

src/services/FolderInfo.js

Lines changed: 0 additions & 44 deletions
This file was deleted.

src/services/PhotoSearch.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
*
2121
*/
2222

23-
import { genFileInfo } from '../utils/fileUtils.js'
24-
import { getCurrentUser } from '@nextcloud/auth'
25-
import { allMimes } from './AllowedMimes.js'
26-
import client from './DavClient.js'
27-
import { props } from './DavRequest.js'
2823
import moment from '@nextcloud/moment'
2924

25+
import { allMimes } from './AllowedMimes.js'
26+
import { genFileInfo } from '../utils/fileUtils.js'
27+
import { davProps } from './DavRequest.ts'
28+
import { davClient } from './DavClient.ts'
29+
import { davRootPath } from '@nextcloud/files'
30+
3031
/**
3132
* List files from a folder and filter out unwanted mimes
3233
*
@@ -51,8 +52,6 @@ export default async function(path = '', options = {}) {
5152
...options,
5253
}
5354

54-
const prefixPath = `/files/${getCurrentUser().uid}`
55-
5655
// generating the search or condition
5756
// based on the allowed mimetypes
5857
const orMime = options.mimesType.reduce((str, mime) => `${str}
@@ -109,12 +108,12 @@ export default async function(path = '', options = {}) {
109108
<d:basicsearch>
110109
<d:select>
111110
<d:prop>
112-
${props}
111+
${davProps}
113112
</d:prop>
114113
</d:select>
115114
<d:from>
116115
<d:scope>
117-
<d:href>${prefixPath}/${path}</d:href>
116+
<d:href>${davRootPath}/${path}</d:href>
118117
<d:depth>infinity</d:depth>
119118
</d:scope>
120119
</d:from>
@@ -147,7 +146,7 @@ export default async function(path = '', options = {}) {
147146
details: true,
148147
}, options)
149148

150-
const response = await client.getDirectoryContents('', options)
149+
const response = await davClient.search('/', options)
151150

152-
return response.data.map(data => genFileInfo(data))
151+
return response.data.results.map(data => genFileInfo(data))
153152
}

src/services/SystemTags.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
*
2121
*/
2222

23-
import client from './DavClient.js'
2423
import { genFileInfo } from '../utils/fileUtils.js'
24+
import { davClient } from './DavClient.ts'
2525

2626
/**
2727
* List system tags
@@ -31,7 +31,7 @@ import { genFileInfo } from '../utils/fileUtils.js'
3131
* @return {Promise<object[]>} the file list
3232
*/
3333
export default async function(path, options = {}) {
34-
const response = await client.getDirectoryContents('/systemtags-assigned/image', Object.assign({}, {
34+
const response = await davClient.getDirectoryContents('/systemtags-assigned/image', Object.assign({}, {
3535
data: `<?xml version="1.0"?>
3636
<d:propfind xmlns:d="DAV:"
3737
xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">

src/services/TaggedImages.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@
2020
*
2121
*/
2222

23+
import { davRootPath } from '@nextcloud/files'
2324
import { genFileInfo } from '../utils/fileUtils.js'
24-
import { props } from './DavRequest.js'
2525
import allowedMimes from './AllowedMimes.js'
26-
import client, { prefixPath } from './DavClient.js'
26+
import { davClient } from './DavClient.ts'
27+
import { davProps } from './DavRequest.ts'
2728

2829
/**
2930
* Get tagged files based on provided tag id
@@ -35,15 +36,17 @@ import client, { prefixPath } from './DavClient.js'
3536
export default async function(id, options = {}) {
3637

3738
options = Object.assign({
38-
method: 'REPORT',
39+
headers: {
40+
method: 'REPORT',
41+
},
3942
data: `<?xml version="1.0"?>
4043
<oc:filter-files
4144
xmlns:d="DAV:"
4245
xmlns:oc="http://owncloud.org/ns"
4346
xmlns:nc="http://nextcloud.org/ns"
4447
xmlns:ocs="http://open-collaboration-services.org/ns">
4548
<d:prop>
46-
${props}
49+
${davProps}
4750
</d:prop>
4851
<oc:filter-rules>
4952
<oc:systemtag>${id}</oc:systemtag>
@@ -52,14 +55,13 @@ export default async function(id, options = {}) {
5255
details: true,
5356
}, options)
5457

55-
const response = await client.getDirectoryContents(prefixPath, options)
56-
58+
const response = await davClient.getDirectoryContents(davRootPath, options)
5759
return response.data
58-
.map(data => genFileInfo(data))
60+
.map((data) => genFileInfo(data))
5961
// filter out unwanted mime because server REPORT service only support
6062
// hardcoded props and mime is not one of them
6163
// https://github.com/nextcloud/server/blob/5bf3d1bb384da56adbf205752be8f840aac3b0c5/apps/dav/lib/Connector/Sabre/FilesReportPlugin.php#L274
62-
.filter(file => file.mime && allowedMimes.indexOf(file.mime) !== -1)
64+
.filter((file) => file.mime && allowedMimes.indexOf(file.mime) !== -1)
6365
// remove prefix path from full file path
64-
.map(data => Object.assign({}, data, { filename: data.filename.replace(prefixPath, '') }))
66+
.map((data) => Object.assign({}, data, { filename: data.filename.replace(davRootPath, '') }))
6567
}

0 commit comments

Comments
 (0)