1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00
pigallery2/src/backend/model/threading/DiskMangerWorker.ts

190 lines
6.1 KiB
TypeScript
Raw Normal View History

2019-12-26 21:03:10 +01:00
import {promises as fsp, Stats} from 'fs';
2018-03-30 15:30:30 -04:00
import * as path from 'path';
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
2018-12-20 23:02:49 +01:00
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
2018-03-30 15:30:30 -04:00
import {ProjectPath} from '../../ProjectPath';
import {Config} from '../../../common/config/private/Config';
2018-12-20 23:02:49 +01:00
import {VideoDTO} from '../../../common/entities/VideoDTO';
2018-11-26 00:26:29 +01:00
import {FileDTO} from '../../../common/entities/FileDTO';
2018-12-20 23:02:49 +01:00
import {MetadataLoader} from './MetadataLoader';
import {Logger} from '../../Logger';
2019-12-09 17:19:28 +01:00
import {SupportedFormats} from '../../../common/SupportedFormats';
2019-12-26 21:03:10 +01:00
import {VideoProcessing} from '../fileprocessing/VideoProcessing';
import {PhotoProcessing} from '../fileprocessing/PhotoProcessing';
2018-03-30 15:30:30 -04:00
2019-12-24 12:22:25 +01:00
const LOG_TAG = '[DiskMangerWorker]';
2017-07-19 20:47:09 +02:00
export class DiskMangerWorker {
2018-11-04 19:28:32 +01:00
public static calcLastModified(stat: Stats) {
return Math.max(stat.ctime.getTime(), stat.mtime.getTime());
}
public static normalizeDirPath(dirPath: string): string {
return path.normalize(path.join('.' + path.sep, dirPath));
}
public static pathFromRelativeDirName(relativeDirectoryName: string): string {
return path.join(path.dirname(this.normalizeDirPath(relativeDirectoryName)), path.sep);
}
public static pathFromParent(parent: { path: string, name: string }): string {
return path.join(this.normalizeDirPath(path.join(parent.path, parent.name)), path.sep);
}
public static dirName(name: string) {
if (name.trim().length === 0) {
return '.';
}
return path.basename(name);
}
2019-12-26 21:03:10 +01:00
public static async excludeDir(name: string, relativeDirectoryName: string, absoluteDirectoryName: string) {
2019-12-10 14:26:16 +01:00
if (Config.Server.Indexing.excludeFolderList.length === 0 ||
Config.Server.Indexing.excludeFileList.length === 0) {
return false;
}
2019-12-07 18:26:29 +01:00
const absoluteName = path.normalize(path.join(absoluteDirectoryName, name));
const relativeName = path.normalize(path.join(relativeDirectoryName, name));
for (let j = 0; j < Config.Server.Indexing.excludeFolderList.length; j++) {
const exclude = Config.Server.Indexing.excludeFolderList[j];
if (exclude.startsWith('/')) {
2019-12-07 18:26:29 +01:00
if (exclude === absoluteName) {
return true;
}
} else if (exclude.includes('/')) {
2019-12-07 18:26:29 +01:00
if (path.normalize(exclude) === relativeName) {
return true;
}
} else {
2019-12-07 18:26:29 +01:00
if (exclude === name) {
return true;
}
}
}
2019-12-07 18:26:29 +01:00
// exclude dirs that have the given files (like .ignore)
for (let j = 0; j < Config.Server.Indexing.excludeFileList.length; j++) {
const exclude = Config.Server.Indexing.excludeFileList[j];
2019-12-26 21:03:10 +01:00
try {
await fsp.access(path.join(absoluteName, exclude));
return true;
2019-12-26 21:03:10 +01:00
} catch (e) {
}
}
return false;
}
2019-12-26 21:03:10 +01:00
public static async scanDirectory(relativeDirectoryName: string,
settings: DiskMangerWorker.DirectoryScanSettings = {}): Promise<DirectoryDTO> {
relativeDirectoryName = this.normalizeDirPath(relativeDirectoryName);
const directoryName = DiskMangerWorker.dirName(relativeDirectoryName);
const directoryParent = this.pathFromRelativeDirName(relativeDirectoryName);
const absoluteDirectoryName = path.join(ProjectPath.ImageFolder, relativeDirectoryName);
const stat = await fsp.stat(path.join(ProjectPath.ImageFolder, relativeDirectoryName));
const directory: DirectoryDTO = {
id: null,
parent: null,
name: directoryName,
path: directoryParent,
lastModified: this.calcLastModified(stat),
lastScanned: Date.now(),
directories: [],
isPartial: false,
mediaCount: 0,
media: [],
metaFile: []
};
const list = await fsp.readdir(absoluteDirectoryName);
for (let i = 0; i < list.length; i++) {
const file = list[i];
const fullFilePath = path.normalize(path.join(absoluteDirectoryName, file));
if ((await fsp.stat(fullFilePath)).isDirectory()) {
if (settings.noDirectory === true ||
await DiskMangerWorker.excludeDir(file, relativeDirectoryName, absoluteDirectoryName)) {
continue;
2017-07-19 20:47:09 +02:00
}
2019-12-26 21:03:10 +01:00
// create preview directory
const d = await DiskMangerWorker.scanDirectory(path.join(relativeDirectoryName, file),
{
maxPhotos: Config.Server.Indexing.folderPreviewSize,
noMetaFile: true,
noVideo: true,
noDirectory: true
}
);
d.lastScanned = 0; // it was not a fully scan
d.isPartial = true;
directory.directories.push(d);
} else if (PhotoProcessing.isPhoto(fullFilePath)) {
if (settings.noPhoto) {
continue;
}
directory.media.push(<PhotoDTO>{
name: file,
directory: null,
metadata: await MetadataLoader.loadPhotoMetadata(fullFilePath)
});
if (settings.maxPhotos && directory.media.length > settings.maxPhotos) {
break;
}
} else if (VideoProcessing.isVideo(fullFilePath)) {
if (Config.Client.Media.Video.enabled === false || settings.noVideo) {
continue;
}
try {
directory.media.push(<VideoDTO>{
name: file,
directory: null,
metadata: await MetadataLoader.loadVideoMetadata(fullFilePath)
});
} catch (e) {
Logger.warn('Media loading error, skipping: ' + file + ', reason: ' + e.toString());
}
2019-12-26 21:03:10 +01:00
} else if (DiskMangerWorker.isMetaFile(fullFilePath)) {
if (Config.Client.MetaFile.enabled === false || settings.noMetaFile) {
continue;
2017-07-19 20:47:09 +02:00
}
2019-12-26 21:03:10 +01:00
directory.metaFile.push(<FileDTO>{
name: file,
directory: null,
});
2017-07-19 20:47:09 +02:00
2019-12-26 21:03:10 +01:00
}
}
2017-07-19 20:47:09 +02:00
2019-12-26 21:03:10 +01:00
directory.mediaCount = directory.media.length;
2019-12-26 21:03:10 +01:00
return directory;
}
2019-12-26 21:03:10 +01:00
private static isMetaFile(fullPath: string) {
const extension = path.extname(fullPath).toLowerCase();
2019-12-09 17:19:28 +01:00
return SupportedFormats.WithDots.MetaFiles.indexOf(extension) !== -1;
}
}
export namespace DiskMangerWorker {
export interface DirectoryScanSettings {
maxPhotos?: number;
noMetaFile?: boolean;
noVideo?: boolean;
noPhoto?: boolean;
noDirectory?: boolean;
}
}