mirror of
https://github.com/dadosfera/maestro.git
synced 2026-09-06 16:24:48 +00:00
171 lines
4.6 KiB
TypeScript
171 lines
4.6 KiB
TypeScript
import {
|
|
OnModuleInit,
|
|
Inject,
|
|
Injectable,
|
|
HttpException,
|
|
HttpStatus,
|
|
InternalServerErrorException,
|
|
} from '@nestjs/common';
|
|
|
|
import { firstValueFrom, lastValueFrom, ReplaySubject } from 'rxjs';
|
|
import { Link } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities';
|
|
import { DucClient } from '../duc/client.config';
|
|
import { ClientGrpc } from '@nestjs/microservices';
|
|
import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc';
|
|
import { CustomerUpdateRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
|
import { ThemeProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service';
|
|
import { ThemeRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages';
|
|
import { CustomerThemeRequest, CustomerThemeResponse } from './dtos/customers';
|
|
import DadosferaLogger from '@dadosfera/dadosfera-logs';
|
|
import { resolve } from 'path';
|
|
import { Readable } from 'stream';
|
|
|
|
type Files = {
|
|
logo: Express.Multer.File,
|
|
logoLogin: Express.Multer.File,
|
|
}
|
|
|
|
@Injectable()
|
|
export class ThemeService implements OnModuleInit {
|
|
private themeService: ThemeProtoService;
|
|
private logger: DadosferaLogger;
|
|
|
|
constructor(
|
|
@Inject(DucClient.name) private readonly grpcClient: ClientGrpc,
|
|
@Inject(DadosferaLogger)
|
|
dadosferaLogger: DadosferaLogger,
|
|
) {
|
|
this.logger = dadosferaLogger.logger;
|
|
}
|
|
|
|
onModuleInit() {
|
|
this.themeService = this.grpcClient.getService<ThemeProtoService>(
|
|
ProtoServices.ThemeProtoService,
|
|
);
|
|
}
|
|
|
|
async resetTheme(id: string) {
|
|
const { theme } = await firstValueFrom(
|
|
this.themeService.ResetCustomerTheme({
|
|
id
|
|
}),
|
|
);
|
|
|
|
return {
|
|
theme
|
|
}
|
|
}
|
|
|
|
async createThemeByCustomer(id: string, theme: CustomerThemeRequest & Files) {
|
|
if (!id) {
|
|
this.logger.error('Error - saveCustomertheme - not found id:' + id);
|
|
throw new HttpException(null, HttpStatus.BAD_REQUEST);
|
|
}
|
|
|
|
const customerThemeRequest$ = new ReplaySubject<ThemeRequest>();
|
|
|
|
customerThemeRequest$.next({
|
|
customerId: id,
|
|
displayName: theme.displayName,
|
|
backgroundColor: theme.backgroundColor,
|
|
textColor: theme.textColor,
|
|
isMetadata: true,
|
|
filename: '',
|
|
chunk: Buffer.alloc(0)
|
|
})
|
|
|
|
if(theme.logo) {
|
|
await this.sendFile(theme.logo, customerThemeRequest$);
|
|
}
|
|
|
|
if(theme.logoLogin) {
|
|
await this.sendFile(theme.logoLogin, customerThemeRequest$);
|
|
}
|
|
customerThemeRequest$.complete();
|
|
|
|
const stream = this.themeService.CustomerCreateTheme(customerThemeRequest$);
|
|
|
|
return lastValueFrom(stream);
|
|
}
|
|
|
|
async getThemeByCustomer(id: string): Promise<CustomerThemeResponse> {
|
|
if (!id) {
|
|
this.logger.error('Error - getCustomerTheme - not found id:' + id);
|
|
throw new HttpException(null, HttpStatus.BAD_REQUEST);
|
|
}
|
|
|
|
const { theme } = await firstValueFrom(
|
|
this.themeService.CustomerGetTheme({
|
|
id
|
|
}),
|
|
);
|
|
|
|
return {
|
|
theme
|
|
}
|
|
}
|
|
|
|
private async sendFile(file: Express.Multer.File, stream$: ReplaySubject<ThemeRequest>) {
|
|
const chunkSize = 4 * 1024 * 1024;
|
|
const bufferStream = new CustomBufferStream(file.buffer, chunkSize);
|
|
const parseMimitypeForExtension = {
|
|
'image/jpeg': '.jpeg',
|
|
'image/jpg': '.jpg',
|
|
'image/png': '.png',
|
|
'image/svg+xml': '.svg',
|
|
}
|
|
|
|
const extension = parseMimitypeForExtension[file.mimetype];
|
|
|
|
return new Promise((resolve, reject) => {
|
|
bufferStream.on('data', (chunk) => {
|
|
const filename = file.fieldname.concat(extension);
|
|
stream$.next({
|
|
customerId: '',
|
|
displayName: '',
|
|
backgroundColor: '',
|
|
textColor: '',
|
|
isMetadata: false,
|
|
filename: filename,
|
|
chunk: chunk
|
|
});
|
|
});
|
|
|
|
bufferStream.on('end', () => {
|
|
resolve(file.filename)
|
|
});
|
|
|
|
bufferStream.on('error', (err) => {
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
class CustomBufferStream extends Readable {
|
|
buffer: Buffer;
|
|
offset: number;
|
|
chunkSize: number;
|
|
|
|
constructor(buffer: Buffer, chunkSize: number) {
|
|
super({ highWaterMark: chunkSize }); // Configura o tamanho do chunk
|
|
this.buffer = buffer;
|
|
this.offset = 0;
|
|
this.chunkSize = chunkSize;
|
|
}
|
|
|
|
_read() {
|
|
if (this.offset < this.buffer.length) {
|
|
const end = Math.min(this.offset + this.chunkSize, this.buffer.length);
|
|
|
|
const copiedBuf = Uint8Array.prototype.slice.call(this.buffer);
|
|
const chunk = copiedBuf.slice(this.offset, end);
|
|
this.offset = end;
|
|
this.push(chunk);
|
|
} else {
|
|
this.push(null);
|
|
}
|
|
}
|
|
}
|