Skip to content

Commit

Permalink
enh: Migrate to use webdav v5 and @nextcloud/files for DAV handling
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Feb 4, 2024
1 parent dc24021 commit 3f18ec3
Show file tree
Hide file tree
Showing 19 changed files with 142 additions and 260 deletions.
2 changes: 1 addition & 1 deletion src/components/FilesListViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import { NcEmptyContent, NcLoadingIcon } from '@nextcloud/vue'
import { subscribe, unsubscribe } from '@nextcloud/event-bus'

import TiledLayout from '../components/TiledLayout/TiledLayout.vue'
import { fetchFile } from '../services/fileFetcher.js'
import { fetchFile } from '../services/fileFetcher.ts'
import VirtualScrolling from '../components/VirtualScrolling.vue'
import EmptyBox from '../assets/Illustrations/empty.svg'
import UserConfig from '../mixins/UserConfig.js'
Expand Down
27 changes: 13 additions & 14 deletions src/mixins/FetchFacesMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@
*
*/

import { mapActions, mapGetters } from 'vuex'

import { showError } from '@nextcloud/dialogs'
import { getCurrentUser } from '@nextcloud/auth'
import { mapActions, mapGetters } from 'vuex'
import he from 'he'

import client from '../services/DavClient.js'
import logger from '../services/logger.js'
import DavRequest from '../services/DavRequest.js'
import { genFileInfo } from '../utils/fileUtils.js'
import logger from '../services/logger.js'
import AbortControllerMixin from './AbortControllerMixin.js'
import he from 'he'
import { davClient } from '../services/DavClient.ts'
import { getPropFind } from '../services/DavRequest.ts'

