mirror of
https://github.com/bpatrik/pigallery2.git
synced 2025-01-04 03:49:28 +02:00
Adding preview field to Directory and populating it with any photo from subdirectory (based on #165), fixes #31
This commit is contained in:
parent
8bd04dda8c
commit
c670a17e27
@ -86,7 +86,7 @@ export class GalleryMWs {
|
||||
|
||||
if (cw.directory) {
|
||||
DirectoryDTO.removeReferences(cw.directory);
|
||||
// TODO: remove when typeorm inheritance is fixed
|
||||
// TODO: remove when typeorm inheritance is fixed (and handles proper inheritance)
|
||||
cleanUpMedia(cw.directory.media);
|
||||
}
|
||||
if (cw.searchResult) {
|
||||
|
@ -31,6 +31,7 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'error during postprocessing result (adding thumbnail info)', error.toString()));
|
||||
|
||||
}
|
||||
@ -62,7 +63,8 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'error during postprocessing result (adding thumbnail info)', error.toString()));
|
||||
return next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'error during postprocessing result (adding thumbnail info for persons)',
|
||||
error.toString()));
|
||||
|
||||
}
|
||||
|
||||
@ -139,6 +141,9 @@ export class ThumbnailGeneratorMWs {
|
||||
if (typeof directory.media !== 'undefined') {
|
||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.media);
|
||||
}
|
||||
if (directory.preview) {
|
||||
ThumbnailGeneratorMWs.addThInfoToAPhoto(directory.preview);
|
||||
}
|
||||
if (typeof directory.directories !== 'undefined') {
|
||||
for (let i = 0; i < directory.directories.length; i++) {
|
||||
ThumbnailGeneratorMWs.addThInfoTODir(directory.directories[i]);
|
||||
@ -148,22 +153,27 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
private static addThInfoToPhotos(photos: MediaDTO[]) {
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
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 = PhotoProcessing.generateConvertedPath(fullMediaPath, size);
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
if (typeof photos[i].readyThumbnails === 'undefined') {
|
||||
photos[i].readyThumbnails = [];
|
||||
}
|
||||
photos[i].readyThumbnails.push(size);
|
||||
this.addThInfoToAPhoto(photos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static addThInfoToAPhoto(photo: MediaDTO) {
|
||||
const fullMediaPath = path.join(ProjectPath.ImageFolder, photo.directory.path, photo.directory.name, photo.name);
|
||||
for (let j = 0; j < Config.Client.Media.Thumbnail.thumbnailSizes.length; j++) {
|
||||
const size = Config.Client.Media.Thumbnail.thumbnailSizes[j];
|
||||
const thPath = PhotoProcessing.generateConvertedPath(fullMediaPath, size);
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
if (typeof photo.readyThumbnails === 'undefined') {
|
||||
photo.readyThumbnails = [];
|
||||
}
|
||||
}
|
||||
const iconPath = PhotoProcessing.generateConvertedPath(fullMediaPath, Config.Client.Media.Thumbnail.iconSize);
|
||||
if (fs.existsSync(iconPath) === true) {
|
||||
photos[i].readyIcon = true;
|
||||
photo.readyThumbnails.push(size);
|
||||
}
|
||||
}
|
||||
const iconPath = PhotoProcessing.generateConvertedPath(fullMediaPath, Config.Client.Media.Thumbnail.iconSize);
|
||||
if (fs.existsSync(iconPath) === true) {
|
||||
photo.readyIcon = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,15 +36,7 @@ export class DiskManager {
|
||||
} else {
|
||||
directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName, settings);
|
||||
}
|
||||
const addDirs = (dir: DirectoryDTO) => {
|
||||
dir.media.forEach((ph) => {
|
||||
ph.directory = dir;
|
||||
});
|
||||
dir.directories.forEach((d) => {
|
||||
addDirs(d);
|
||||
});
|
||||
};
|
||||
addDirs(directory);
|
||||
DirectoryDTO.addReferences(directory);
|
||||
return directory;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,6 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
|
||||
}
|
||||
|
||||
|
||||
async countDirectories(): Promise<number> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
return await connection.getRepository(DirectoryEntity)
|
||||
@ -103,7 +102,6 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
return sum || 0;
|
||||
}
|
||||
|
||||
|
||||
async countPhotos(): Promise<number> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
return await connection.getRepository(PhotoEntity)
|
||||
@ -238,38 +236,32 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
}
|
||||
if (dir.directories) {
|
||||
for (let i = 0; i < dir.directories.length; i++) {
|
||||
const dirName = GalleryManager.getAbsoluteDirName(dir.directories[i]);
|
||||
dir.directories[i].media = await connection
|
||||
|
||||
const _path = dir.path;
|
||||
const currentRoot = (_path === './' ? '' : _path);
|
||||
const dirName = currentRoot + dir.name + path.sep;
|
||||
dir.directories[i].media = [];
|
||||
dir.directories[i].preview = await connection
|
||||
.getRepository(MediaEntity)
|
||||
.createQueryBuilder('media')
|
||||
.innerJoinAndSelect('media.directory', 'directory')
|
||||
.where('media.directory = :dir', {
|
||||
dir: dir.directories[i].id
|
||||
})
|
||||
.orWhere("directory.path like :parentPath||'%'", {
|
||||
parentPath: dirName
|
||||
.orWhere('directory.path like :parentPath||\'%\'', {
|
||||
parentPath: dirName
|
||||
})
|
||||
.orderBy('media.metadata.creationDate', 'DESC')
|
||||
.limit(Config.Server.Indexing.folderPreviewSize)
|
||||
.getMany();
|
||||
.limit(1)
|
||||
.getOne();
|
||||
dir.directories[i].isPartial = true;
|
||||
|
||||
const dirs = dir.directories[i]
|
||||
for (let j = 0; j < dirs.media.length; j++) {
|
||||
const mediaDirName = GalleryManager.getAbsoluteDirName(dirs.media[j].directory);
|
||||
const name = mediaDirName.substring(dirName.length);
|
||||
dir.directories[i].media[j].name = name + dir.directories[i].media[j].name
|
||||
dir.directories[i].media[j].directory = dir.directories[i];
|
||||
dir.directories[i].media[j].readyThumbnails = [];
|
||||
dir.directories[i].media[j].readyIcon = false;
|
||||
if (dir.directories[i].preview) {
|
||||
dir.directories[i].preview.directory = dir.directories[i];
|
||||
dir.directories[i].preview.readyThumbnails = [];
|
||||
dir.directories[i].preview.readyIcon = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static getAbsoluteDirName(dir: DirectoryEntity) {
|
||||
const path = dir.path;
|
||||
const currentRoot = (path === "./" ? "" : path) ;
|
||||
return currentRoot + dir.name + "/";
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,9 @@ export class IndexingManager implements IIndexingManager {
|
||||
const scannedDirectory = await DiskManager.scanDirectory(relativeDirectoryName);
|
||||
|
||||
// returning with the result
|
||||
if (scannedDirectory.preview) {
|
||||
scannedDirectory.preview.readyThumbnails = [];
|
||||
}
|
||||
scannedDirectory.media.forEach(p => p.readyThumbnails = []);
|
||||
resolve(scannedDirectory);
|
||||
|
||||
|
@ -54,6 +54,8 @@ export class DirectoryEntity implements DirectoryDTO {
|
||||
@OneToMany(type => DirectoryEntity, dir => dir.parent)
|
||||
public directories: DirectoryEntity[];
|
||||
|
||||
public preview: MediaEntity;
|
||||
|
||||
@OneToMany(type => MediaEntity, media => media.directory)
|
||||
public media: MediaEntity[];
|
||||
|
||||
|
@ -104,6 +104,7 @@ export class DiskMangerWorker {
|
||||
directories: [],
|
||||
isPartial: false,
|
||||
mediaCount: 0,
|
||||
preview: null,
|
||||
media: [],
|
||||
metaFile: []
|
||||
};
|
||||
@ -117,7 +118,7 @@ export class DiskMangerWorker {
|
||||
const file = list[i];
|
||||
const fullFilePath = path.normalize(path.join(absoluteDirectoryName, file));
|
||||
if ((await fsp.stat(fullFilePath)).isDirectory()) {
|
||||
if (settings.noDirectory === true ||
|
||||
if (settings.noDirectory === true || settings.previewOnly === true ||
|
||||
await DiskMangerWorker.excludeDir(file, relativeDirectoryName, absoluteDirectoryName)) {
|
||||
continue;
|
||||
}
|
||||
@ -125,11 +126,7 @@ export class DiskMangerWorker {
|
||||
// create preview directory
|
||||
const d = await DiskMangerWorker.scanDirectory(path.join(relativeDirectoryName, file),
|
||||
{
|
||||
maxPhotos: Config.Server.Indexing.folderPreviewSize,
|
||||
noMetaFile: true,
|
||||
noVideo: true,
|
||||
noDirectory: true,
|
||||
noPhoto: settings.noChildDirPhotos || settings.noPhoto
|
||||
previewOnly: true
|
||||
}
|
||||
);
|
||||
|
||||
@ -141,18 +138,23 @@ export class DiskMangerWorker {
|
||||
if (settings.noPhoto === true) {
|
||||
continue;
|
||||
}
|
||||
directory.media.push(<PhotoDTO>{
|
||||
|
||||
const photo = <PhotoDTO>{
|
||||
name: file,
|
||||
directory: null,
|
||||
metadata: settings.noMetadata === true ? null : await MetadataLoader.loadPhotoMetadata(fullFilePath)
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
if (settings.maxPhotos && directory.media.length > settings.maxPhotos) {
|
||||
if (!directory.preview) {
|
||||
directory.preview = photo;
|
||||
}
|
||||
if (settings.previewOnly === true) {
|
||||
break;
|
||||
}
|
||||
directory.media.push(photo);
|
||||
|
||||
} else if (VideoProcessing.isVideo(fullFilePath)) {
|
||||
if (Config.Client.Media.Video.enabled === false || settings.noVideo === true) {
|
||||
if (Config.Client.Media.Video.enabled === false || settings.noVideo === true || settings.previewOnly === true) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
@ -166,7 +168,7 @@ export class DiskMangerWorker {
|
||||
}
|
||||
|
||||
} else if (DiskMangerWorker.isMetaFile(fullFilePath)) {
|
||||
if (Config.Client.MetaFile.enabled === false || settings.noMetaFile === true) {
|
||||
if (Config.Client.MetaFile.enabled === false || settings.noMetaFile === true || settings.previewOnly === true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -193,7 +195,7 @@ export class DiskMangerWorker {
|
||||
|
||||
export namespace DiskMangerWorker {
|
||||
export interface DirectoryScanSettings {
|
||||
maxPhotos?: number;
|
||||
previewOnly?: boolean;
|
||||
noMetaFile?: boolean;
|
||||
noVideo?: boolean;
|
||||
noPhoto?: boolean;
|
||||
|
@ -96,8 +96,6 @@ export module ServerConfig {
|
||||
|
||||
@SubConfigClass()
|
||||
export class IndexingConfig {
|
||||
@ConfigProperty()
|
||||
folderPreviewSize: number = 2;
|
||||
@ConfigProperty()
|
||||
cachedFolderTimeout: number = 1000 * 60 * 60; // Do not rescans the folder if seems ok
|
||||
@ConfigProperty({type: ReIndexingSensitivity})
|
||||
|
@ -12,6 +12,7 @@ export interface DirectoryDTO<S extends FileDTO = MediaDTO> {
|
||||
parent: DirectoryDTO<S>;
|
||||
mediaCount: number;
|
||||
directories: DirectoryDTO<S>[];
|
||||
preview: S;
|
||||
media: S[];
|
||||
metaFile: FileDTO[];
|
||||
}
|
||||
@ -22,6 +23,9 @@ export module DirectoryDTO {
|
||||
media.directory = dir;
|
||||
});
|
||||
|
||||
if (dir.preview) {
|
||||
dir.preview.directory = dir;
|
||||
}
|
||||
if (dir.metaFile) {
|
||||
dir.metaFile.forEach((file: FileDTO) => {
|
||||
file.directory = dir;
|
||||
@ -42,6 +46,9 @@ export module DirectoryDTO {
|
||||
media.directory = null;
|
||||
});
|
||||
}
|
||||
if (dir.preview) {
|
||||
dir.preview.directory = null;
|
||||
}
|
||||
if (dir.metaFile) {
|
||||
dir.metaFile.forEach((file: FileDTO) => {
|
||||
file.directory = null;
|
||||
|
@ -28,10 +28,7 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
public get SamplePhoto(): MediaDTO {
|
||||
if (this.directory.media.length > 0) {
|
||||
return this.directory.media[0];
|
||||
}
|
||||
return null;
|
||||
return this.directory.preview;
|
||||
}
|
||||
|
||||
getSanitizedThUrl() {
|
||||
@ -59,7 +56,7 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.directory.media.length > 0) {
|
||||
if (this.directory.preview) {
|
||||
this.thumbnail = this.thumbnailService.getThumbnail(new Media(this.SamplePhoto, this.size, this.size));
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,6 @@
|
||||
required="true">
|
||||
</app-settings-entry>
|
||||
|
||||
<app-settings-entry
|
||||
name="Sub folder preview size"
|
||||
description="Reads this many photos from sub folders."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.folderPreviewSize"
|
||||
required="true">
|
||||
</app-settings-entry>
|
||||
|
||||
|
||||
<app-settings-entry
|
||||
name="Folder reindexing sensitivity"
|
||||
|
@ -68,6 +68,9 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
dir.media.forEach((media: MediaDTO) => {
|
||||
delete media.id;
|
||||
});
|
||||
if (dir.preview) {
|
||||
delete dir.preview.id;
|
||||
}
|
||||
if (dir.metaFile) {
|
||||
if (dir.metaFile.length === 0) {
|
||||
delete dir.metaFile;
|
||||
@ -128,12 +131,16 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir1.preview = subDir1.media[0];
|
||||
subDir1.isPartial = true;
|
||||
delete subDir1.directories;
|
||||
delete subDir1.metaFile;
|
||||
delete subDir1.media;
|
||||
subDir2.preview = subDir2.media[0];
|
||||
subDir2.isPartial = true;
|
||||
delete subDir2.directories;
|
||||
delete subDir2.metaFile;
|
||||
delete subDir2.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent)));
|
||||
});
|
||||
@ -163,8 +170,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir1.isPartial = true;
|
||||
subDir1.preview = subDir1.media[0];
|
||||
delete subDir1.directories;
|
||||
delete subDir1.metaFile;
|
||||
delete subDir1.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent1)));
|
||||
}
|
||||
@ -175,8 +184,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir2.isPartial = true;
|
||||
subDir2.preview = subDir2.media[0];
|
||||
delete subDir2.directories;
|
||||
delete subDir2.metaFile;
|
||||
delete subDir2.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent2)));
|
||||
}
|
||||
@ -212,8 +223,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir.isPartial = true;
|
||||
subDir.preview = subDir.media[0];
|
||||
delete subDir.directories;
|
||||
delete subDir.metaFile;
|
||||
delete subDir.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent)));
|
||||
});
|
||||
@ -248,8 +261,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir.isPartial = true;
|
||||
subDir.preview = subDir.media[0];
|
||||
delete subDir.directories;
|
||||
delete subDir.metaFile;
|
||||
delete subDir.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent)));
|
||||
});
|
||||
@ -277,8 +292,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir.isPartial = true;
|
||||
subDir.preview = subDir.media[0];
|
||||
delete subDir.directories;
|
||||
delete subDir.metaFile;
|
||||
delete subDir.media;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
.to.deep.equal(Utils.clone(Utils.removeNullOrEmptyObj(parent)));
|
||||
});
|
||||
@ -405,8 +422,10 @@ describe('IndexingManager', (sqlHelper: SQLTestHelper) => {
|
||||
DirectoryDTO.removeReferences(selected);
|
||||
removeIds(selected);
|
||||
subDir.isPartial = true;
|
||||
subDir.preview = subDir.media[0];
|
||||
delete subDir.directories;
|
||||
delete subDir.metaFile;
|
||||
delete subDir.media;
|
||||
delete sp1.metadata.faces;
|
||||
delete sp2.metadata.faces;
|
||||
expect(Utils.clone(Utils.removeNullOrEmptyObj(selected)))
|
||||
|
@ -259,6 +259,7 @@ export class TestHelper {
|
||||
mediaCount: 0,
|
||||
directories: [],
|
||||
metaFile: [],
|
||||
preview: null,
|
||||
media: [],
|
||||
lastModified: Date.now(),
|
||||
lastScanned: null,
|
||||
|
Loading…
Reference in New Issue
Block a user