add image delete api

This commit is contained in:
rubikscraft
2022-05-04 21:50:11 +02:00
parent 80b60595fe
commit 966954acc7
4 changed files with 101 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
import { Repository } from 'typeorm';
import { In, Repository } from 'typeorm';
import { EImageDerivativeBackend } from '../../models/entities/image-derivative.entity';
import { EImageFileBackend } from '../../models/entities/image-file.entity';
import { EImageBackend } from '../../models/entities/image.entity';
@@ -33,10 +33,13 @@ export class ImageDBService {
return imageEntity;
}
public async findOne(id: string): AsyncFailable<EImageBackend> {
public async findOne(
id: string,
userid: string | undefined,
): AsyncFailable<EImageBackend> {
try {
const found = await this.imageRepo.findOne({
where: { id },
where: { id, user_id: userid },
});
if (!found) return Fail('Image not found');
@@ -49,7 +52,7 @@ export class ImageDBService {
public async findMany(
count: number,
page: number,
userid: string | false,
userid: string | undefined,
): AsyncFailable<EImageBackend[]> {
if (count < 1 || page < 0) return Fail('Invalid page');
if (count > 100) return Fail('Too many results');
@@ -59,7 +62,7 @@ export class ImageDBService {
skip: count * page,
take: count,
where: {
user_id: userid === false ? undefined : userid,
user_id: userid,
},
});
@@ -70,15 +73,40 @@ export class ImageDBService {
}
}
public async delete(id: string): AsyncFailable<true> {
public async findList(
ids: string[],
userid: string | undefined,
): AsyncFailable<EImageBackend[]> {
if (ids.length === 0) return [];
if (ids.length > 500) return Fail('Too many results');
try {
const found = await this.imageRepo.find({
where: {
id: In(ids),
user_id: userid,
},
});
if (found === undefined) return Fail('Images not found');
return found;
} catch (e) {
return Fail(e);
}
}
public async delete(ids: string[]): AsyncFailable<true> {
if (ids.length === 0) return true;
if (ids.length > 500) return Fail('Too many results');
try {
const derivativesResult = await this.imageDerivativeRepo.delete({
image_id: id,
image_id: In(ids),
});
const filesResult = await this.imageFileRepo.delete({
image_id: id,
image_id: In(ids),
});
const result = await this.imageRepo.delete({ id });
const result = await this.imageRepo.delete({ id: In(ids) });
if (
result.affected === 0 &&

View File

@@ -33,18 +33,35 @@ export class ImageManagerService {
private readonly sysPref: SysPreferenceService,
) {}
public async findOne(id: string): AsyncFailable<EImageBackend> {
return await this.imagesService.findOne(id);
public async findOne(
id: string,
): AsyncFailable<EImageBackend> {
return await this.imagesService.findOne(id, undefined);
}
public async findMany(
count: number,
page: number,
userid: string | false,
userid: string | undefined,
): AsyncFailable<EImageBackend[]> {
return await this.imagesService.findMany(count, page, userid);
}
public async deleteMany(
ids: string[],
userid: string | undefined,
): AsyncFailable<EImageBackend[]> {
const images = await this.imagesService.findList(ids, userid);
if (HasFailed(images)) return images;
const availableIds = images.map(image => image.id);
const deleteResult = await this.imagesService.delete(availableIds);
if (HasFailed(deleteResult)) return deleteResult;
return images;
}
public async upload(
image: Buffer,
userid: string,

View File

@@ -1,4 +1,5 @@
import {
BadRequestException,
Body,
Controller,
InternalServerErrorException,
@@ -6,6 +7,8 @@ import {
Post
} from '@nestjs/common';
import {
ImageDeleteRequest,
ImageDeleteResponse,
ImageListRequest,
ImageListResponse,
ImageUploadResponse
@@ -61,7 +64,7 @@ export class ImageManageController {
const images = await this.imagesService.findMany(
body.count,
body.page,
userid,
body.user_id,
);
if (HasFailed(images)) {
this.logger.warn(images.getReason());
@@ -74,4 +77,26 @@ export class ImageManageController {
page: body.page,
};
}
@Post('delete')
@Returns(ImageDeleteResponse)
async deleteImage(
@Body() body: ImageDeleteRequest,
@ReqUserID() userid: string,
@HasPermission(Permission.ImageAdmin) isImageAdmin: boolean,
): Promise<ImageDeleteResponse> {
const deletedImages = await this.imagesService.deleteMany(
body.ids,
isImageAdmin ? undefined : userid,
);
if (HasFailed(deletedImages)) {
this.logger.warn(deletedImages.getReason());
throw new BadRequestException('Could not delete images');
}
return {
images: deletedImages,
count: deletedImages.length,
};
}
}

View File

@@ -16,9 +16,7 @@ export const ImageListRequestSchema = z.object({
page: IsPosInt(),
user_id: z.string().uuid().optional(),
});
export class ImageListRequest extends createZodDto(
ImageListRequestSchema,
) {}
export class ImageListRequest extends createZodDto(ImageListRequestSchema) {}
export const ImageListResponseSchema = z.object({
images: z.array(EImageSchema),
@@ -26,3 +24,20 @@ export const ImageListResponseSchema = z.object({
page: IsPosInt(),
});
export class ImageListResponse extends createZodDto(ImageListResponseSchema) {}
// Image Delete
export const ImageDeleteRequestSchema = z.object({
ids: z.array(z.string().uuid()),
});
export class ImageDeleteRequest extends createZodDto(
ImageDeleteRequestSchema,
) {}
export const ImageDeleteResponseSchema = z.object({
images: z.array(EImageSchema),
count: IsPosInt(),
});
export class ImageDeleteResponse extends createZodDto(
ImageDeleteResponseSchema,
) {}