upd: introduce a separate ./cache dir and cache video thumbnails there

This commit is contained in:
ShittyKopper 2024-01-04 19:55:02 +03:00
parent bc24e6a294
commit a3c302e756
4 changed files with 41 additions and 0 deletions

1
.gitignore vendored
View file

@ -54,6 +54,7 @@ api-docs.json
*.code-workspace *.code-workspace
.DS_Store .DS_Store
/files /files
/cache
ormconfig.json ormconfig.json
temp temp
/packages/frontend/src/**/*.stories.ts /packages/frontend/src/**/*.stories.ts

View file

@ -20,6 +20,7 @@ services:
- shonk - shonk
volumes: volumes:
- ./files:/sharkey/files - ./files:/sharkey/files
- ./cache:/sharkey/cache
- ./.config:/sharkey/.config:ro - ./.config:/sharkey/.config:ro
redis: redis:

View file

@ -16,6 +16,7 @@ const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
const path = Path.resolve(_dirname, '../../../../files'); const path = Path.resolve(_dirname, '../../../../files');
const cachePath = Path.resolve(_dirname, '../../../../cache');
@Injectable() @Injectable()
export class InternalStorageService { export class InternalStorageService {
@ -30,11 +31,26 @@ export class InternalStorageService {
return Path.resolve(path, key); return Path.resolve(path, key);
} }
@bindThis
public resolveCachePath(key: string) {
return Path.resolve(cachePath, key);
}
@bindThis
public existsCache(key: string) {
return fs.existsSync(this.resolveCachePath(key));
}
@bindThis @bindThis
public read(key: string) { public read(key: string) {
return fs.createReadStream(this.resolvePath(key)); return fs.createReadStream(this.resolvePath(key));
} }
@bindThis
public readCache(key: string) {
return fs.createReadStream(this.resolveCachePath(key));
}
@bindThis @bindThis
public saveFromPath(key: string, srcPath: string) { public saveFromPath(key: string, srcPath: string) {
fs.mkdirSync(path, { recursive: true }); fs.mkdirSync(path, { recursive: true });
@ -49,8 +65,19 @@ export class InternalStorageService {
return `${this.config.url}/files/${key}`; return `${this.config.url}/files/${key}`;
} }
@bindThis
public saveCacheFromBuffer(key: string, data: Buffer) {
fs.mkdirSync(cachePath, { recursive: true });
fs.writeFileSync(this.resolveCachePath(key), data);
}
@bindThis @bindThis
public del(key: string) { public del(key: string) {
fs.unlink(this.resolvePath(key), () => {}); fs.unlink(this.resolvePath(key), () => {});
} }
@bindThis
public delCache(key: string) {
fs.unlink(this.resolveCachePath(key), () => {});
}
} }

View file

@ -4,6 +4,7 @@
*/ */
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import * as crypto from 'node:crypto';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path'; import { dirname } from 'node:path';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
@ -33,6 +34,7 @@ const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
const assets = `${_dirname}/../../server/file/assets/`; const assets = `${_dirname}/../../server/file/assets/`;
const cacheDir = `${_dirname}/../../../../cache/`;
@Injectable() @Injectable()
export class FileServerService { export class FileServerService {
@ -380,6 +382,14 @@ export class FileServerService {
@bindThis @bindThis
private async videoThumbnailHandler(request: FastifyRequest<{ Querystring: { url: string; }; }>, reply: FastifyReply) { private async videoThumbnailHandler(request: FastifyRequest<{ Querystring: { url: string; }; }>, reply: FastifyReply) {
const cacheKey = crypto.createHash('md5').update(request.query.url).digest('base64url');
const cacheFile = `videoThumbnail-${cacheKey}.webp`;
if (this.internalStorageService.existsCache(cacheFile)) {
reply.header('Content-Type', 'image/webp');
reply.header('Cache-Control', 'max-age=31536000, immutable');
return reply.sendFile(cacheFile, cacheDir);
}
const file = await this.getStreamAndTypeFromUrl(request.query.url); const file = await this.getStreamAndTypeFromUrl(request.query.url);
if (file === '404') { if (file === '404') {
@ -414,6 +424,8 @@ export class FileServerService {
file.cleanup(); file.cleanup();
} }
this.internalStorageService.saveCacheFromBuffer(cacheFile, image.data);
reply.header('Content-Type', image.type); reply.header('Content-Type', image.type);
reply.header('Cache-Control', 'max-age=31536000, immutable'); reply.header('Cache-Control', 'max-age=31536000, immutable');
return image.data; return image.data;