cleaned up image file repository
This commit is contained in:
parent
de893f7c40
commit
ba512c2e5b
|
@ -2,7 +2,7 @@ import { Injectable } from '@nestjs/common';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { ImageFileType } from 'picsur-shared/dist/dto/image-file-types.enum';
|
import { ImageFileType } from 'picsur-shared/dist/dto/image-file-types.enum';
|
||||||
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
|
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
|
||||||
import { In, LessThan, Repository } from 'typeorm';
|
import { LessThan, Repository } from 'typeorm';
|
||||||
import { EImageDerivativeBackend } from '../../models/entities/image-derivative.entity';
|
import { EImageDerivativeBackend } from '../../models/entities/image-derivative.entity';
|
||||||
import { EImageFileBackend } from '../../models/entities/image-file.entity';
|
import { EImageFileBackend } from '../../models/entities/image-file.entity';
|
||||||
|
|
||||||
|
@ -57,37 +57,24 @@ export class ImageFileDBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getFileMime(
|
// This is useful because you dont have to pull the whole image file
|
||||||
imageId: string,
|
|
||||||
type: ImageFileType,
|
|
||||||
): AsyncFailable<string> {
|
|
||||||
try {
|
|
||||||
const found = await this.imageFileRepo.findOne({
|
|
||||||
where: { image_id: imageId, type },
|
|
||||||
select: ['mime'],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!found) return Fail('Image not found');
|
|
||||||
return found.mime;
|
|
||||||
} catch (e) {
|
|
||||||
return Fail(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getFileMimes(
|
public async getFileMimes(
|
||||||
imageId: string,
|
imageId: string,
|
||||||
types: ImageFileType[],
|
): AsyncFailable<{ [key in ImageFileType]?: string }> {
|
||||||
): AsyncFailable<{ [key: string]: string | undefined }> {
|
|
||||||
try {
|
try {
|
||||||
const found = await this.imageFileRepo.find({
|
const found = await this.imageFileRepo.find({
|
||||||
where: { image_id: imageId, type: In(types) },
|
where: { image_id: imageId },
|
||||||
select: ['type', 'mime'],
|
select: ['type', 'mime'],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!found) return Fail('Image not found');
|
if (!found) return Fail('Image not found');
|
||||||
return Object.fromEntries(
|
|
||||||
types.map((type) => [type, found.find((f) => f.type === type)?.mime]),
|
const result: { [key in ImageFileType]?: string } = {};
|
||||||
);
|
for (const file of found) {
|
||||||
|
result[file.type] = file.mime;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return Fail(e);
|
return Fail(e);
|
||||||
}
|
}
|
||||||
|
@ -113,6 +100,7 @@ export class ImageFileDBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns null when derivative is not found
|
||||||
public async getDerivative(
|
public async getDerivative(
|
||||||
imageId: string,
|
imageId: string,
|
||||||
key: string,
|
key: string,
|
||||||
|
@ -123,6 +111,7 @@ export class ImageFileDBService {
|
||||||
});
|
});
|
||||||
if (!derivative) return null;
|
if (!derivative) return null;
|
||||||
|
|
||||||
|
// Ensure read time updated to within 1 day precision
|
||||||
const yesterday = new Date(Date.now() - A_DAY_IN_SECONDS * 1000);
|
const yesterday = new Date(Date.now() - A_DAY_IN_SECONDS * 1000);
|
||||||
if (derivative.last_read > yesterday) {
|
if (derivative.last_read > yesterday) {
|
||||||
derivative.last_read = new Date();
|
derivative.last_read = new Date();
|
||||||
|
@ -135,23 +124,6 @@ export class ImageFileDBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getDerivativeMime(
|
|
||||||
imageId: string,
|
|
||||||
key: string,
|
|
||||||
): AsyncFailable<string> {
|
|
||||||
try {
|
|
||||||
const found = await this.imageDerivativeRepo.findOne({
|
|
||||||
where: { image_id: imageId, key },
|
|
||||||
select: ['mime'],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!found) return Fail('Image not found');
|
|
||||||
return found.mime;
|
|
||||||
} catch (e) {
|
|
||||||
return Fail(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async cleanupDerivatives(
|
public async cleanupDerivatives(
|
||||||
olderThanSeconds: number,
|
olderThanSeconds: number,
|
||||||
): AsyncFailable<number> {
|
): AsyncFailable<number> {
|
||||||
|
|
|
@ -168,13 +168,14 @@ export class ImageManagerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getMasterMime(imageId: string): AsyncFailable<FullMime> {
|
public async getMasterMime(imageId: string): AsyncFailable<FullMime> {
|
||||||
const mime = await this.imageFilesService.getFileMime(
|
const mime = await this.imageFilesService.getFileMimes(
|
||||||
imageId,
|
imageId
|
||||||
ImageFileType.MASTER,
|
|
||||||
);
|
);
|
||||||
if (HasFailed(mime)) return mime;
|
if (HasFailed(mime)) return mime;
|
||||||
|
|
||||||
return ParseMime(mime);
|
if (mime.master === undefined) return Fail('No master file');
|
||||||
|
|
||||||
|
return ParseMime(mime.master);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getOriginal(imageId: string): AsyncFailable<EImageFileBackend> {
|
public async getOriginal(imageId: string): AsyncFailable<EImageFileBackend> {
|
||||||
|
@ -182,23 +183,21 @@ export class ImageManagerService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getOriginalMime(imageId: string): AsyncFailable<FullMime> {
|
public async getOriginalMime(imageId: string): AsyncFailable<FullMime> {
|
||||||
const mime = await this.imageFilesService.getFileMime(
|
const mime = await this.imageFilesService.getFileMimes(
|
||||||
imageId,
|
imageId
|
||||||
ImageFileType.ORIGINAL,
|
|
||||||
);
|
);
|
||||||
if (HasFailed(mime)) return mime;
|
if (HasFailed(mime)) return mime;
|
||||||
|
|
||||||
return ParseMime(mime);
|
if (mime.original === undefined) return Fail('No original file');
|
||||||
|
|
||||||
|
return ParseMime(mime.original);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAllFileMimes(imageId: string): AsyncFailable<{
|
public async getFileMimes(imageId: string): AsyncFailable<{
|
||||||
[ImageFileType.MASTER]: string;
|
[ImageFileType.MASTER]: string;
|
||||||
[ImageFileType.ORIGINAL]: string | undefined;
|
[ImageFileType.ORIGINAL]: string | undefined;
|
||||||
}> {
|
}> {
|
||||||
const result = await this.imageFilesService.getFileMimes(imageId, [
|
const result = await this.imageFilesService.getFileMimes(imageId);
|
||||||
ImageFileType.MASTER,
|
|
||||||
ImageFileType.ORIGINAL,
|
|
||||||
]);
|
|
||||||
if (HasFailed(result)) return result;
|
if (HasFailed(result)) return result;
|
||||||
|
|
||||||
if (result[ImageFileType.MASTER] === undefined) {
|
if (result[ImageFileType.MASTER] === undefined) {
|
||||||
|
|
|
@ -6,12 +6,12 @@ import {
|
||||||
Logger,
|
Logger,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
Query,
|
Query,
|
||||||
Res,
|
Res
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import type { FastifyReply } from 'fastify';
|
import type { FastifyReply } from 'fastify';
|
||||||
import {
|
import {
|
||||||
ImageMetaResponse,
|
ImageMetaResponse,
|
||||||
ImageRequestParams,
|
ImageRequestParams
|
||||||
} from 'picsur-shared/dist/dto/api/image.dto';
|
} from 'picsur-shared/dist/dto/api/image.dto';
|
||||||
import { HasFailed } from 'picsur-shared/dist/types';
|
import { HasFailed } from 'picsur-shared/dist/types';
|
||||||
import { UsersService } from '../../collections/user-db/user-db.service';
|
import { UsersService } from '../../collections/user-db/user-db.service';
|
||||||
|
@ -97,7 +97,7 @@ export class ImageController {
|
||||||
}
|
}
|
||||||
|
|
||||||
const [fileMimes, imageUser] = await Promise.all([
|
const [fileMimes, imageUser] = await Promise.all([
|
||||||
this.imagesService.getAllFileMimes(id),
|
this.imagesService.getFileMimes(id),
|
||||||
this.userService.findOne(image.user_id),
|
this.userService.findOne(image.user_id),
|
||||||
]);
|
]);
|
||||||
if (HasFailed(fileMimes)) {
|
if (HasFailed(fileMimes)) {
|
||||||
|
|
Loading…
Reference in a new issue