diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-11-12 02:02:25 +0900 |
| commit | 0e4a111f81cceed275d9bec2695f6e401fb654d8 (patch) | |
| tree | 40874799472fa07416f17b50a398ac33b7771905 /packages/backend/src/server/api/endpoints/admin/drive | |
| parent | update deps (diff) | |
| download | sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.gz sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.tar.bz2 sharkey-0e4a111f81cceed275d9bec2695f6e401fb654d8.zip | |
refactoring
Resolve #7779
Diffstat (limited to 'packages/backend/src/server/api/endpoints/admin/drive')
4 files changed, 295 insertions, 0 deletions
diff --git a/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts new file mode 100644 index 0000000000..76a6acff59 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/drive/clean-remote-files.ts @@ -0,0 +1,13 @@ +import define from '../../../define'; +import { createCleanRemoteFilesJob } from '@/queue/index'; + +export const meta = { + tags: ['admin'], + + requireCredential: true as const, + requireModerator: true, +}; + +export default define(meta, async (ps, me) => { + createCleanRemoteFilesJob(); +}); diff --git a/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts new file mode 100644 index 0000000000..8497478da9 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/drive/cleanup.ts @@ -0,0 +1,21 @@ +import { IsNull } from 'typeorm'; +import define from '../../../define'; +import { deleteFile } from '@/services/drive/delete-file'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + tags: ['admin'], + + requireCredential: true as const, + requireModerator: true, +}; + +export default define(meta, async (ps, me) => { + const files = await DriveFiles.find({ + userId: IsNull() + }); + + for (const file of files) { + deleteFile(file); + } +}); diff --git a/packages/backend/src/server/api/endpoints/admin/drive/files.ts b/packages/backend/src/server/api/endpoints/admin/drive/files.ts new file mode 100644 index 0000000000..fe1c799805 --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/drive/files.ts @@ -0,0 +1,81 @@ +import $ from 'cafy'; +import define from '../../../define'; +import { DriveFiles } from '@/models/index'; +import { makePaginationQuery } from '../../../common/make-pagination-query'; +import { ID } from '@/misc/cafy-id'; + +export const meta = { + tags: ['admin'], + + requireCredential: false as const, + requireModerator: true, + + params: { + limit: { + validator: $.optional.num.range(1, 100), + default: 10 + }, + + sinceId: { + validator: $.optional.type(ID), + }, + + untilId: { + validator: $.optional.type(ID), + }, + + type: { + validator: $.optional.nullable.str.match(/^[a-zA-Z0-9\/\-*]+$/) + }, + + origin: { + validator: $.optional.str.or([ + 'combined', + 'local', + 'remote', + ]), + default: 'local' + }, + + hostname: { + validator: $.optional.nullable.str, + default: null + }, + }, + + res: { + type: 'array' as const, + optional: false as const, nullable: false as const, + items: { + type: 'object' as const, + optional: false as const, nullable: false as const, + ref: 'DriveFile' + } + } +}; + +export default define(meta, async (ps, me) => { + const query = makePaginationQuery(DriveFiles.createQueryBuilder('file'), ps.sinceId, ps.untilId); + + if (ps.origin === 'local') { + query.andWhere('file.userHost IS NULL'); + } else if (ps.origin === 'remote') { + query.andWhere('file.userHost IS NOT NULL'); + } + + if (ps.hostname) { + query.andWhere('file.userHost = :hostname', { hostname: ps.hostname }); + } + + if (ps.type) { + if (ps.type.endsWith('/*')) { + query.andWhere('file.type like :type', { type: ps.type.replace('/*', '/') + '%' }); + } else { + query.andWhere('file.type = :type', { type: ps.type }); + } + } + + const files = await query.take(ps.limit!).getMany(); + + return await DriveFiles.packMany(files, { detail: true, withUser: true, self: true }); +}); diff --git a/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts new file mode 100644 index 0000000000..270b89c4fa --- /dev/null +++ b/packages/backend/src/server/api/endpoints/admin/drive/show-file.ts @@ -0,0 +1,180 @@ +import $ from 'cafy'; +import { ID } from '@/misc/cafy-id'; +import define from '../../../define'; +import { ApiError } from '../../../error'; +import { DriveFiles } from '@/models/index'; + +export const meta = { + tags: ['admin'], + + requireCredential: true as const, + requireModerator: true, + + params: { + fileId: { + validator: $.optional.type(ID), + }, + + url: { + validator: $.optional.str, + }, + }, + + errors: { + noSuchFile: { + message: 'No such file.', + code: 'NO_SUCH_FILE', + id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240' + } + }, + + res: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + id: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + createdAt: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'date-time', + }, + userId: { + type: 'string' as const, + optional: false as const, nullable: true as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + userHost: { + type: 'string' as const, + optional: false as const, nullable: true as const + }, + md5: { + type: 'string' as const, + optional: false as const, nullable: false as const, + format: 'md5', + example: '15eca7fba0480996e2245f5185bf39f2' + }, + name: { + type: 'string' as const, + optional: false as const, nullable: false as const, + example: 'lenna.jpg' + }, + type: { + type: 'string' as const, + optional: false as const, nullable: false as const, + example: 'image/jpeg' + }, + size: { + type: 'number' as const, + optional: false as const, nullable: false as const, + example: 51469 + }, + comment: { + type: 'string' as const, + optional: false as const, nullable: true as const + }, + blurhash: { + type: 'string' as const, + optional: false as const, nullable: true as const + }, + properties: { + type: 'object' as const, + optional: false as const, nullable: false as const, + properties: { + width: { + type: 'number' as const, + optional: false as const, nullable: false as const, + example: 1280 + }, + height: { + type: 'number' as const, + optional: false as const, nullable: false as const, + example: 720 + }, + avgColor: { + type: 'string' as const, + optional: true as const, nullable: false as const, + example: 'rgb(40,65,87)' + } + } + }, + storedInternal: { + type: 'boolean' as const, + optional: false as const, nullable: true as const, + example: true + }, + url: { + type: 'string' as const, + optional: false as const, nullable: true as const, + format: 'url', + }, + thumbnailUrl: { + type: 'string' as const, + optional: false as const, nullable: true as const, + format: 'url', + }, + webpublicUrl: { + type: 'string' as const, + optional: false as const, nullable: true as const, + format: 'url', + }, + accessKey: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + thumbnailAccessKey: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + webpublicAccessKey: { + type: 'string' as const, + optional: false as const, nullable: false as const, + }, + uri: { + type: 'string' as const, + optional: false as const, nullable: true as const + }, + src: { + type: 'string' as const, + optional: false as const, nullable: true as const + }, + folderId: { + type: 'string' as const, + optional: false as const, nullable: true as const, + format: 'id', + example: 'xxxxxxxxxx', + }, + isSensitive: { + type: 'boolean' as const, + optional: false as const, nullable: false as const, + }, + isLink: { + type: 'boolean' as const, + optional: false as const, nullable: false as const + } + } + } +}; + +export default define(meta, async (ps, me) => { + const file = ps.fileId ? await DriveFiles.findOne(ps.fileId) : await DriveFiles.findOne({ + where: [{ + url: ps.url + }, { + thumbnailUrl: ps.url + }, { + webpublicUrl: ps.url + }] + }); + + if (file == null) { + throw new ApiError(meta.errors.noSuchFile); + } + + return file; +}); |