import { Inject, Injectable } from '@nestjs/common'; import { fstat, readFileSync } from 'fs'; import { join } from 'path'; import { fileURLToPath } from 'url'; import path from 'path'; import fs from 'fs-extra'; import { ImageProperty } from '../models/main.model.js'; import sharp from 'sharp'; import { WINSTON_MODULE_PROVIDER } from 'nest-winston'; import { Logger } from 'winston'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @Injectable() export class FileService { private subscriptions: any; constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) { this.loadSubscriptions(); fs.ensureDirSync(`./pictures`); fs.ensureDirSync(`./pictures/profile`); fs.ensureDirSync(`./pictures/logo`); fs.ensureDirSync(`./pictures/property`); } private loadSubscriptions(): void { const filePath = join(__dirname, '..', 'assets', 'subscriptions.json'); const rawData = readFileSync(filePath, 'utf8'); this.subscriptions = JSON.parse(rawData); } getSubscriptions() { return this.subscriptions } async storeProfilePicture(file: Express.Multer.File, userId: string) { let quality = 50; const output = await sharp(file.buffer) .resize({ width: 300 }) .avif({ quality }) // Verwende AVIF //.webp({ quality }) // Verwende Webp .toBuffer(); await sharp(output).toFile(`./pictures/profile/${userId}.avif`); } hasProfile(userId: string){ return fs.existsSync(`./pictures/profile/${userId}.avif`) } async storeCompanyLogo(file: Express.Multer.File, userId: string) { let quality = 50; const output = await sharp(file.buffer) .resize({ width: 300 }) .avif({ quality }) // Verwende AVIF //.webp({ quality }) // Verwende Webp .toBuffer(); await sharp(output).toFile(`./pictures/logo/${userId}.avif`); // Ersetze Dateierweiterung // await fs.outputFile(`./pictures/logo/${userId}`, file.buffer); } hasCompanyLogo(userId: string){ return fs.existsSync(`./pictures/logo/${userId}.avif`) } async getPropertyImages(listingId: string): Promise { const result: ImageProperty[] = [] const directory = `./pictures/property/${listingId}` if (fs.existsSync(directory)) { const files = await fs.readdir(directory); files.forEach(f => { const image: ImageProperty = { name: f, id: '', code: '' }; result.push(image) }) return result; } else { return [] } } async hasPropertyImages(listingId: string): Promise { const result: ImageProperty[] = [] const directory = `./pictures/property/${listingId}` if (fs.existsSync(directory)) { const files = await fs.readdir(directory); return files.length>0 } else { return false } } async storePropertyPicture(file: Express.Multer.File, listingId: string) { const suffix = file.mimetype.includes('png') ? 'png' : 'jpg' const directory = `./pictures/property/${listingId}` fs.ensureDirSync(`${directory}`); const imageName = await this.getNextImageName(directory); //await fs.outputFile(`${directory}/${imageName}`, file.buffer); await this.resizeImageToAVIF(file.buffer,150 * 1024,imageName,directory); } async getNextImageName(directory) { try { const files = await fs.readdir(directory); const imageNumbers = files .map(file => parseInt(file, 10)) // Dateinamen direkt in Zahlen umwandeln .filter(number => !isNaN(number)) // Sicherstellen, dass die Konvertierung gültig ist .sort((a, b) => a - b); // Aufsteigend sortieren const nextNumber = imageNumbers.length > 0 ? Math.max(...imageNumbers) + 1 : 1; return `${nextNumber}`; // Keine Endung für den Dateinamen } catch (error) { console.error('Fehler beim Lesen des Verzeichnisses:', error); return null; } } async resizeImageToAVIF(buffer: Buffer, maxSize: number,imageName:string,directory:string) { let quality = 50; // AVIF kann mit niedrigeren Qualitätsstufen gute Ergebnisse erzielen let output; let start = Date.now(); output = await sharp(buffer) .resize({ width: 1500 }) .avif({ quality }) // Verwende AVIF //.webp({ quality }) // Verwende Webp .toBuffer(); await sharp(output).toFile(`${directory}/${imageName}.avif`); // Ersetze Dateierweiterung let timeTaken = Date.now() - start; this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`) } getProfileImagesForUsers(userids:string){ const ids = userids.split(','); let result = {}; for (const id of ids){ result = {...result,[id]:fs.existsSync(`./pictures/profile/${id}.avif`)} } return result; } getCompanyLogosForUsers(userids:string){ const ids = userids.split(','); let result = {}; for (const id of ids){ result = {...result,[id]:fs.existsSync(`./pictures/logo/${id}.avif`)} } return result; } deleteImage(path:string){ fs.unlinkSync(path); } }