mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-22 23:33:09 +02:00
upd: introduce a separate ./cache dir and cache video thumbnails there
This commit is contained in:
parent
bc24e6a294
commit
a3c302e756
4 changed files with 41 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -54,6 +54,7 @@ api-docs.json
|
|||
*.code-workspace
|
||||
.DS_Store
|
||||
/files
|
||||
/cache
|
||||
ormconfig.json
|
||||
temp
|
||||
/packages/frontend/src/**/*.stories.ts
|
||||
|
|
|
@ -20,6 +20,7 @@ services:
|
|||
- shonk
|
||||
volumes:
|
||||
- ./files:/sharkey/files
|
||||
- ./cache:/sharkey/cache
|
||||
- ./.config:/sharkey/.config:ro
|
||||
|
||||
redis:
|
||||
|
|
|
@ -16,6 +16,7 @@ const _filename = fileURLToPath(import.meta.url);
|
|||
const _dirname = dirname(_filename);
|
||||
|
||||
const path = Path.resolve(_dirname, '../../../../files');
|
||||
const cachePath = Path.resolve(_dirname, '../../../../cache');
|
||||
|
||||
@Injectable()
|
||||
export class InternalStorageService {
|
||||
|
@ -30,11 +31,26 @@ export class InternalStorageService {
|
|||
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
|
||||
public read(key: string) {
|
||||
return fs.createReadStream(this.resolvePath(key));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public readCache(key: string) {
|
||||
return fs.createReadStream(this.resolveCachePath(key));
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public saveFromPath(key: string, srcPath: string) {
|
||||
fs.mkdirSync(path, { recursive: true });
|
||||
|
@ -49,8 +65,19 @@ export class InternalStorageService {
|
|||
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
|
||||
public del(key: string) {
|
||||
fs.unlink(this.resolvePath(key), () => {});
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public delCache(key: string) {
|
||||
fs.unlink(this.resolveCachePath(key), () => {});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
import * as fs from 'node:fs';
|
||||
import * as crypto from 'node:crypto';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname } from 'node:path';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
|
@ -33,6 +34,7 @@ const _filename = fileURLToPath(import.meta.url);
|
|||
const _dirname = dirname(_filename);
|
||||
|
||||
const assets = `${_dirname}/../../server/file/assets/`;
|
||||
const cacheDir = `${_dirname}/../../../../cache/`;
|
||||
|
||||
@Injectable()
|
||||
export class FileServerService {
|
||||
|
@ -380,6 +382,14 @@ export class FileServerService {
|
|||
|
||||
@bindThis
|
||||
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);
|
||||
|
||||
if (file === '404') {
|
||||
|
@ -414,6 +424,8 @@ export class FileServerService {
|
|||
file.cleanup();
|
||||
}
|
||||
|
||||
this.internalStorageService.saveCacheFromBuffer(cacheFile, image.data);
|
||||
|
||||
reply.header('Content-Type', image.type);
|
||||
reply.header('Cache-Control', 'max-age=31536000, immutable');
|
||||
return image.data;
|
||||
|
|
Loading…
Reference in a new issue