Adiciona criacao de video
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
import axios, { isAxiosError } from 'axios';
|
||||
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
|
||||
@@ -42,10 +46,10 @@ export class AuthService {
|
||||
} catch (error) {
|
||||
if (isAxiosError(error)) {
|
||||
console.error(error.response?.data);
|
||||
throw new UnauthorizedException(error.response?.data);
|
||||
throw new BadRequestException(error.response?.data);
|
||||
}
|
||||
|
||||
throw new UnauthorizedException('Usuário ou senha inválidos');
|
||||
throw new BadRequestException('Usuário ou senha inválidos');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
|
||||
import { Transform } from 'class-transformer';
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
IsArray,
|
||||
IsNumber,
|
||||
@@ -11,8 +8,6 @@ import {
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
export class CreateVideoDto {
|
||||
@IsOptional()
|
||||
@IsString({ message: 'Id deve ser uma string' })
|
||||
@@ -46,34 +41,29 @@ export class CreateVideoDto {
|
||||
@MaxLength(244)
|
||||
videoid?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString({ message: 'Duration deve ser uma string' })
|
||||
@Transform(({ value }: { value: number }) => {
|
||||
const duration = dayjs.duration(value, 'seconds');
|
||||
|
||||
return duration.format('HH:mm:ss');
|
||||
})
|
||||
duration?: string;
|
||||
@IsNumber()
|
||||
@Type(() => Number)
|
||||
duration!: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(244)
|
||||
description?: string;
|
||||
|
||||
@IsString()
|
||||
@MaxLength(244)
|
||||
qualidade: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUrl()
|
||||
@MaxLength(244)
|
||||
transcriptionUrl?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber(
|
||||
{ allowNaN: false, allowInfinity: false },
|
||||
{ message: 'Timestamp deve ser um número' },
|
||||
)
|
||||
@Transform(({ value }: { value: number }) => {
|
||||
const duration = dayjs(value * 1000);
|
||||
|
||||
return duration.format('DD/MM/YYYY HH:mm:ss');
|
||||
})
|
||||
timestamp?: string;
|
||||
timestamp?: number;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Query,
|
||||
Patch,
|
||||
Body,
|
||||
Delete,
|
||||
UseGuards,
|
||||
Post,
|
||||
Query,
|
||||
UseGuards,
|
||||
UsePipes,
|
||||
ValidationPipe,
|
||||
} from '@nestjs/common';
|
||||
import { Prisma, videos, video_situation } from 'generated/prisma';
|
||||
|
||||
@@ -57,6 +59,13 @@ export class VideosController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
@UsePipes(
|
||||
new ValidationPipe({
|
||||
whitelist: true,
|
||||
forbidNonWhitelisted: true,
|
||||
transform: true,
|
||||
}),
|
||||
)
|
||||
@Roles('user', 'admin')
|
||||
async create(@Body() body: CreateVideoDto): Promise<void> {
|
||||
await this.videosService.createNewVideo(body);
|
||||
|
||||
@@ -12,6 +12,24 @@ import { PaginatedResponse } from '@shared/dto/paginated';
|
||||
import { ListVideosQueryDto } from './dto/list-videos-query.dto';
|
||||
import { VideoMetadataDto } from '@shared/dto/video-metadata';
|
||||
import { CreateVideoDto } from './dto/create-video-dto';
|
||||
import { N8N_REMOTE_SERVER } from '@/shared/url';
|
||||
|
||||
const formatSecondsToClock = (totalSeconds: number): string => {
|
||||
if (!Number.isFinite(totalSeconds)) {
|
||||
return '00:00:00';
|
||||
}
|
||||
|
||||
const safeSeconds = Math.max(0, Math.floor(totalSeconds));
|
||||
const hours = Math.floor(safeSeconds / 3600)
|
||||
.toString()
|
||||
.padStart(2, '0');
|
||||
const minutes = Math.floor((safeSeconds % 3600) / 60)
|
||||
.toString()
|
||||
.padStart(2, '0');
|
||||
const seconds = (safeSeconds % 60).toString().padStart(2, '0');
|
||||
|
||||
return `${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class VideosService {
|
||||
@@ -137,17 +155,62 @@ export class VideosService {
|
||||
}
|
||||
|
||||
async createNewVideo(data: CreateVideoDto): Promise<void> {
|
||||
const { url, videoid } = data;
|
||||
const { url, videoid, duration, qualidade, title, timestamp } = data;
|
||||
|
||||
const query: Prisma.videosWhereInput = { url };
|
||||
|
||||
if (videoid) {
|
||||
query.videoid = videoid;
|
||||
}
|
||||
|
||||
const searchUrl = await this.prisma.videos.findFirst({
|
||||
where: { url, videoid },
|
||||
where: query,
|
||||
});
|
||||
|
||||
if (!isEmpty(searchUrl)) {
|
||||
if (searchUrl && !isEmpty(searchUrl)) {
|
||||
throw new Error(
|
||||
`Esta video já foi renderizado, e se encontra na situação ${searchUrl.situation}`,
|
||||
);
|
||||
}
|
||||
|
||||
const formattedDuration = Number.isFinite(duration)
|
||||
? formatSecondsToClock(duration)
|
||||
: undefined;
|
||||
|
||||
const createData: Prisma.videosCreateInput = {
|
||||
url,
|
||||
situation: video_situation.FILA,
|
||||
};
|
||||
|
||||
if (videoid) {
|
||||
createData.videoid = videoid;
|
||||
}
|
||||
|
||||
if (title) {
|
||||
createData.title = title;
|
||||
}
|
||||
|
||||
if (formattedDuration) {
|
||||
createData.duration = formattedDuration;
|
||||
}
|
||||
|
||||
if (typeof timestamp === 'number' && Number.isFinite(timestamp)) {
|
||||
createData.datetime_download = new Date(timestamp * 1000);
|
||||
}
|
||||
|
||||
await this.prisma.videos.create({
|
||||
data: createData,
|
||||
});
|
||||
|
||||
// const params = {
|
||||
// url,
|
||||
// videoid,
|
||||
// qualidade: qualidade === 'automatic' ? 'medium' : qualidade,
|
||||
// };
|
||||
|
||||
// await axios.get(`${N8N_REMOTE_SERVER}/webhook/download-video`, {
|
||||
// params,
|
||||
// });
|
||||
}
|
||||
|
||||
async update(id: number, data: Prisma.videosUpdateInput): Promise<videos> {
|
||||
|
||||
Reference in New Issue
Block a user