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:
parent
5ec9171ddf
commit
c3c94c1709
@ -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)) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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]';
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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';
|
||||
|
@ -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');
|
||||
|
@ -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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user