1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

replacing flat thumbnail path to shadow original folder hierarchy

preparing tmp folder clean-up task
This commit is contained in:
Patrik J. Braun 2019-12-24 12:44:38 +01:00
parent 5ec9171ddf
commit c3c94c1709
10 changed files with 37 additions and 33 deletions

View File

@ -7,6 +7,7 @@ class ProjectPathClass {
public ImageFolder: string;
public ThumbnailFolder: string;
public TranscodedFolder: string;
public FacesFolder: string;
public FrontendFolder: string;
constructor() {
@ -31,6 +32,7 @@ class ProjectPathClass {
this.ImageFolder = this.getAbsolutePath(Config.Server.Media.folder);
this.ThumbnailFolder = this.getAbsolutePath(Config.Server.Media.tempFolder);
this.TranscodedFolder = path.join(this.ThumbnailFolder, 'tc');
this.FacesFolder = path.join(this.ThumbnailFolder, 'f');
// create thumbnail folder if not exist
if (!fs.existsSync(this.ThumbnailFolder)) {

View File

@ -15,7 +15,7 @@ export class PhotoConverterMWs {
}
const fullMediaPath = req.resultPipe;
const convertedVideo = PhotoProcessing.generateConvertedFileName(fullMediaPath);
const convertedVideo = PhotoProcessing.generateConvertedFilePath(fullMediaPath);
// check if transcoded video exist
if (fs.existsSync(convertedVideo) === true) {

View File

@ -6,7 +6,7 @@ import {ContentWrapper} from '../../../common/entities/ConentWrapper';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
import {ProjectPath} from '../../ProjectPath';
import {Config} from '../../../common/config/private/Config';
import {ThumbnailSourceType} from '../../model/threading/ThumbnailWorker';
import {ThumbnailSourceType} from '../../model/threading/PhotoWorker';
import {MediaDTO} from '../../../common/entities/MediaDTO';
import {PersonWithPhoto} from '../PersonMWs';
import {PhotoProcessing} from '../../model/fileprocessing/PhotoProcessing';
@ -56,8 +56,7 @@ export class ThumbnailGeneratorMWs {
persons[i].samplePhoto.directory.name, persons[i].samplePhoto.name);
// generate thumbnail path
const thPath = path.join(ProjectPath.ThumbnailFolder,
PhotoProcessing.generatePersonThumbnailName(mediaPath, persons[i].samplePhoto.metadata.faces[0], size));
const thPath = PhotoProcessing.generatePersonThumbnailPath(mediaPath, persons[i].samplePhoto.metadata.faces[0], size);
persons[i].readyThumbnail = fs.existsSync(thPath);
}
@ -151,7 +150,7 @@ export class ThumbnailGeneratorMWs {
const fullMediaPath = path.join(ProjectPath.ImageFolder, photos[i].directory.path, photos[i].directory.name, photos[i].name);
for (let j = 0; j < Config.Client.Media.Thumbnail.thumbnailSizes.length; j++) {
const size = Config.Client.Media.Thumbnail.thumbnailSizes[j];
const thPath = path.join(thumbnailFolder, PhotoProcessing.generateThumbnailName(fullMediaPath, size));
const thPath = PhotoProcessing.generateThumbnailPath(fullMediaPath, size);
if (fs.existsSync(thPath) === true) {
if (typeof photos[i].readyThumbnails === 'undefined') {
photos[i].readyThumbnails = [];
@ -159,8 +158,7 @@ export class ThumbnailGeneratorMWs {
photos[i].readyThumbnails.push(size);
}
}
const iconPath = path.join(thumbnailFolder,
PhotoProcessing.generateThumbnailName(fullMediaPath, Config.Client.Media.Thumbnail.iconSize));
const iconPath = PhotoProcessing.generateThumbnailPath(fullMediaPath, Config.Client.Media.Thumbnail.iconSize);
if (fs.existsSync(iconPath) === true) {
photos[i].readyIcon = true;
}

View File

@ -5,7 +5,7 @@ import * as crypto from 'crypto';
import {ProjectPath} from '../../ProjectPath';
import {Config} from '../../../common/config/private/Config';
import {ThumbnailTH} from '../threading/ThreadPool';
import {RendererInput, ThumbnailSourceType, ThumbnailWorker} from '../threading/ThumbnailWorker';
import {PhotoWorker, RendererInput, ThumbnailSourceType} from '../threading/PhotoWorker';
import {ITaskExecuter, TaskExecuter} from '../threading/TaskExecuter';
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
import {FaceRegion, PhotoDTO} from '../../../common/entities/PhotoDTO';
@ -37,7 +37,7 @@ export class PhotoProcessing {
this.taskQue = new ThumbnailTH(Config.Client.Media.Thumbnail.concurrentThumbnailGenerations);
} else {
this.taskQue = new TaskExecuter(Config.Client.Media.Thumbnail.concurrentThumbnailGenerations,
(input => ThumbnailWorker.render(input, Config.Server.Media.photoProcessingLibrary)));
(input => PhotoWorker.render(input, Config.Server.Media.photoProcessingLibrary)));
}
this.initDone = true;
@ -56,8 +56,7 @@ export class PhotoProcessing {
const mediaPath = path.join(ProjectPath.ImageFolder, photo.directory.path, photo.directory.name, photo.name);
const size: number = Config.Client.Media.Thumbnail.personThumbnailSize;
// generate thumbnail path
const thPath = path.join(ProjectPath.ThumbnailFolder,
PhotoProcessing.generatePersonThumbnailName(mediaPath, photo.metadata.faces[0], size));
const thPath = PhotoProcessing.generatePersonThumbnailPath(mediaPath, photo.metadata.faces[0], size);
// check if thumbnail already exist
@ -95,17 +94,22 @@ export class PhotoProcessing {
}
public static generateThumbnailName(mediaPath: string, size: number): string {
return crypto.createHash('md5').update(mediaPath).digest('hex') + '_' + size + '.jpg';
public static generateThumbnailPath(mediaPath: string, size: number): string {
const extension = path.extname(mediaPath);
const file = path.basename(mediaPath, extension);
return path.join(ProjectPath.TranscodedFolder,
ProjectPath.getRelativePathToImages(path.dirname(mediaPath)), file +
'_' + size + '.jpg');
}
public static generatePersonThumbnailName(mediaPath: string, faceRegion: FaceRegion, size: number): string {
return crypto.createHash('md5').update(mediaPath + '_' + faceRegion.name + '_' + faceRegion.box.left + '_' + faceRegion.box.top)
.digest('hex') + '_' + size + '.jpg';
public static generatePersonThumbnailPath(mediaPath: string, faceRegion: FaceRegion, size: number): string {
return path.join(ProjectPath.FacesFolder,
crypto.createHash('md5').update(mediaPath + '_' + faceRegion.name + '_' + faceRegion.box.left + '_' + faceRegion.box.top)
.digest('hex') + '_' + size + '.jpg');
}
public static generateConvertedFileName(photoPath: string): string {
public static generateConvertedFilePath(photoPath: string): string {
const extension = path.extname(photoPath);
const file = path.basename(photoPath, extension);
const postfix = Config.Server.Media.Photo.Converting.resolution;
@ -117,7 +121,7 @@ export class PhotoProcessing {
public static async convertPhoto(mediaPath: string, size: number) {
// generate thumbnail path
const outPath = PhotoProcessing.generateConvertedFileName(mediaPath);
const outPath = PhotoProcessing.generateConvertedFilePath(mediaPath);
// check if file already exist
@ -149,7 +153,7 @@ export class PhotoProcessing {
sourceType: ThumbnailSourceType,
makeSquare: boolean) {
// generate thumbnail path
const outPath = path.join(ProjectPath.ThumbnailFolder, PhotoProcessing.generateThumbnailName(mediaPath, size));
const outPath = PhotoProcessing.generateThumbnailPath(mediaPath, size);
// check if thumbnail already exist

View File

@ -31,7 +31,7 @@ export class PhotoConvertingJob extends FileJob<string> {
directory.media[i].directory.name,
directory.media[i].name);
if (await existsPr(PhotoProcessing.generateConvertedFileName(photoPath)) === false) {
if (await existsPr(PhotoProcessing.generateConvertedFilePath(photoPath)) === false) {
ret.push(photoPath);
}
}

View File

@ -7,7 +7,7 @@ import * as util from 'util';
import {FileJob} from './FileJob';
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
import {PhotoProcessing} from '../../fileprocessing/PhotoProcessing';
import {ThumbnailSourceType} from '../../threading/ThumbnailWorker';
import {ThumbnailSourceType} from '../../threading/PhotoWorker';
import {MediaDTO} from '../../../../common/entities/MediaDTO';
const LOG_TAG = '[ThumbnailGenerationJob]';

View File

@ -5,7 +5,7 @@ import {FfmpegCommand, FfprobeData} from 'fluent-ffmpeg';
import {FFmpegFactory} from '../FFmpegFactory';
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
export class ThumbnailWorker {
export class PhotoWorker {
private static imageRenderer: (input: RendererInput) => Promise<void> = null;
private static videoRenderer: (input: RendererInput) => Promise<void> = null;
@ -19,19 +19,19 @@ export class ThumbnailWorker {
}
public static renderFromImage(input: RendererInput, renderer: ServerConfig.PhotoProcessingLib): Promise<void> {
if (ThumbnailWorker.rendererType !== renderer) {
ThumbnailWorker.imageRenderer = ImageRendererFactory.build(renderer);
ThumbnailWorker.rendererType = renderer;
if (PhotoWorker.rendererType !== renderer) {
PhotoWorker.imageRenderer = ImageRendererFactory.build(renderer);
PhotoWorker.rendererType = renderer;
}
return ThumbnailWorker.imageRenderer(input);
return PhotoWorker.imageRenderer(input);
}
public static renderFromVideo(input: RendererInput): Promise<void> {
if (ThumbnailWorker.videoRenderer === null) {
ThumbnailWorker.videoRenderer = VideoRendererFactory.build();
if (PhotoWorker.videoRenderer === null) {
PhotoWorker.videoRenderer = VideoRendererFactory.build();
}
return ThumbnailWorker.videoRenderer(input);
return PhotoWorker.videoRenderer(input);
}
}

View File

@ -2,7 +2,7 @@ import * as cluster from 'cluster';
import {Logger} from '../../Logger';
import {DiskManagerTask, ThumbnailTask, WorkerMessage, WorkerTask, WorkerTaskTypes} from './Worker';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
import {RendererInput} from './ThumbnailWorker';
import {RendererInput} from './PhotoWorker';
import {Config} from '../../../common/config/private/Config';
import {TaskQue, TaskQueEntry} from './TaskQue';
import {ITaskExecuter} from './TaskExecuter';

View File

@ -1,6 +1,6 @@
import {DiskMangerWorker} from './DiskMangerWorker';
import {Logger} from '../../Logger';
import {RendererInput, ThumbnailWorker} from './ThumbnailWorker';
import {RendererInput, PhotoWorker} from './PhotoWorker';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
import {Utils} from '../../../common/Utils';
import {ServerConfig} from '../../../common/config/private/IPrivateConfig';
@ -22,7 +22,7 @@ export class Worker {
}
break;
case WorkerTaskTypes.thumbnail:
result = await ThumbnailWorker.render((<ThumbnailTask>task).input, (<ThumbnailTask>task).renderer);
result = await PhotoWorker.render((<ThumbnailTask>task).input, (<ThumbnailTask>task).renderer);
break;
default:
throw new Error('Unknown worker task type');

View File

@ -4,7 +4,7 @@ import {GalleryMWs} from '../middlewares/GalleryMWs';
import {RenderingMWs} from '../middlewares/RenderingMWs';
import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
import {UserRoles} from '../../common/entities/UserDTO';
import {ThumbnailSourceType} from '../model/threading/ThumbnailWorker';
import {ThumbnailSourceType} from '../model/threading/PhotoWorker';
import {VersionMWs} from '../middlewares/VersionMWs';
import {SupportedFormats} from '../../common/SupportedFormats';
import {PhotoConverterMWs} from '../middlewares/thumbnail/PhotoConverterMWs';