Add - Classe Gemini, endpoint de criacao de video
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { OllamaService } from './ollama.service';
|
||||
import { ChatDto } from './dto/chat.dto';
|
||||
|
||||
@Controller('ollama')
|
||||
export class OllamaController {
|
||||
constructor(private readonly ollamaService: OllamaService) {}
|
||||
|
||||
@Get('models')
|
||||
public async getModels(
|
||||
@Query('onlyChats') { onlyChats }: { onlyChats: boolean },
|
||||
) {
|
||||
return await this.ollamaService.getModels({ onlyChats });
|
||||
}
|
||||
|
||||
@Post('chat')
|
||||
public async chat(@Body() body: ChatDto) {
|
||||
const { message, model } = body;
|
||||
|
||||
if (!message) {
|
||||
throw new Error('O atributo message é obrigatório');
|
||||
}
|
||||
|
||||
if (!model) {
|
||||
const [defaultModel] = await this.ollamaService.getModels({
|
||||
onlyChats: true,
|
||||
});
|
||||
|
||||
if (!defaultModel) {
|
||||
throw new Error('Nenhum modelo encontrado');
|
||||
}
|
||||
|
||||
return await this.ollamaService.generateChat({
|
||||
model: defaultModel.name,
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
return await this.ollamaService.generateChat({
|
||||
model,
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { OllamaController } from './ollama.controller';
|
||||
import { OllamaService } from './ollama.service';
|
||||
|
||||
@Module({
|
||||
controllers: [OllamaController],
|
||||
providers: [OllamaService],
|
||||
})
|
||||
export class OllamaModule {}
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
|
||||
import { Transform } from 'class-transformer';
|
||||
import {
|
||||
IsEnum,
|
||||
IsInt,
|
||||
IsISO8601,
|
||||
IsArray,
|
||||
IsNumber,
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUrl,
|
||||
MaxLength,
|
||||
} from 'class-validator';
|
||||
import { video_situation } from '@root/generated/prisma';
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
export class CreateVideoDto {
|
||||
@IsOptional()
|
||||
@IsString({ message: 'Id deve ser uma string' })
|
||||
@MaxLength(244)
|
||||
id?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray({ message: 'Tags deve ser um array' })
|
||||
tags?: string[];
|
||||
|
||||
@IsUrl()
|
||||
@MaxLength(244)
|
||||
url!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(video_situation)
|
||||
situation?: video_situation;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@MaxLength(244)
|
||||
error_message?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
clips_quantity?: number;
|
||||
|
||||
@IsOptional()
|
||||
times?: unknown;
|
||||
@IsArray({ message: 'Categories deve ser um array' })
|
||||
categories?: string[];
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@@ -36,24 +37,38 @@ export class CreateVideoDto {
|
||||
title?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsUrl()
|
||||
@MaxLength(244)
|
||||
filename?: string;
|
||||
thumbnail?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@IsString({ message: 'Videoid deve ser uma string' })
|
||||
@MaxLength(244)
|
||||
videoid?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsISO8601()
|
||||
datetime_download?: string;
|
||||
@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;
|
||||
|
||||
@IsOptional()
|
||||
@IsISO8601()
|
||||
datetime_convert?: string;
|
||||
@IsString()
|
||||
@MaxLength(244)
|
||||
description?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsISO8601()
|
||||
datetime_posted?: string;
|
||||
@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;
|
||||
}
|
||||
|
||||
@@ -7,27 +7,20 @@ import {
|
||||
Body,
|
||||
Delete,
|
||||
UseGuards,
|
||||
Post,
|
||||
} from '@nestjs/common';
|
||||
import { Prisma, videos, video_situation } from 'generated/prisma';
|
||||
|
||||
import { VideosService } from './videos.service';
|
||||
import { VideoResponseDto } from './dto/video-response.dto';
|
||||
import { KeycloakAuthGuard } from '../auth/keycloak-auth.guard';
|
||||
import { Roles } from '../auth/decorator/roles.decorator';
|
||||
import { ListVideosQueryDto } from './dto/list-videos-query.dto';
|
||||
import { VideoMetadataDto } from 'src/shared/dto/video-metadata';
|
||||
import { KeycloakAuthGuard } from '@modules/auth/keycloak-auth.guard';
|
||||
import { Roles } from '@modules/auth/decorator/roles.decorator';
|
||||
import { VideoMetadataDto } from '@shared/dto/video-metadata';
|
||||
|
||||
type PaginatedResponse<T> = {
|
||||
content: T[];
|
||||
pagination: {
|
||||
page: number;
|
||||
perPage: number;
|
||||
total: number;
|
||||
totalPages: number;
|
||||
hasNext: boolean;
|
||||
hasPrev: boolean;
|
||||
};
|
||||
};
|
||||
import { ListVideosQueryDto } from './dto/list-videos-query.dto';
|
||||
import { VideoResponseDto } from './dto/video-response.dto';
|
||||
import { VideosService } from './videos.service';
|
||||
|
||||
import type { PaginatedResponse } from '@shared/types/pagination';
|
||||
import { CreateVideoDto } from './dto/create-video-dto';
|
||||
|
||||
@Controller('videos')
|
||||
@UseGuards(KeycloakAuthGuard)
|
||||
@@ -63,6 +56,12 @@ export class VideosController {
|
||||
});
|
||||
}
|
||||
|
||||
@Post()
|
||||
@Roles('user', 'admin')
|
||||
async create(@Body() body: CreateVideoDto): Promise<void> {
|
||||
await this.videosService.createNewVideo(body);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
async get(@Param('id') id: string): Promise<videos | null> {
|
||||
return this.videosService.get(Number(id));
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import axios from 'axios';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
|
||||
@@ -9,6 +11,7 @@ import { VideoResponseDto } from './dto/video-response.dto';
|
||||
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';
|
||||
|
||||
@Injectable()
|
||||
export class VideosService {
|
||||
@@ -133,6 +136,20 @@ export class VideosService {
|
||||
}
|
||||
}
|
||||
|
||||
async createNewVideo(data: CreateVideoDto): Promise<void> {
|
||||
const { url, videoid } = data;
|
||||
|
||||
const searchUrl = await this.prisma.videos.findFirst({
|
||||
where: { url, videoid },
|
||||
});
|
||||
|
||||
if (!isEmpty(searchUrl)) {
|
||||
throw new Error(
|
||||
`Esta video já foi renderizado, e se encontra na situação ${searchUrl.situation}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async update(id: number, data: Prisma.videosUpdateInput): Promise<videos> {
|
||||
return this.prisma.videos.update({
|
||||
where: { id },
|
||||
|
||||
Reference in New Issue
Block a user