diff --git a/src/client/app/desktop/views/components/drive.file.vue b/src/client/app/desktop/views/components/drive.file.vue index a4531e221..86addb131 100644 --- a/src/client/app/desktop/views/components/drive.file.vue +++ b/src/client/app/desktop/views/components/drive.file.vue @@ -145,7 +145,7 @@ export default Vue.extend({ (this as any).api('drive/files/update', { fileId: this.file.id, name: name - }) + }); }); }, @@ -173,7 +173,9 @@ export default Vue.extend({ }, deleteFile() { - alert('not implemented yet'); + (this as any).api('drive/files/delete', { + fileId: this.file.id + }); } } }); diff --git a/src/client/app/desktop/views/components/drive.vue b/src/client/app/desktop/views/components/drive.vue index b69c88408..df141b6d6 100644 --- a/src/client/app/desktop/views/components/drive.vue +++ b/src/client/app/desktop/views/components/drive.vue @@ -118,6 +118,7 @@ export default Vue.extend({ this.connection.on('file_created', this.onStreamDriveFileCreated); this.connection.on('file_updated', this.onStreamDriveFileUpdated); + this.connection.on('file_deleted', this.onStreamDriveFileDeleted); this.connection.on('folder_created', this.onStreamDriveFolderCreated); this.connection.on('folder_updated', this.onStreamDriveFolderUpdated); @@ -130,6 +131,7 @@ export default Vue.extend({ beforeDestroy() { this.connection.off('file_created', this.onStreamDriveFileCreated); this.connection.off('file_updated', this.onStreamDriveFileUpdated); + this.connection.off('file_deleted', this.onStreamDriveFileDeleted); this.connection.off('folder_created', this.onStreamDriveFolderCreated); this.connection.off('folder_updated', this.onStreamDriveFolderUpdated); (this as any).os.streams.driveStream.dispose(this.connectionId); @@ -167,6 +169,10 @@ export default Vue.extend({ } }, + onStreamDriveFileDeleted(fileId) { + this.removeFile(fileId); + }, + onStreamDriveFolderCreated(folder) { this.addFolder(folder, true); }, diff --git a/src/client/app/mobile/views/components/drive.file-detail.vue b/src/client/app/mobile/views/components/drive.file-detail.vue index ad2913526..f6a22f95f 100644 --- a/src/client/app/mobile/views/components/drive.file-detail.vue +++ b/src/client/app/mobile/views/components/drive.file-detail.vue @@ -34,15 +34,10 @@
@@ -112,6 +107,13 @@ export default Vue.extend({ }); }); }, + del() { + (this as any).api('drive/files/delete', { + fileId: this.file.id + }).then(() => { + this.browser.cd(this.file.folderId, true); + }); + }, showCreatedAt() { alert(new Date(this.file.createdAt).toLocaleString()); }, diff --git a/src/client/app/mobile/views/components/drive.vue b/src/client/app/mobile/views/components/drive.vue index 8adf6d854..c313d225e 100644 --- a/src/client/app/mobile/views/components/drive.vue +++ b/src/client/app/mobile/views/components/drive.vue @@ -100,6 +100,7 @@ export default Vue.extend({ this.connection.on('file_created', this.onStreamDriveFileCreated); this.connection.on('file_updated', this.onStreamDriveFileUpdated); + this.connection.on('file_deleted', this.onStreamDriveFileDeleted); this.connection.on('folder_created', this.onStreamDriveFolderCreated); this.connection.on('folder_updated', this.onStreamDriveFolderUpdated); @@ -118,6 +119,7 @@ export default Vue.extend({ beforeDestroy() { this.connection.off('file_created', this.onStreamDriveFileCreated); this.connection.off('file_updated', this.onStreamDriveFileUpdated); + this.connection.off('file_deleted', this.onStreamDriveFileDeleted); this.connection.off('folder_created', this.onStreamDriveFolderCreated); this.connection.off('folder_updated', this.onStreamDriveFolderUpdated); (this as any).os.streams.driveStream.dispose(this.connectionId); @@ -136,6 +138,10 @@ export default Vue.extend({ } }, + onStreamDriveFileDeleted(fileId) { + this.removeFile(fileId); + }, + onStreamDriveFolderCreated(folder) { this.addFolder(folder, true); }, diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts index ab4b18cef..0f0e3d65a 100644 --- a/src/server/api/endpoints/drive/files.ts +++ b/src/server/api/endpoints/drive/files.ts @@ -37,10 +37,13 @@ module.exports = async (params, user, app) => { const sort = { _id: -1 }; + const query = { 'metadata.userId': user._id, - 'metadata.folderId': folderId + 'metadata.folderId': folderId, + 'metadata.deletedAt': { $exists: false } } as any; + if (sinceId) { sort._id = 1; query._id = { @@ -51,6 +54,7 @@ module.exports = async (params, user, app) => { $lt: untilId }; } + if (type) { query.contentType = new RegExp(`^${type.replace(/\*/g, '.+?')}$`); } diff --git a/src/server/api/endpoints/drive/files/delete.ts b/src/server/api/endpoints/drive/files/delete.ts new file mode 100644 index 000000000..a722b4e82 --- /dev/null +++ b/src/server/api/endpoints/drive/files/delete.ts @@ -0,0 +1,32 @@ +import $ from 'cafy'; import ID from '../../../../../cafy-id'; +import DriveFile from '../../../../../models/drive-file'; +import del from '../../../../../services/drive/delete-file'; +import { publishDriveStream } from '../../../../../publishers/stream'; + +/** + * Delete a file + */ +module.exports = async (params, user) => { + // Get 'fileId' parameter + const [fileId, fileIdErr] = $.type(ID).get(params.fileId); + if (fileIdErr) throw 'invalid fileId param'; + + // Fetch file + const file = await DriveFile + .findOne({ + _id: fileId, + 'metadata.userId': user._id + }); + + if (file === null) { + throw 'file-not-found'; + } + + // Delete + await del(file); + + // Publish file_deleted event + publishDriveStream(user._id, 'file_deleted', file._id); + + return; +}; diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts index ace1a6d62..d7f71e866 100644 --- a/src/services/drive/add-file.ts +++ b/src/services/drive/add-file.ts @@ -9,13 +9,14 @@ import * as debug from 'debug'; import fileType = require('file-type'); import prominence = require('prominence'); -import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile, DriveFileChunk } from '../../models/drive-file'; +import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile } from '../../models/drive-file'; import DriveFolder from '../../models/drive-folder'; import { pack } from '../../models/drive-file'; import event, { publishDriveStream } from '../../publishers/stream'; import { isLocalUser, IUser, IRemoteUser } from '../../models/user'; -import DriveFileThumbnail, { getDriveFileThumbnailBucket, DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail'; +import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail'; import genThumbnail from '../../drive/gen-thumbnail'; +import delFile from './delete-file'; const gm = _gm.subClass({ imageMagick: true @@ -58,31 +59,7 @@ async function deleteOldFile(user: IRemoteUser) { }); if (oldFile) { - // チャンクをすべて削除 - DriveFileChunk.remove({ - files_id: oldFile._id - }); - - DriveFile.update({ _id: oldFile._id }, { - $set: { - 'metadata.deletedAt': new Date(), - 'metadata.isExpired': true - } - }); - - //#region サムネイルもあれば削除 - const thumbnail = await DriveFileThumbnail.findOne({ - 'metadata.originalId': oldFile._id - }); - - if (thumbnail) { - DriveFileThumbnailChunk.remove({ - files_id: thumbnail._id - }); - - DriveFileThumbnail.remove({ _id: thumbnail._id }); - } - //#endregion + delFile(oldFile, true); } } diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts new file mode 100644 index 000000000..a8ed13bd7 --- /dev/null +++ b/src/services/drive/delete-file.ts @@ -0,0 +1,30 @@ +import DriveFile, { DriveFileChunk, IDriveFile } from "../../models/drive-file"; +import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail'; + +export default async function(file: IDriveFile, isExpired = false) { + // チャンクをすべて削除 + await DriveFileChunk.remove({ + files_id: file._id + }); + + await DriveFile.update({ _id: file._id }, { + $set: { + 'metadata.deletedAt': new Date(), + 'metadata.isExpired': isExpired + } + }); + + //#region サムネイルもあれば削除 + const thumbnail = await DriveFileThumbnail.findOne({ + 'metadata.originalId': file._id + }); + + if (thumbnail) { + await DriveFileThumbnailChunk.remove({ + files_id: thumbnail._id + }); + + await DriveFileThumbnail.remove({ _id: thumbnail._id }); + } + //#endregion +}