128 lines
4.5 KiB
TypeScript
128 lines
4.5 KiB
TypeScript
import { Inject, Injectable } from '@nestjs/common';
|
|
import fs from 'fs-extra';
|
|
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
|
|
import sharp from 'sharp';
|
|
import { Logger } from 'winston';
|
|
|
|
@Injectable()
|
|
export class FileService {
|
|
constructor(@Inject(WINSTON_MODULE_PROVIDER) private readonly logger: Logger) {
|
|
fs.ensureDirSync(`./pictures`);
|
|
fs.ensureDirSync(`./pictures/profile`);
|
|
fs.ensureDirSync(`./pictures/logo`);
|
|
fs.ensureDirSync(`./pictures/property`);
|
|
}
|
|
// ############
|
|
// Profile
|
|
// ############
|
|
async storeProfilePicture(file: Express.Multer.File, adjustedEmail: string) {
|
|
const 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/${adjustedEmail}.avif`);
|
|
}
|
|
hasProfile(adjustedEmail: string) {
|
|
return fs.existsSync(`./pictures/profile/${adjustedEmail}.avif`);
|
|
}
|
|
// ############
|
|
// Logo
|
|
// ############
|
|
async storeCompanyLogo(file: Express.Multer.File, adjustedEmail: string) {
|
|
const 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/${adjustedEmail}.avif`); // Ersetze Dateierweiterung
|
|
// await fs.outputFile(`./pictures/logo/${userId}`, file.buffer);
|
|
}
|
|
hasCompanyLogo(adjustedEmail: string) {
|
|
return fs.existsSync(`./pictures/logo/${adjustedEmail}.avif`) ? true : false;
|
|
}
|
|
// ############
|
|
// Property
|
|
// ############
|
|
async getPropertyImages(imagePath: string, serial: string): Promise<string[]> {
|
|
const result: string[] = [];
|
|
const directory = `./pictures/property/${imagePath}/${serial}`;
|
|
if (fs.existsSync(directory)) {
|
|
const files = await fs.readdir(directory);
|
|
files.forEach(f => {
|
|
result.push(f);
|
|
});
|
|
return result;
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
async hasPropertyImages(imagePath: string, serial: string): Promise<boolean> {
|
|
const directory = `./pictures/property/${imagePath}/${serial}`;
|
|
if (fs.existsSync(directory)) {
|
|
const files = await fs.readdir(directory);
|
|
return files.length > 0;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
async storePropertyPicture(file: Express.Multer.File, imagePath: string, serial: string): Promise<string> {
|
|
const directory = `./pictures/property/${imagePath}/${serial}`;
|
|
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);
|
|
return `${imageName}.avif`;
|
|
}
|
|
// ############
|
|
// utils
|
|
// ############
|
|
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) {
|
|
const quality = 50; // AVIF kann mit niedrigeren Qualitätsstufen gute Ergebnisse erzielen
|
|
const start = Date.now();
|
|
const 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
|
|
const timeTaken = Date.now() - start;
|
|
this.logger.info(`Quality: ${quality} - Time: ${timeTaken} milliseconds`);
|
|
}
|
|
deleteImage(path: string) {
|
|
fs.unlinkSync(path);
|
|
}
|
|
|
|
deleteDirectoryIfExists(imagePath) {
|
|
const dirPath = `pictures/property/${imagePath}`;
|
|
try {
|
|
const exists = fs.pathExistsSync();
|
|
if (exists) {
|
|
fs.removeSync(dirPath);
|
|
console.log(`Directory ${dirPath} was deleted.`);
|
|
} else {
|
|
console.log(`Directory ${dirPath} does not exist.`);
|
|
}
|
|
} catch (error) {
|
|
console.error(`Error while deleting ${dirPath}:`, error);
|
|
}
|
|
}
|
|
}
|