export default {
name: 'FetchFacesMixin',
Expand Down Expand Up @@ -76,8 +75,8 @@ export default {
this.loadingFaces = true
this.errorFetchingFaces = null

const { data: faces } = await client.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {
data: DavRequest,
const { data: faces } = await davClient.getDirectoryContents(`/recognize/${getCurrentUser()?.uid}/faces/`, {
data: getPropFind(),
details: true,
signal: this.abortController.signal,
})
Expand Down Expand Up @@ -111,10 +110,10 @@ export default {
this.errorFetchingFiles = null
this.loadingFiles = true

let { data: fetchedFiles } = await client.getDirectoryContents(
let { data: fetchedFiles } = await davClient.getDirectoryContents(
`/recognize/${getCurrentUser()?.uid}/faces/${faceName}`,
{
data: DavRequest,
data: getPropFind(),
details: true,
signal: this.abortController.signal,
}
Expand Down Expand Up @@ -163,10 +162,10 @@ export default {
this.errorFetchingFiles = null
this.loadingFiles = true

let { data: fetchedFiles } = await client.getDirectoryContents(
let { data: fetchedFiles } = await davClient.getDirectoryContents(
`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,
{
data: DavRequest,
data: getPropFind(),
details: true,
signal: this.abortController.signal,
}
Expand Down Expand Up @@ -204,10 +203,10 @@ export default {

async fetchUnassignedFacesCount() {
try {
const { data: unassignedFacesRoot } = await client.stat(
const { data: unassignedFacesRoot } = await davClient.stat(
`/recognize/${getCurrentUser()?.uid}/unassigned-faces`,
{
data: DavRequest,
data: getPropFind(),
details: true,
signal: this.abortController.signal,
}
Expand Down
5 changes: 3 additions & 2 deletions src/mixins/FetchFilesMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*
*/

import { showError } from '@nextcloud/dialogs'
import logger from '../services/logger.js'
import getPhotos from '../services/PhotoSearch.js'
import SemaphoreWithPriority from '../utils/semaphoreWithPriority.js'
Expand Down Expand Up @@ -107,8 +108,8 @@ export default {
}

// cancelled request, moving on...
logger.error('Error fetching files', { error })
console.error(error)
showError(t('photos', 'Error fetching files'))
logger.error(error)
} finally {
this.loadingFiles = false
this.fetchSemaphore.release(fetchSemaphoreSymbol)
Expand Down
41 changes: 0 additions & 41 deletions src/services/DavClient.js

This file was deleted.

28 changes: 5 additions & 23 deletions src/services/FileInfo.js → src/services/DavClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @copyright Copyright (c) 2019 John Molakvoæ <[email protected]>
* @copyright Copyright (c) 2024 Ferdinand Thiessen <[email protected]>
*
* @author John Molakvoæ <[email protected]>
* @author Ferdinand Thiessen <[email protected]>
*
* @license AGPL-3.0-or-later
*
Expand All @@ -20,25 +20,7 @@
*
*/

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

/**
* Get a file info
*
* @param {string} path the path relative to the user root
* @return {FileInfo} the file info
*/
export default async function(path) {
// getDirectoryContents doesn't accept / for root
const fixedPath = path === '/' ? '' : path

// fetch listing
const response = await client.stat(prefixPath + fixedPath, {
data: request,
details: true,
})

return genFileInfo(response.data)
}
export const davClient: WebDAVClient = davGetClient()
13 changes: 9 additions & 4 deletions src/services/DavRequest.js → src/services/DavRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @copyright Copyright (c) 2019 John Molakvoæ <[email protected]>
*
* @author John Molakvoæ <[email protected]>
* @author Ferdinand Thiessen <[email protected]>
*
* @license AGPL-3.0-or-later
*
Expand All @@ -19,7 +20,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
const props = `
export const davProps = `
<d:getcontentlength />
<d:getcontenttype />
<d:getetag />
Expand All @@ -39,13 +40,17 @@ const props = `
<nc:nbItems />
`

export { props }
export default `<?xml version="1.0"?>
/**
* @param extraProps - Extra properties to add to the DAV request.
*/
export function getPropFind(extraProps: string[] = []): string {
return `<?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>
${props}
${[...davProps, ...extraProps].join('')}
</d:prop>
</d:propfind>`
}
44 changes: 0 additions & 44 deletions src/services/FolderInfo.js

This file was deleted.

21 changes: 10 additions & 11 deletions src/services/PhotoSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
*
*/

import { genFileInfo } from '../utils/fileUtils.js'
import { getCurrentUser } from '@nextcloud/auth'
import { allMimes } from './AllowedMimes.js'
import client from './DavClient.js'
import { props } from './DavRequest.js'
import moment from '@nextcloud/moment'

import { allMimes } from './AllowedMimes.js'
import { genFileInfo } from '../utils/fileUtils.js'
import { davProps } from './DavRequest.ts'
import { davClient } from './DavClient.ts'
import { davRootPath } from '@nextcloud/files'

/**
* List files from a folder and filter out unwanted mimes
*
Expand All @@ -51,8 +52,6 @@ export default async function(path = '', options = {}) {
...options,
}

const prefixPath = `/files/${getCurrentUser().uid}`

// generating the search or condition
// based on the allowed mimetypes
const orMime = options.mimesType.reduce((str, mime) => `${str}
Expand Down Expand Up @@ -109,12 +108,12 @@ export default async function(path = '', options = {}) {
<d:basicsearch>
<d:select>
<d:prop>
${props}
${davProps}
</d:prop>
</d:select>
<d:from>
<d:scope>
<d:href>${prefixPath}/${path}</d:href>
<d:href>${davRootPath}/${path}</d:href>
<d:depth>infinity</d:depth>
</d:scope>
</d:from>
Expand Down Expand Up @@ -147,7 +146,7 @@ export default async function(path = '', options = {}) {
details: true,
}, options)

const response = await client.getDirectoryContents('', options)
const response = await davClient.search('/', options)

return response.data.map(data => genFileInfo(data))
return response.data.results.map(data => genFileInfo(data))
}
4 changes: 2 additions & 2 deletions src/services/SystemTags.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
*
*/

import client from './DavClient.js'
import { genFileInfo } from '../utils/fileUtils.js'
import { davClient } from './DavClient.ts'

/**
* List system tags
Expand All @@ -31,7 +31,7 @@ import { genFileInfo } from '../utils/fileUtils.js'
* @return {Promise<object[]>} the file list
*/
export default async function(path, options = {}) {
const response = await client.getDirectoryContents('/systemtags-assigned/image', Object.assign({}, {
const response = await davClient.getDirectoryContents('/systemtags-assigned/image', Object.assign({}, {
data: `<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:"
xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
Expand Down
20 changes: 11 additions & 9 deletions src/services/TaggedImages.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
*
*/

import { davRootPath } from '@nextcloud/files'
import { genFileInfo } from '../utils/fileUtils.js'
import { props } from './DavRequest.js'
import allowedMimes from './AllowedMimes.js'
import client, { prefixPath } from './DavClient.js'
import { davClient } from './DavClient.ts'
import { davProps } from './DavRequest.ts'

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

options = Object.assign({
method: 'REPORT',
headers: {
method: 'REPORT',
},
data: `<?xml version="1.0"?>
<oc:filter-files
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>
${props}
${davProps}
</d:prop>
<oc:filter-rules>
<oc:systemtag>${id}</oc:systemtag>
Expand All @@ -52,14 +55,13 @@ export default async function(id, options = {}) {
details: true,
}, options)

const response = await client.getDirectoryContents(prefixPath, options)

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

0 comments on commit 3f18ec3

Please sign in to comment.