postiz/apps/backend/src/api/routes/media.controller.ts

183 lines
4.9 KiB
TypeScript

import {
Body,
Controller,
Delete,
Get,
Param,
Post,
Query,
Req,
Res,
UploadedFile,
UseInterceptors,
UsePipes,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { GetOrgFromRequest } from '@gitroom/nestjs-libraries/user/org.from.request';
import { Organization } from '@prisma/client';
import { MediaService } from '@gitroom/nestjs-libraries/database/prisma/media/media.service';
import { ApiTags } from '@nestjs/swagger';
import handleR2Upload from '@gitroom/nestjs-libraries/upload/r2.uploader';
import { FileInterceptor } from '@nestjs/platform-express';
import { CustomFileValidationPipe } from '@gitroom/nestjs-libraries/upload/custom.upload.validation';
import { SubscriptionService } from '@gitroom/nestjs-libraries/database/prisma/subscriptions/subscription.service';
import { UploadFactory } from '@gitroom/nestjs-libraries/upload/upload.factory';
import { SaveMediaInformationDto } from '@gitroom/nestjs-libraries/dtos/media/save.media.information.dto';
import { VideoDto } from '@gitroom/nestjs-libraries/dtos/videos/video.dto';
@ApiTags('Media')
@Controller('/media')
export class MediaController {
private storage = UploadFactory.createStorage();
constructor(
private _mediaService: MediaService,
private _subscriptionService: SubscriptionService
) {}
@Delete('/:id')
deleteMedia(@GetOrgFromRequest() org: Organization, @Param('id') id: string) {
return this._mediaService.deleteMedia(org.id, id);
}
@Post('/generate-image')
async generateImage(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('prompt') prompt: string,
isPicturePrompt = false
) {
const total = await this._subscriptionService.checkCredits(org);
if (process.env.STRIPE_PUBLISHABLE_KEY && total.credits <= 0) {
return false;
}
return {
output:
(isPicturePrompt ? '' : 'data:image/png;base64,') +
(await this._mediaService.generateImage(prompt, org, isPicturePrompt)),
};
}
@Post('/generate-image-with-prompt')
async generateImageFromText(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('prompt') prompt: string
) {
const image = await this.generateImage(org, req, prompt, true);
if (!image) {
return false;
}
const file = await this.storage.uploadSimple(image.output);
return this._mediaService.saveFile(org.id, file.split('/').pop(), file);
}
@Post('/upload-server')
@UseInterceptors(FileInterceptor('file'))
@UsePipes(new CustomFileValidationPipe())
async uploadServer(
@GetOrgFromRequest() org: Organization,
@UploadedFile() file: Express.Multer.File
) {
const uploadedFile = await this.storage.uploadFile(file);
return this._mediaService.saveFile(
org.id,
uploadedFile.originalname,
uploadedFile.path
);
}
@Post('/save-media')
async saveMedia(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Body('name') name: string
) {
if (!name) {
return false;
}
return this._mediaService.saveFile(
org.id,
name,
process.env.CLOUDFLARE_BUCKET_URL + '/' + name
);
}
@Post('/information')
saveMediaInformation(
@GetOrgFromRequest() org: Organization,
@Body() body: SaveMediaInformationDto
) {
return this._mediaService.saveMediaInformation(org.id, body);
}
@Post('/upload-simple')
@UseInterceptors(FileInterceptor('file'))
async uploadSimple(
@GetOrgFromRequest() org: Organization,
@UploadedFile('file') file: Express.Multer.File,
@Body('preventSave') preventSave: string = 'false'
) {
const getFile = await this.storage.uploadFile(file);
if (preventSave === 'true') {
const { path } = getFile;
return { path };
}
return this._mediaService.saveFile(
org.id,
getFile.originalname,
getFile.path
);
}
@Post('/:endpoint')
async uploadFile(
@GetOrgFromRequest() org: Organization,
@Req() req: Request,
@Res() res: Response,
@Param('endpoint') endpoint: string
) {
const upload = await handleR2Upload(endpoint, req, res);
if (endpoint !== 'complete-multipart-upload') {
return upload;
}
// @ts-ignore
const name = upload.Location.split('/').pop();
const saveFile = await this._mediaService.saveFile(
org.id,
name,
// @ts-ignore
upload.Location
);
res.status(200).json({ ...upload, saved: saveFile });
}
@Get('/')
getMedia(
@GetOrgFromRequest() org: Organization,
@Query('page') page: number
) {
return this._mediaService.getMedia(org.id, page);
}
@Get('/video-options')
getVideos() {
return this._mediaService.getVideoOptions();
}
@Post('/generate-video/:type')
generateVideo(
@GetOrgFromRequest() org: Organization,
@Body() body: VideoDto,
@Param('type') type: string,
) {
return this._mediaService.generateVideo(org.id, body, type);
}
}