mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-25 02:04:15 +02:00
Refactoring directory interfaces #80
This commit is contained in:
parent
6bcd8ff33c
commit
628bc74226
@ -5,7 +5,6 @@ import {IndexingManager} from '../src/backend/model/database/sql/IndexingManager
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {Utils} from '../src/common/Utils';
|
||||
import {DirectoryDTO} from '../src/common/entities/DirectoryDTO';
|
||||
import {DatabaseType, ReIndexingSensitivity} from '../src/common/config/private/PrivateConfig';
|
||||
import {ProjectPath} from '../src/backend/ProjectPath';
|
||||
import {Benchmark} from './Benchmark';
|
||||
@ -30,6 +29,7 @@ import {
|
||||
TextSearchQueryTypes
|
||||
} from '../src/common/entities/SearchQueryDTO';
|
||||
import {QueryKeywords, SearchQueryParser} from '../src/common/SearchQueryParser';
|
||||
import {DirectoryBaseDTO, ParentDirectoryDTO} from '../src/common/entities/DirectoryDTO';
|
||||
|
||||
|
||||
export interface BenchmarkResult {
|
||||
@ -43,7 +43,7 @@ export interface BenchmarkResult {
|
||||
|
||||
export class BMIndexingManager extends IndexingManager {
|
||||
|
||||
public async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
public async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
return super.saveToDB(scannedDirectory);
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@ export class BenchmarkRunner {
|
||||
name: 'Saving directory to DB',
|
||||
fn: (): Promise<void> => {
|
||||
const im = new BMIndexingManager();
|
||||
return im.saveToDB(dir);
|
||||
return im.saveToDB(dir as ParentDirectoryDTO);
|
||||
}
|
||||
});
|
||||
return await bm.run(this.RUNS);
|
||||
|
@ -3,7 +3,7 @@ import {promises as fsp} from 'fs';
|
||||
import * as archiver from 'archiver';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {DirectoryDTO, DirectoryDTOUtils} from '../../common/entities/DirectoryDTO';
|
||||
import {DirectoryDTOUtils, ParentDirectoryDTO} from '../../common/entities/DirectoryDTO';
|
||||
import {ObjectManagers} from '../model/ObjectManagers';
|
||||
import {ContentWrapper} from '../../common/entities/ConentWrapper';
|
||||
import {PhotoDTO} from '../../common/entities/PhotoDTO';
|
||||
@ -46,7 +46,7 @@ export class GalleryMWs {
|
||||
if (req.session.user.permissions &&
|
||||
req.session.user.permissions.length > 0 &&
|
||||
req.session.user.permissions[0] !== '/*') {
|
||||
(directory as DirectoryDTO).directories = (directory as DirectoryDTO).directories.filter((d): boolean =>
|
||||
directory.directories = directory.directories.filter((d): boolean =>
|
||||
UserDTOUtils.isDirectoryAvailable(d, req.session.user.permissions));
|
||||
}
|
||||
req.resultPipe = new ContentWrapper(directory, null);
|
||||
@ -149,11 +149,8 @@ export class GalleryMWs {
|
||||
|
||||
if (Config.Client.Media.Video.enabled === false) {
|
||||
if (cw.directory) {
|
||||
const removeVideos = (dir: DirectoryDTO): void => {
|
||||
const removeVideos = (dir: ParentDirectoryDTO): void => {
|
||||
dir.media = dir.media.filter((m): boolean => !MediaDTOUtils.isVideo(m));
|
||||
if (dir.directories) {
|
||||
dir.directories.forEach((d): void => removeVideos(d));
|
||||
}
|
||||
};
|
||||
removeVideos(cw.directory);
|
||||
}
|
||||
|
@ -3,11 +3,11 @@ import * as fs from 'fs';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO, SubDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ThumbnailSourceType} from '../../model/threading/PhotoWorker';
|
||||
import {MediaBaseDTO, MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {PhotoProcessing} from '../../model/fileprocessing/PhotoProcessing';
|
||||
import {PersonWithSampleRegion} from '../../../common/entities/PersonDTO';
|
||||
|
||||
@ -144,18 +144,13 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
|
||||
private static addThInfoTODir(directory: DirectoryDTO): void {
|
||||
private static addThInfoTODir(directory: ParentDirectoryDTO | SubDirectoryDTO): void {
|
||||
if (typeof directory.media !== 'undefined') {
|
||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.media);
|
||||
}
|
||||
if (directory.preview) {
|
||||
ThumbnailGeneratorMWs.addThInfoToAPhoto(directory.preview);
|
||||
}
|
||||
if (typeof directory.directories !== 'undefined') {
|
||||
for (const item of directory.directories) {
|
||||
ThumbnailGeneratorMWs.addThInfoTODir(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static addThInfoToPhotos(photos: MediaDTO[]): void {
|
||||
@ -164,7 +159,7 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
}
|
||||
|
||||
private static addThInfoToAPhoto(photo: MediaBaseDTO): void {
|
||||
private static addThInfoToAPhoto(photo: MediaDTO): void {
|
||||
const fullMediaPath = path.join(ProjectPath.ImageFolder, photo.directory.path, photo.directory.name, photo.name);
|
||||
for (const size of Config.Client.Media.Thumbnail.thumbnailSizes) {
|
||||
const thPath = PhotoProcessing.generateConvertedPath(fullMediaPath, size);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {DirectoryDTO, DirectoryDTOUtils} from '../../common/entities/DirectoryDTO';
|
||||
import {DirectoryDTOUtils, ParentDirectoryDTO} from '../../common/entities/DirectoryDTO';
|
||||
import {Logger} from '../Logger';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {DiskManagerTH} from './threading/ThreadPool';
|
||||
@ -17,24 +17,26 @@ export class DiskManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all files in a folder as fast as possible
|
||||
*/
|
||||
public static async scanDirectoryNoMetadata(relativeDirectoryName: string,
|
||||
settings: DirectoryScanSettings = {}): Promise<DirectoryDTO<FileDTO>> {
|
||||
settings: DirectoryScanSettings = {}): Promise<ParentDirectoryDTO<FileDTO>> {
|
||||
settings.noMetadata = true;
|
||||
return this.scanDirectory(relativeDirectoryName, settings);
|
||||
}
|
||||
|
||||
public static async scanDirectory(relativeDirectoryName: string,
|
||||
settings: DirectoryScanSettings = {}): Promise<DirectoryDTO> {
|
||||
settings: DirectoryScanSettings = {}): Promise<ParentDirectoryDTO> {
|
||||
|
||||
Logger.silly(LOG_TAG, 'scanning directory:', relativeDirectoryName);
|
||||
|
||||
let directory: DirectoryDTO;
|
||||
let directory: ParentDirectoryDTO;
|
||||
|
||||
if (Config.Server.Threading.enabled === true) {
|
||||
directory = await DiskManager.threadPool.execute(relativeDirectoryName, settings);
|
||||
} else {
|
||||
directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName, settings);
|
||||
directory = await DiskMangerWorker.scanDirectory(relativeDirectoryName, settings) as ParentDirectoryDTO;
|
||||
}
|
||||
DirectoryDTOUtils.unpackDirectory(directory);
|
||||
return directory;
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
|
||||
export interface IGalleryManager {
|
||||
listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<DirectoryDTO>;
|
||||
knownLastScanned?: number): Promise<ParentDirectoryDTO>;
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
|
||||
export interface IIndexingManager {
|
||||
SavingReady: Promise<void>;
|
||||
IsSavingInProgress: boolean;
|
||||
|
||||
indexDirectory(relativeDirectoryName: string): Promise<DirectoryDTO>;
|
||||
indexDirectory(relativeDirectoryName: string): Promise<ParentDirectoryDTO>;
|
||||
|
||||
resetDB(): Promise<void>;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {IGalleryManager} from '../interfaces/IGalleryManager';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@ -11,7 +11,9 @@ import {ServerPG2ConfMap} from '../../../../common/PG2ConfMap';
|
||||
|
||||
export class GalleryManager implements IGalleryManager {
|
||||
|
||||
public async listDirectory(relativeDirectoryName: string, knownLastModified?: number, knownLastScanned?: number): Promise<DirectoryDTO> {
|
||||
public async listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<ParentDirectoryDTO> {
|
||||
// If it seems that the content did not changed, do not work on it
|
||||
if (knownLastModified && knownLastScanned) {
|
||||
const stat = fs.statSync(path.join(ProjectPath.ImageFolder, relativeDirectoryName));
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {IIndexingManager} from '../interfaces/IIndexingManager';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
|
||||
export class IndexingManager implements IIndexingManager {
|
||||
IsSavingInProgress: boolean;
|
||||
SavingReady: Promise<void>;
|
||||
|
||||
indexDirectory(relativeDirectoryName: string): Promise<DirectoryDTO> {
|
||||
indexDirectory(relativeDirectoryName: string): Promise<ParentDirectoryDTO> {
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {IGalleryManager} from '../interfaces/IGalleryManager';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryPathDTO, ParentDirectoryDTO, SubDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
@ -35,7 +35,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
|
||||
public async listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<DirectoryDTO> {
|
||||
knownLastScanned?: number): Promise<ParentDirectoryDTO> {
|
||||
const directoryPath = GalleryManager.parseRelativeDirePath(relativeDirectoryName);
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const stat = fs.statSync(path.join(ProjectPath.ImageFolder, relativeDirectoryName));
|
||||
@ -259,7 +259,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
return await query.getOne();
|
||||
}
|
||||
|
||||
protected async fillPreviewFromSubDir(connection: Connection, dir: DirectoryDTO): Promise<void> {
|
||||
protected async fillPreviewFromSubDir(connection: Connection, dir: SubDirectoryDTO): Promise<void> {
|
||||
dir.media = [];
|
||||
const query = connection
|
||||
.getRepository(MediaEntity)
|
||||
|
@ -1,13 +1,14 @@
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {IGalleryManager} from '../interfaces/IGalleryManager';
|
||||
import {DuplicatesDTO} from '../../../../common/entities/DuplicatesDTO';
|
||||
import {Connection} from 'typeorm';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
|
||||
export interface ISQLGalleryManager extends IGalleryManager {
|
||||
listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<DirectoryDTO>;
|
||||
knownLastScanned?: number): Promise<ParentDirectoryDTO>;
|
||||
|
||||
countDirectories(): Promise<number>;
|
||||
|
||||
@ -19,7 +20,7 @@ export interface ISQLGalleryManager extends IGalleryManager {
|
||||
|
||||
getPossibleDuplicates(): Promise<DuplicatesDTO[]>;
|
||||
|
||||
selectDirStructure(directory: string): Promise<DirectoryDTO>;
|
||||
selectDirStructure(directory: string): Promise<ParentDirectoryDTO<FileDTO>>;
|
||||
|
||||
fillPreviewForSubDir(connection: Connection, dir: DirectoryEntity): Promise<void>;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {DiskManager} from '../../DiskManger';
|
||||
@ -29,7 +29,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
|
||||
SavingReady: Promise<void> = null;
|
||||
private SavingReadyPR: () => void = null;
|
||||
private savingQueue: DirectoryDTO[] = [];
|
||||
private savingQueue: ParentDirectoryDTO[] = [];
|
||||
private isSaving = false;
|
||||
|
||||
get IsSavingInProgress(): boolean {
|
||||
@ -55,7 +55,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
* Indexes a dir, but returns early with the scanned version,
|
||||
* does not wait for the DB to be saved
|
||||
*/
|
||||
public indexDirectory(relativeDirectoryName: string): Promise<DirectoryDTO> {
|
||||
public indexDirectory(relativeDirectoryName: string): Promise<ParentDirectoryDTO> {
|
||||
return new Promise(async (resolve, reject): Promise<void> => {
|
||||
try {
|
||||
const scannedDirectory = await DiskManager.scanDirectory(relativeDirectoryName);
|
||||
@ -99,7 +99,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
/**
|
||||
* Queues up a directory to save to the DB.
|
||||
*/
|
||||
protected async queueForSave(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
protected async queueForSave(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
// Is this dir already queued for saving?
|
||||
if (this.savingQueue.findIndex((dir): boolean => dir.name === scannedDirectory.name &&
|
||||
dir.path === scannedDirectory.path &&
|
||||
@ -133,7 +133,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
|
||||
}
|
||||
|
||||
protected async saveParentDir(connection: Connection, scannedDirectory: DirectoryDTO): Promise<number> {
|
||||
protected async saveParentDir(connection: Connection, scannedDirectory: ParentDirectoryDTO): Promise<number> {
|
||||
const directoryRepository = connection.getRepository(DirectoryEntity);
|
||||
|
||||
const currentDir: DirectoryEntity = await directoryRepository.createQueryBuilder('directory')
|
||||
@ -159,7 +159,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
}
|
||||
}
|
||||
|
||||
protected async saveChildDirs(connection: Connection, currentDirId: number, scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
protected async saveChildDirs(connection: Connection, currentDirId: number, scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
const directoryRepository = connection.getRepository(DirectoryEntity);
|
||||
|
||||
// update subdirectories that does not have a parent
|
||||
@ -200,7 +200,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
|
||||
}
|
||||
|
||||
protected async saveMetaFiles(connection: Connection, currentDirID: number, scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
protected async saveMetaFiles(connection: Connection, currentDirID: number, scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
const fileRepository = connection.getRepository(FileEntity);
|
||||
// save files
|
||||
const indexedMetaFiles = await fileRepository.createQueryBuilder('file')
|
||||
@ -359,7 +359,7 @@ export class IndexingManager implements IIndexingManager {
|
||||
|
||||
}
|
||||
|
||||
protected async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
protected async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
this.isSaving = true;
|
||||
try {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
|
@ -241,14 +241,14 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
}
|
||||
|
||||
public async getPreview(queryIN: SearchQueryDTO): Promise<MediaDTO> {
|
||||
public async getPreview(queryIN: SearchQueryDTO, ): Promise<MediaDTO> {
|
||||
const query = await this.prepareQuery(queryIN);
|
||||
const connection = await SQLConnection.getConnection();
|
||||
|
||||
return await connection
|
||||
.getRepository(MediaEntity)
|
||||
.createQueryBuilder('media')
|
||||
.innerJoinAndSelect('media.directory', 'directory')
|
||||
.select(['media', ...this.DIRECTORY_SELECT])
|
||||
.where(this.buildWhereQuery(query))
|
||||
.orderBy('media.metadata.creationDate', 'DESC')
|
||||
.limit(1)
|
||||
|
@ -1,12 +1,13 @@
|
||||
import {Column, Entity, Index, ManyToOne, OneToMany, PrimaryGeneratedColumn, Unique} from 'typeorm';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO, SubDirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {MediaEntity} from './MediaEntity';
|
||||
import {FileEntity} from './FileEntity';
|
||||
import {columnCharsetCS} from './EntityUtils';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
|
||||
@Entity()
|
||||
@Unique(['name', 'path'])
|
||||
export class DirectoryEntity implements DirectoryDTO {
|
||||
export class DirectoryEntity implements ParentDirectoryDTO<MediaDTO>, SubDirectoryDTO<MediaDTO> {
|
||||
|
||||
@Index()
|
||||
@PrimaryGeneratedColumn({unsigned: true})
|
||||
|
@ -9,9 +9,10 @@ import {DatabaseType} from '../../../../common/config/private/PrivateConfig';
|
||||
import {DiskMangerWorker} from '../../threading/DiskMangerWorker';
|
||||
import {ProjectPath} from '../../../ProjectPath';
|
||||
import {backendTexts} from '../../../../common/BackendTexts';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ISQLGalleryManager} from '../../database/sql/IGalleryManager';
|
||||
import {Logger} from '../../../Logger';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
|
||||
|
||||
export class IndexingJob<S extends { indexChangesOnly: boolean } = { indexChangesOnly: boolean }> extends Job<S> {
|
||||
@ -45,7 +46,7 @@ export class IndexingJob<S extends { indexChangesOnly: boolean } = { indexChange
|
||||
const directory = this.directoriesToIndex.shift();
|
||||
this.Progress.Left = this.directoriesToIndex.length;
|
||||
|
||||
let scanned: DirectoryDTO;
|
||||
let scanned: ParentDirectoryDTO<FileDTO>;
|
||||
let dirChanged = true;
|
||||
|
||||
// check if the folder got modified if only changes need to be indexed
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {promises as fsp, Stats} from 'fs';
|
||||
import * as path from 'path';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO, SubDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
@ -77,13 +77,13 @@ export class DiskMangerWorker {
|
||||
}
|
||||
|
||||
public static async scanDirectoryNoMetadata(relativeDirectoryName: string,
|
||||
settings: DirectoryScanSettings = {}): Promise<DirectoryDTO<FileDTO>> {
|
||||
settings: DirectoryScanSettings = {}): Promise<ParentDirectoryDTO<FileDTO>> {
|
||||
settings.noMetadata = true;
|
||||
return this.scanDirectory(relativeDirectoryName, settings);
|
||||
return (await this.scanDirectory(relativeDirectoryName, settings)) as ParentDirectoryDTO<FileDTO>;
|
||||
}
|
||||
|
||||
public static async scanDirectory(relativeDirectoryName: string,
|
||||
settings: DirectoryScanSettings = {}): Promise<DirectoryDTO> {
|
||||
settings: DirectoryScanSettings = {}): Promise<ParentDirectoryDTO> {
|
||||
|
||||
relativeDirectoryName = this.normalizeDirPath(relativeDirectoryName);
|
||||
const directoryName = DiskMangerWorker.dirName(relativeDirectoryName);
|
||||
@ -91,7 +91,7 @@ export class DiskMangerWorker {
|
||||
const absoluteDirectoryName = path.join(ProjectPath.ImageFolder, relativeDirectoryName);
|
||||
|
||||
const stat = await fsp.stat(path.join(ProjectPath.ImageFolder, relativeDirectoryName));
|
||||
const directory: DirectoryDTO = {
|
||||
const directory: ParentDirectoryDTO = {
|
||||
id: null,
|
||||
parent: null,
|
||||
name: directoryName,
|
||||
@ -124,7 +124,7 @@ export class DiskMangerWorker {
|
||||
{
|
||||
previewOnly: true
|
||||
}
|
||||
);
|
||||
) as SubDirectoryDTO;
|
||||
|
||||
d.lastScanned = 0; // it was not a fully scan
|
||||
d.isPartial = true;
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
|
||||
export interface TaskQueEntry<I, O> {
|
||||
|
@ -1,7 +1,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 {ParentDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {RendererInput} from './PhotoWorker';
|
||||
import {TaskQue, TaskQueEntry} from './TaskQue';
|
||||
import {ITaskExecuter} from './TaskExecuter';
|
||||
@ -89,8 +89,8 @@ export class ThreadPool<O> {
|
||||
|
||||
}
|
||||
|
||||
export class DiskManagerTH extends ThreadPool<DirectoryDTO> implements ITaskExecuter<string, DirectoryDTO> {
|
||||
execute(relativeDirectoryName: string, settings: DirectoryScanSettings = {}): Promise<DirectoryDTO> {
|
||||
export class DiskManagerTH extends ThreadPool<ParentDirectoryDTO> implements ITaskExecuter<string, ParentDirectoryDTO> {
|
||||
execute(relativeDirectoryName: string, settings: DirectoryScanSettings = {}): Promise<ParentDirectoryDTO> {
|
||||
return super.executeTask({
|
||||
type: WorkerTaskTypes.diskManager,
|
||||
relativeDirectoryName,
|
||||
|
@ -3,13 +3,14 @@ import {Logger} from '../../Logger';
|
||||
import {PhotoWorker, RendererInput} from './PhotoWorker';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
declare var global: NodeJS.Global;
|
||||
const LOG_TAG = '[Worker]';
|
||||
|
||||
export class Worker {
|
||||
public static process<O extends (void | DirectoryDTO<MediaDTO>)>(): void {
|
||||
public static process<O extends (void | ParentDirectoryDTO<MediaDTO>)>(): void {
|
||||
Logger.debug(LOG_TAG, 'Worker is waiting for tasks');
|
||||
process.on('message', async (task: WorkerTask) => {
|
||||
try {
|
||||
|
@ -1,8 +1,8 @@
|
||||
import {DirectoryDTO} from './DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from './DirectoryDTO';
|
||||
import {SearchResultDTO} from './SearchResultDTO';
|
||||
|
||||
export class ContentWrapper {
|
||||
constructor(public directory: DirectoryDTO = null,
|
||||
constructor(public directory: ParentDirectoryDTO = null,
|
||||
public searchResult: SearchResultDTO = null,
|
||||
public notModified?: boolean) {
|
||||
}
|
||||
|
@ -3,28 +3,71 @@ import {FileDTO} from './FileDTO';
|
||||
import {PhotoDTO, PreviewPhotoDTO} from './PhotoDTO';
|
||||
import {Utils} from '../Utils';
|
||||
|
||||
export interface DirectoryBaseDTO {
|
||||
export interface DirectoryPathDTO {
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
//
|
||||
// export interface DirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryPathDTO {
|
||||
// id: number;
|
||||
// name: string;
|
||||
// path: string;
|
||||
// lastModified: number;
|
||||
// lastScanned: number;
|
||||
// isPartial?: boolean;
|
||||
// parent: DirectoryDTO<S>;
|
||||
// mediaCount: number;
|
||||
// directories: DirectoryDTO<S>[];
|
||||
// preview: PreviewPhotoDTO;
|
||||
// media: S[];
|
||||
// metaFile: FileDTO[];
|
||||
// }
|
||||
|
||||
export interface DirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryBaseDTO {
|
||||
|
||||
export interface DirectoryBaseDTO<S extends FileDTO = MediaDTO> extends DirectoryPathDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
lastModified: number;
|
||||
lastScanned: number;
|
||||
isPartial?: boolean;
|
||||
parent: DirectoryDTO<S>;
|
||||
parent: DirectoryBaseDTO<S>;
|
||||
mediaCount: number;
|
||||
directories: DirectoryDTO<S>[];
|
||||
preview: PreviewPhotoDTO;
|
||||
|
||||
directories?: DirectoryBaseDTO<S>[];
|
||||
media?: S[];
|
||||
metaFile?: FileDTO[];
|
||||
preview?: PreviewPhotoDTO;
|
||||
}
|
||||
|
||||
export interface ParentDirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryBaseDTO<S> {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
lastModified: number;
|
||||
lastScanned: number;
|
||||
isPartial?: boolean;
|
||||
parent: ParentDirectoryDTO<S>;
|
||||
mediaCount: number;
|
||||
directories: SubDirectoryDTO<S>[];
|
||||
media: S[];
|
||||
metaFile: FileDTO[];
|
||||
}
|
||||
|
||||
export interface SubDirectoryDTO<S extends FileDTO = MediaDTO> extends DirectoryBaseDTO<S> {
|
||||
id: number;
|
||||
name: string;
|
||||
path: string;
|
||||
lastModified: number;
|
||||
lastScanned: number;
|
||||
isPartial?: boolean;
|
||||
parent: ParentDirectoryDTO<S>;
|
||||
mediaCount: number;
|
||||
preview: PreviewPhotoDTO;
|
||||
}
|
||||
|
||||
export const DirectoryDTOUtils = {
|
||||
unpackDirectory: (dir: DirectoryDTO): void => {
|
||||
unpackDirectory: (dir: DirectoryBaseDTO): void => {
|
||||
dir.media.forEach((media: MediaDTO) => {
|
||||
media.directory = dir;
|
||||
});
|
||||
@ -36,14 +79,14 @@ export const DirectoryDTOUtils = {
|
||||
}
|
||||
|
||||
if (dir.directories) {
|
||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
||||
dir.directories.forEach((directory) => {
|
||||
DirectoryDTOUtils.unpackDirectory(directory);
|
||||
directory.parent = dir;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
packDirectory: (dir: DirectoryDTO): DirectoryDTO => {
|
||||
packDirectory: (dir: DirectoryBaseDTO): DirectoryBaseDTO => {
|
||||
if (dir.preview) {
|
||||
dir.preview.directory = {
|
||||
path: dir.preview.directory.path,
|
||||
@ -67,7 +110,7 @@ export const DirectoryDTOUtils = {
|
||||
});
|
||||
}
|
||||
if (dir.directories) {
|
||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
||||
dir.directories.forEach((directory) => {
|
||||
DirectoryDTOUtils.packDirectory(directory);
|
||||
directory.parent = null;
|
||||
});
|
||||
@ -76,10 +119,10 @@ export const DirectoryDTOUtils = {
|
||||
return dir;
|
||||
|
||||
},
|
||||
filterPhotos: (dir: DirectoryDTO): PhotoDTO[] => {
|
||||
filterPhotos: (dir: DirectoryBaseDTO): PhotoDTO[] => {
|
||||
return dir.media.filter(m => MediaDTOUtils.isPhoto(m)) as PhotoDTO[];
|
||||
},
|
||||
filterVideos: (dir: DirectoryDTO): PhotoDTO[] => {
|
||||
filterVideos: (dir: DirectoryBaseDTO): PhotoDTO[] => {
|
||||
return dir.media.filter(m => MediaDTOUtils.isPhoto(m)) as PhotoDTO[];
|
||||
}
|
||||
};
|
||||
|
@ -1,14 +1,9 @@
|
||||
import {DirectoryBaseDTO, DirectoryDTO} from './DirectoryDTO';
|
||||
import {DirectoryPathDTO} from './DirectoryDTO';
|
||||
|
||||
export interface FileBaseDTO {
|
||||
|
||||
export interface FileDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryBaseDTO;
|
||||
}
|
||||
|
||||
export interface FileDTO extends FileBaseDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryDTO;
|
||||
directory: DirectoryPathDTO;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,13 @@
|
||||
import {DirectoryBaseDTO, DirectoryDTO} from './DirectoryDTO';
|
||||
import {DirectoryPathDTO} from './DirectoryDTO';
|
||||
import {PhotoDTO} from './PhotoDTO';
|
||||
import {FileBaseDTO, FileDTO} from './FileDTO';
|
||||
import {FileDTO} from './FileDTO';
|
||||
import {SupportedFormats} from '../SupportedFormats';
|
||||
|
||||
export interface MediaBaseDTO extends FileBaseDTO {
|
||||
name: string;
|
||||
directory: DirectoryBaseDTO;
|
||||
metadata: MediaMetadata;
|
||||
readyThumbnails: number[];
|
||||
readyIcon: boolean;
|
||||
}
|
||||
|
||||
export interface MediaDTO extends FileDTO, MediaBaseDTO {
|
||||
export interface MediaDTO extends FileDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryDTO;
|
||||
directory: DirectoryPathDTO;
|
||||
metadata: MediaMetadata;
|
||||
readyThumbnails: number[];
|
||||
readyIcon: boolean;
|
||||
@ -35,7 +28,7 @@ export interface MediaDimension {
|
||||
}
|
||||
|
||||
export const MediaDTOUtils = {
|
||||
hasPositionData: (media: MediaBaseDTO): boolean => {
|
||||
hasPositionData: (media: MediaDTO): boolean => {
|
||||
return !!(media as PhotoDTO).metadata.positionData &&
|
||||
!!((media as PhotoDTO).metadata.positionData.city ||
|
||||
(media as PhotoDTO).metadata.positionData.state ||
|
||||
@ -45,11 +38,11 @@ export const MediaDTOUtils = {
|
||||
(media as PhotoDTO).metadata.positionData.GPSData.latitude &&
|
||||
(media as PhotoDTO).metadata.positionData.GPSData.longitude));
|
||||
},
|
||||
isPhoto: (media: FileBaseDTO): boolean => {
|
||||
isPhoto: (media: FileDTO): boolean => {
|
||||
return !MediaDTOUtils.isVideo(media);
|
||||
},
|
||||
|
||||
isVideo: (media: FileBaseDTO): boolean => {
|
||||
isVideo: (media: FileDTO): boolean => {
|
||||
const lower = media.name.toLowerCase();
|
||||
for (const ext of SupportedFormats.WithDots.Videos) {
|
||||
if (lower.endsWith(ext)) {
|
||||
@ -69,7 +62,7 @@ export const MediaDTOUtils = {
|
||||
return false;
|
||||
},
|
||||
|
||||
isVideoTranscodingNeeded: (media: FileBaseDTO): boolean => {
|
||||
isVideoTranscodingNeeded: (media: FileDTO): boolean => {
|
||||
const lower = media.name.toLowerCase();
|
||||
for (const ext of SupportedFormats.WithDots.TranscodeNeed.Videos) {
|
||||
if (lower.endsWith(ext)) {
|
||||
@ -80,7 +73,7 @@ export const MediaDTOUtils = {
|
||||
},
|
||||
|
||||
|
||||
calcAspectRatio: (photo: MediaBaseDTO): number => {
|
||||
calcAspectRatio: (photo: MediaDTO): number => {
|
||||
return photo.metadata.size.width / photo.metadata.size.height;
|
||||
}
|
||||
};
|
||||
|
@ -1,20 +1,20 @@
|
||||
import {DirectoryBaseDTO, DirectoryDTO} from './DirectoryDTO';
|
||||
import {DirectoryPathDTO} from './DirectoryDTO';
|
||||
import {OrientationTypes} from 'ts-exif-parser';
|
||||
import {MediaBaseDTO, MediaDimension, MediaDTO, MediaMetadata} from './MediaDTO';
|
||||
import {MediaDimension, MediaDTO, MediaMetadata} from './MediaDTO';
|
||||
|
||||
export interface PreviewPhotoDTO extends MediaBaseDTO {
|
||||
export interface PreviewPhotoDTO extends MediaDTO {
|
||||
name: string;
|
||||
directory: DirectoryBaseDTO;
|
||||
readyThumbnails: Array<number>;
|
||||
directory: DirectoryPathDTO;
|
||||
readyThumbnails: number[];
|
||||
readyIcon: boolean;
|
||||
}
|
||||
|
||||
export interface PhotoDTO extends PreviewPhotoDTO, MediaDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryDTO;
|
||||
directory: DirectoryPathDTO;
|
||||
metadata: PhotoMetadata;
|
||||
readyThumbnails: Array<number>;
|
||||
readyThumbnails: number[];
|
||||
readyIcon: boolean;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {DirectoryDTO} from './DirectoryDTO';
|
||||
import {SubDirectoryDTO} from './DirectoryDTO';
|
||||
import {FileDTO} from './FileDTO';
|
||||
import {MediaDTO} from './MediaDTO';
|
||||
import {SearchQueryDTO} from './SearchQueryDTO';
|
||||
|
||||
export interface SearchResultDTO {
|
||||
searchQuery: SearchQueryDTO;
|
||||
directories: DirectoryDTO[];
|
||||
directories: SubDirectoryDTO[];
|
||||
media: MediaDTO[];
|
||||
metaFile: FileDTO[];
|
||||
resultOverflow: boolean;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {DirectoryDTO} from './DirectoryDTO';
|
||||
import {DirectoryPathDTO} from './DirectoryDTO';
|
||||
import {Utils} from '../Utils';
|
||||
|
||||
export enum UserRoles {
|
||||
@ -50,7 +50,7 @@ export const UserDTOUtils = {
|
||||
},
|
||||
|
||||
|
||||
isDirectoryAvailable: (directory: DirectoryDTO, permissions: string[]): boolean => {
|
||||
isDirectoryAvailable: (directory: DirectoryPathDTO, permissions: string[]): boolean => {
|
||||
return UserDTOUtils.isDirectoryPathAvailable(
|
||||
Utils.concatUrls(directory.path, directory.name), permissions);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {DirectoryDTO} from './DirectoryDTO';
|
||||
import {DirectoryPathDTO} from './DirectoryDTO';
|
||||
import {MediaDimension, MediaDTO, MediaMetadata} from './MediaDTO';
|
||||
|
||||
export interface VideoDTO extends MediaDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
directory: DirectoryDTO;
|
||||
directory: DirectoryPathDTO;
|
||||
metadata: VideoMetadata;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ShareService} from '../ui/gallery/share.service';
|
||||
import {MediaBaseDTO} from '../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../common/QueryParams';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {GalleryService} from '../ui/gallery/gallery.service';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO, SubDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
@Injectable()
|
||||
export class QueryService {
|
||||
@ -15,7 +15,7 @@ export class QueryService {
|
||||
private galleryService: GalleryService) {
|
||||
}
|
||||
|
||||
getMediaStringId(media: MediaBaseDTO): string {
|
||||
getMediaStringId(media: MediaDTO): string {
|
||||
if (this.galleryService.isSearchResult()) {
|
||||
return Utils.concatUrls(media.directory.path, media.directory.name, media.name);
|
||||
} else {
|
||||
@ -23,7 +23,7 @@ export class QueryService {
|
||||
}
|
||||
}
|
||||
|
||||
getParams(media?: MediaBaseDTO): { [key: string]: string } {
|
||||
getParams(media?: MediaDTO): { [key: string]: string } {
|
||||
const query: { [key: string]: string } = {};
|
||||
if (media) {
|
||||
query[QueryParams.gallery.photo] = this.getMediaStringId(media);
|
||||
@ -36,7 +36,7 @@ export class QueryService {
|
||||
return query;
|
||||
}
|
||||
|
||||
getParamsForDirs(directory: DirectoryDTO): { [key: string]: any } {
|
||||
getParamsForDirs(directory: ParentDirectoryDTO | SubDirectoryDTO): { [key: string]: any } {
|
||||
const params: { [key: string]: any } = {};
|
||||
if (Config.Client.Sharing.enabled === true) {
|
||||
if (this.shareService.isSharing()) {
|
||||
|
@ -3,7 +3,7 @@ import {DuplicateService} from './duplicates.service';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {QueryService} from '../../model/query.service';
|
||||
import {DuplicatesDTO} from '../../../../common/entities/DuplicatesDTO';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryPathDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
@ -51,16 +51,17 @@ export class DuplicateComponent implements OnDestroy {
|
||||
this.duplicateCount.photos = duplicates.reduce((prev: number, curr): number => prev + curr.media.length, 0);
|
||||
this.duplicateCount.pairs = duplicates.length;
|
||||
|
||||
const getMostFrequentDir = (dupls: DuplicatesDTO[]): DirectoryDTO<MediaDTO> | null => {
|
||||
const getMostFrequentDir = (dupls: DuplicatesDTO[]): DirectoryPathDTO | null => {
|
||||
if (dupls.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const dirFrequency: { [key: number]: { count: number, dir: DirectoryDTO } } = {};
|
||||
const dirFrequency: { [key: string]: { count: number, dir: DirectoryPathDTO } } = {};
|
||||
dupls.forEach((d): void => d.media.forEach((m): void => {
|
||||
dirFrequency[m.directory.id] = dirFrequency[m.directory.id] || {dir: m.directory, count: 0};
|
||||
dirFrequency[m.directory.id].count++;
|
||||
const k = Utils.concatUrls(m.directory.path, m.directory.name);
|
||||
dirFrequency[k] = dirFrequency[k] || {dir: m.directory, count: 0};
|
||||
dirFrequency[k].count++;
|
||||
}));
|
||||
let max: { count: number, dir: DirectoryDTO } = {count: -1, dir: null};
|
||||
let max: { count: number, dir: DirectoryPathDTO } = {count: -1, dir: null};
|
||||
for (const freq of Object.values(dirFrequency)) {
|
||||
if (max.count <= freq.count) {
|
||||
max = freq;
|
||||
@ -71,8 +72,10 @@ export class DuplicateComponent implements OnDestroy {
|
||||
|
||||
while (duplicates.length > 0) {
|
||||
const dir = getMostFrequentDir(duplicates);
|
||||
const group = duplicates.filter((d): MediaDTO => d.media.find((m): boolean => m.directory.id === dir.id));
|
||||
duplicates = duplicates.filter((d): boolean => !d.media.find((m): boolean => m.directory.id === dir.id));
|
||||
const group = duplicates.filter((d): MediaDTO =>
|
||||
d.media.find((m): boolean => m.directory.name === dir.name && m.directory.path === dir.path));
|
||||
duplicates = duplicates.filter((d): boolean =>
|
||||
!d.media.find((m): boolean => m.directory.name === dir.name && m.directory.path === dir.path));
|
||||
this.directoryGroups.push({name: this.getDirectoryPath(dir) + ' (' + group.length + ')', duplicates: group});
|
||||
}
|
||||
this.renderMore();
|
||||
@ -86,7 +89,7 @@ export class DuplicateComponent implements OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
getDirectoryPath(directory: DirectoryDTO): string {
|
||||
getDirectoryPath(directory: DirectoryPathDTO): string {
|
||||
return Utils.concatUrls(directory.path, directory.name);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {MediaIcon} from './MediaIcon';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {MediaBaseDTO, MediaDTOUtils} from '../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO, MediaDTOUtils} from '../../../../common/entities/MediaDTO';
|
||||
|
||||
export class Media extends MediaIcon {
|
||||
|
||||
static readonly sortedThumbnailSizes = Config.Client.Media.Thumbnail.thumbnailSizes
|
||||
.sort((a, b): number => a - b);
|
||||
|
||||
constructor(media: MediaBaseDTO, public renderWidth: number, public renderHeight: number) {
|
||||
constructor(media: MediaDTO, public renderWidth: number, public renderHeight: number) {
|
||||
super(media);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {MediaBaseDTO, MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
|
||||
export class MediaIcon {
|
||||
|
||||
|
||||
protected replacementSizeCache: number | boolean = false;
|
||||
|
||||
constructor(public media: MediaBaseDTO) {
|
||||
constructor(public media: MediaDTO) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {DirectoryDTO, DirectoryDTOUtils} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryDTOUtils, DirectoryPathDTO, ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {IAutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {MediaBaseDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {VersionService} from '../../model/version.service';
|
||||
import {SearchQueryDTO, SearchQueryTypes} from '../../../../common/entities/SearchQueryDTO';
|
||||
@ -83,7 +83,7 @@ export class GalleryCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
public getSorting(dir: DirectoryDTO): SortingMethods {
|
||||
public getSorting(dir: DirectoryPathDTO): SortingMethods {
|
||||
const key = GalleryCacheService.SORTING_PREFIX + dir.path + '/' + dir.name;
|
||||
const tmp = localStorage.getItem(key);
|
||||
if (tmp != null) {
|
||||
@ -92,7 +92,7 @@ export class GalleryCacheService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public removeSorting(dir: DirectoryDTO): void {
|
||||
public removeSorting(dir: DirectoryPathDTO): void {
|
||||
try {
|
||||
const key = GalleryCacheService.SORTING_PREFIX + dir.path + '/' + dir.name;
|
||||
localStorage.removeItem(key);
|
||||
@ -102,7 +102,7 @@ export class GalleryCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
public setSorting(dir: DirectoryDTO, sorting: SortingMethods): SortingMethods {
|
||||
public setSorting(dir: DirectoryPathDTO, sorting: SortingMethods): SortingMethods {
|
||||
try {
|
||||
const key = GalleryCacheService.SORTING_PREFIX + dir.path + '/' + dir.name;
|
||||
localStorage.setItem(key, sorting.toString());
|
||||
@ -196,14 +196,14 @@ export class GalleryCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
public getDirectory(directoryName: string): DirectoryDTO {
|
||||
public getDirectory(directoryName: string): ParentDirectoryDTO {
|
||||
if (Config.Client.Other.enableCache === false) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
const value = localStorage.getItem(GalleryCacheService.CONTENT_PREFIX + Utils.concatUrls(directoryName));
|
||||
if (value != null) {
|
||||
const directory: DirectoryDTO = JSON.parse(value);
|
||||
const directory: ParentDirectoryDTO = JSON.parse(value);
|
||||
|
||||
DirectoryDTOUtils.unpackDirectory(directory);
|
||||
return directory;
|
||||
@ -213,7 +213,7 @@ export class GalleryCacheService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public setDirectory(directory: DirectoryDTO): void {
|
||||
public setDirectory(directory: ParentDirectoryDTO): void {
|
||||
if (Config.Client.Other.enableCache === false) {
|
||||
return;
|
||||
}
|
||||
@ -226,7 +226,7 @@ export class GalleryCacheService {
|
||||
try {
|
||||
// try to fit it
|
||||
localStorage.setItem(key, JSON.stringify(directory));
|
||||
directory.directories.forEach((dir: DirectoryDTO) => {
|
||||
directory.directories.forEach((dir) => {
|
||||
const subKey = GalleryCacheService.CONTENT_PREFIX + Utils.concatUrls(dir.path, dir.name);
|
||||
if (localStorage.getItem(subKey) == null) { // don't override existing
|
||||
localStorage.setItem(subKey, JSON.stringify(dir));
|
||||
@ -243,7 +243,7 @@ export class GalleryCacheService {
|
||||
* Update media state at cache too (Eg.: thumbnail rendered)
|
||||
* @param media: MediaBaseDTO
|
||||
*/
|
||||
public mediaUpdated(media: MediaBaseDTO): void {
|
||||
public mediaUpdated(media: MediaDTO): void {
|
||||
|
||||
if (Config.Client.Other.enableCache === false) {
|
||||
return;
|
||||
@ -253,7 +253,7 @@ export class GalleryCacheService {
|
||||
const directoryName = Utils.concatUrls(media.directory.path, media.directory.name);
|
||||
const value = localStorage.getItem(directoryName);
|
||||
if (value != null) {
|
||||
const directory: DirectoryDTO = JSON.parse(value);
|
||||
const directory: ParentDirectoryDTO = JSON.parse(value);
|
||||
directory.media.forEach((p) => {
|
||||
if (p.name === media.name) {
|
||||
// update data
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, ElementRef, Input, OnChanges} from '@angular/core';
|
||||
import { DeviceDetectorService } from 'ngx-device-detector';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {DeviceDetectorService} from 'ngx-device-detector';
|
||||
import {SubDirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-directories',
|
||||
@ -9,7 +9,7 @@ import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
})
|
||||
export class DirectoriesComponent implements OnChanges {
|
||||
|
||||
@Input() directories: DirectoryDTO[];
|
||||
@Input() directories: SubDirectoryDTO[];
|
||||
size: number;
|
||||
isDesktop: boolean;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||
import {DomSanitizer, SafeStyle} from '@angular/platform-browser';
|
||||
import {DirectoryDTO} from '../../../../../../common/entities/DirectoryDTO';
|
||||
import {SubDirectoryDTO} from '../../../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Utils} from '../../../../../../common/Utils';
|
||||
import {Media} from '../../Media';
|
||||
@ -16,7 +16,7 @@ import {PreviewPhotoDTO} from '../../../../../../common/entities/PhotoDTO';
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
@Input() directory: DirectoryDTO;
|
||||
@Input() directory: SubDirectoryDTO;
|
||||
@Input() size: number;
|
||||
thumbnail: Thumbnail = null;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {GalleryService} from './gallery.service';
|
||||
import {GalleryGridComponent} from './grid/grid.gallery.component';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO, SubDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {ShareService} from './share.service';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
@ -32,7 +32,7 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
public showShare = false;
|
||||
public showRandomPhotoBuilder = false;
|
||||
|
||||
public directories: DirectoryDTO[] = [];
|
||||
public directories: SubDirectoryDTO[] = [];
|
||||
public isPhotoWithLocation = false;
|
||||
public countDown: { day: number, hour: number, minute: number, second: number } = null;
|
||||
public readonly mapEnabled: boolean;
|
||||
@ -143,7 +143,7 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
const tmp = (content.searchResult || content.directory || {
|
||||
directories: [],
|
||||
media: []
|
||||
}) as DirectoryDTO | SearchResultDTO;
|
||||
}) as ParentDirectoryDTO | SearchResultDTO;
|
||||
this.directories = tmp.directories;
|
||||
this.sortDirectories();
|
||||
this.isPhotoWithLocation = false;
|
||||
@ -167,30 +167,30 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
switch (this.galleryService.sorting.value) {
|
||||
case SortingMethods.ascRating: // directories does not have rating
|
||||
case SortingMethods.ascName:
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare()(a.name, b.name));
|
||||
this.directories.sort((a, b) => compare()(a.name, b.name));
|
||||
break;
|
||||
case SortingMethods.ascDate:
|
||||
if (Config.Client.Other.enableDirectorySortingByDate === true) {
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare()(a.lastModified, b.lastModified));
|
||||
this.directories.sort((a, b) => compare()(a.lastModified, b.lastModified));
|
||||
break;
|
||||
}
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare()(a.name, b.name));
|
||||
this.directories.sort((a, b) => compare()(a.name, b.name));
|
||||
break;
|
||||
|
||||
case SortingMethods.descRating: // directories does not have rating
|
||||
case SortingMethods.descName:
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare({order: 'desc'})(a.name, b.name));
|
||||
this.directories.sort((a, b) => compare({order: 'desc'})(a.name, b.name));
|
||||
break;
|
||||
case SortingMethods.descDate:
|
||||
if (Config.Client.Other.enableDirectorySortingByDate === true) {
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare({order: 'desc'})(a.lastModified, b.lastModified));
|
||||
this.directories.sort((a, b) => compare({order: 'desc'})(a.lastModified, b.lastModified));
|
||||
break;
|
||||
}
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO) => compare({order: 'desc'})(a.name, b.name));
|
||||
this.directories.sort((a, b) => compare({order: 'desc'})(a.name, b.name));
|
||||
break;
|
||||
case SortingMethods.random:
|
||||
this.rndService.setSeed(this.directories.length);
|
||||
this.directories.sort((a: DirectoryDTO, b: DirectoryDTO): number => {
|
||||
this.directories.sort((a, b): number => {
|
||||
if (a.name.toLowerCase() < b.name.toLowerCase()) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO, DirectoryDTOUtils} from '../../../../common/entities/DirectoryDTO';
|
||||
import {DirectoryDTOUtils, ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {GalleryCacheService} from './cache.gallery.service';
|
||||
import {BehaviorSubject} from 'rxjs';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
@ -22,7 +22,7 @@ export class GalleryService {
|
||||
lastRequest: { directory: string } = {
|
||||
directory: null
|
||||
};
|
||||
private lastDirectory: DirectoryDTO;
|
||||
private lastDirectory: ParentDirectoryDTO;
|
||||
private searchId: any;
|
||||
private ongoingSearch: SearchQueryDTO = null;
|
||||
|
||||
@ -34,7 +34,7 @@ export class GalleryService {
|
||||
this.sorting = new BehaviorSubject<SortingMethods>(Config.Client.Other.defaultPhotoSortingMethod);
|
||||
}
|
||||
|
||||
getDefaultSorting(directory: DirectoryDTO): SortingMethods {
|
||||
getDefaultSorting(directory: ParentDirectoryDTO): SortingMethods {
|
||||
if (directory && directory.metaFile) {
|
||||
for (const file in PG2ConfMap.sorting) {
|
||||
if (directory.metaFile.some(f => f.name === file)) {
|
||||
@ -108,9 +108,9 @@ export class GalleryService {
|
||||
return;
|
||||
}
|
||||
|
||||
DirectoryDTOUtils.unpackDirectory(cw.directory as DirectoryDTO);
|
||||
DirectoryDTOUtils.unpackDirectory(cw.directory);
|
||||
|
||||
this.lastDirectory = (cw.directory as DirectoryDTO);
|
||||
this.lastDirectory = cw.directory;
|
||||
this.setContent(cw);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -9,7 +9,7 @@ import {Subscription} from 'rxjs';
|
||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {PageHelper} from '../../../model/page.helper';
|
||||
import {QueryService} from '../../../model/query.service';
|
||||
import {MediaBaseDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
|
||||
import {QueryParams} from '../../../../../common/QueryParams';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
@ -184,7 +184,7 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
public showLigthbox(photo: MediaBaseDTO): void {
|
||||
public showLigthbox(photo: MediaDTO): void {
|
||||
if (this.controls) {
|
||||
this.controls.resetZoom();
|
||||
}
|
||||
@ -417,7 +417,7 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
|
||||
|
||||
}
|
||||
|
||||
private findPhotoComponent(media: MediaBaseDTO): GalleryPhotoComponent {
|
||||
private findPhotoComponent(media: MediaDTO): GalleryPhotoComponent {
|
||||
const galleryPhotoComponents = this.gridPhotoQL.toArray();
|
||||
for (const item of galleryPhotoComponents) {
|
||||
if (item.gridMedia.media === media) {
|
||||
@ -427,7 +427,7 @@ export class GalleryLightboxComponent implements OnDestroy, OnInit {
|
||||
return null;
|
||||
}
|
||||
|
||||
private calcLightBoxPhotoDimension(photo: MediaBaseDTO): Dimension {
|
||||
private calcLightBoxPhotoDimension(photo: MediaDTO): Dimension {
|
||||
let width: number;
|
||||
let height: number;
|
||||
const photoAspect = photo.metadata.size.width / photo.metadata.size.height;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {Component, Input, OnChanges} from '@angular/core';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {UserDTOUtils} from '../../../../../common/entities/UserDTO';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
@ -18,7 +18,7 @@ import {SearchQueryTypes} from '../../../../../common/entities/SearchQueryDTO';
|
||||
providers: [RouterLink],
|
||||
})
|
||||
export class GalleryNavigatorComponent implements OnChanges {
|
||||
@Input() directory: DirectoryDTO;
|
||||
@Input() directory: ParentDirectoryDTO;
|
||||
@Input() searchResult: SearchResultDTO;
|
||||
|
||||
routes: NavigatorPath[] = [];
|
||||
|
@ -6,7 +6,7 @@ import {ContentWrapper} from '../../../../../common/entities/ConentWrapper';
|
||||
import {SharingDTO} from '../../../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {} from '../../../../../common/entities/DirectoryDTO';
|
||||
import {BsModalService} from 'ngx-bootstrap/modal';
|
||||
import {BsModalRef} from 'ngx-bootstrap/modal/bs-modal-ref.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
@ -59,7 +59,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
this.currentDir = Utils.concatUrls((content.directory as DirectoryDTO).path, (content.directory as DirectoryDTO).name);
|
||||
this.currentDir = Utils.concatUrls((content.directory).path, (content.directory).name);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import * as fs from 'fs';
|
||||
import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection';
|
||||
import {DatabaseType} from '../../src/common/config/private/PrivateConfig';
|
||||
import {ProjectPath} from '../../src/backend/ProjectPath';
|
||||
import {DirectoryDTO} from '../../src/common/entities/DirectoryDTO';
|
||||
import {DirectoryBaseDTO, ParentDirectoryDTO} from '../../src/common/entities/DirectoryDTO';
|
||||
import {DirectoryEntity} from '../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||
import {ObjectManagers} from '../../src/backend/model/ObjectManagers';
|
||||
import {DiskMangerWorker} from '../../src/backend/model/threading/DiskMangerWorker';
|
||||
@ -18,7 +18,7 @@ const savedDescribe = describe;
|
||||
|
||||
class IndexingManagerTest extends IndexingManager {
|
||||
|
||||
public async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
public async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
return super.saveToDB(scannedDirectory);
|
||||
}
|
||||
}
|
||||
@ -83,14 +83,14 @@ export class DBTestHelper {
|
||||
};
|
||||
}
|
||||
|
||||
public static async persistTestDir(directory: DirectoryDTO): Promise<DirectoryEntity> {
|
||||
public static async persistTestDir(directory: DirectoryBaseDTO): Promise<DirectoryEntity> {
|
||||
await ObjectManagers.InitSQLManagers();
|
||||
const connection = await SQLConnection.getConnection();
|
||||
ObjectManagers.getInstance().IndexingManager.indexDirectory = () => Promise.resolve(null);
|
||||
|
||||
|
||||
const im = new IndexingManagerTest();
|
||||
await im.saveToDB(directory);
|
||||
await im.saveToDB(directory as ParentDirectoryDTO);
|
||||
// not saving subdirs. saveToDB destroys data
|
||||
// await im.saveToDB(subDir);
|
||||
// await im.saveToDB(subDir2);
|
||||
@ -104,7 +104,7 @@ export class DBTestHelper {
|
||||
const dir = await gm.selectParentDir(connection, directory.name, path.join(path.dirname('.'), path.sep));
|
||||
await gm.fillParentDir(connection, dir);
|
||||
|
||||
const populateDir = async (d: DirectoryDTO) => {
|
||||
const populateDir = async (d: DirectoryBaseDTO) => {
|
||||
for (let i = 0; i < d.directories.length; i++) {
|
||||
d.directories[i] = await gm.selectParentDir(connection, d.directories[i].name,
|
||||
path.join(DiskMangerWorker.pathFromParent(d), path.sep));
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {DBTestHelper} from '../../../DBTestHelper';
|
||||
import {DirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import { ParentDirectoryDTO, SubDirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {TestHelper} from './TestHelper';
|
||||
import {ObjectManagers} from '../../../../../src/backend/model/ObjectManagers';
|
||||
import {PhotoDTO, PhotoMetadata} from '../../../../../src/common/entities/PhotoDTO';
|
||||
@ -40,9 +40,9 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
* |- p4
|
||||
*/
|
||||
|
||||
let dir: DirectoryDTO;
|
||||
let subDir: DirectoryDTO;
|
||||
let subDir2: DirectoryDTO;
|
||||
let dir: ParentDirectoryDTO;
|
||||
let subDir: SubDirectoryDTO;
|
||||
let subDir2: SubDirectoryDTO;
|
||||
let v: VideoDTO;
|
||||
let p: PhotoDTO;
|
||||
let p2: PhotoDTO;
|
||||
@ -51,7 +51,7 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
const setUpTestGallery = async (): Promise<void> => {
|
||||
const directory: DirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
const directory: ParentDirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
subDir = TestHelper.getDirectoryEntry(directory, 'The Phantom Menace');
|
||||
subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
||||
p = TestHelper.getRandomizedPhotoEntry(directory, 'Photo1');
|
||||
@ -78,20 +78,22 @@ describe('AlbumManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
const toAlbumPreview = (m: MediaDTO): MediaDTO => {
|
||||
const tmpM = m.directory.media;
|
||||
const tmpD = m.directory.directories;
|
||||
const tmpP = m.directory.preview;
|
||||
const tmpMT = m.directory.metaFile;
|
||||
delete m.directory.directories;
|
||||
delete m.directory.media;
|
||||
delete m.directory.preview;
|
||||
delete m.directory.metaFile;
|
||||
// generated dirs for test contain everything, not like return values from the server.
|
||||
const tmpDir: ParentDirectoryDTO = m.directory as ParentDirectoryDTO;
|
||||
const tmpM = tmpDir.media;
|
||||
const tmpD = tmpDir.directories;
|
||||
const tmpP = tmpDir.preview;
|
||||
const tmpMT = tmpDir.metaFile;
|
||||
delete tmpDir.directories;
|
||||
delete tmpDir.media;
|
||||
delete tmpDir.preview;
|
||||
delete tmpDir.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete (ret.metadata as PhotoMetadata).faces;
|
||||
m.directory.directories = tmpD;
|
||||
m.directory.media = tmpM;
|
||||
m.directory.preview = tmpP;
|
||||
m.directory.metaFile = tmpMT;
|
||||
tmpDir.directories = tmpD;
|
||||
tmpDir.media = tmpM;
|
||||
tmpDir.preview = tmpP;
|
||||
tmpDir.metaFile = tmpMT;
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
@ -2,7 +2,7 @@ import * as fs from 'fs';
|
||||
import {Config} from '../../../../../src/common/config/private/Config';
|
||||
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
||||
import {GalleryManager} from '../../../../../src/backend/model/database/sql/GalleryManager';
|
||||
import {DirectoryDTO, DirectoryDTOUtils} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {DirectoryBaseDTO, DirectoryDTOUtils, ParentDirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {TestHelper} from './TestHelper';
|
||||
import {Connection} from 'typeorm';
|
||||
import {DirectoryEntity} from '../../../../../src/backend/model/database/sql/enitites/DirectoryEntity';
|
||||
@ -42,11 +42,11 @@ class GalleryManagerTest extends GalleryManager {
|
||||
class IndexingManagerTest extends IndexingManager {
|
||||
|
||||
|
||||
public async queueForSave(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
public async queueForSave(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
return super.queueForSave(scannedDirectory);
|
||||
}
|
||||
|
||||
public async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
public async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
return await super.saveToDB(scannedDirectory);
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
await sqlHelper.clearDB();
|
||||
});
|
||||
|
||||
const setPartial = (dir: DirectoryDTO) => {
|
||||
const setPartial = (dir: DirectoryBaseDTO) => {
|
||||
if (!dir.preview && dir.media && dir.media.length > 0) {
|
||||
dir.preview = dir.media[0];
|
||||
}
|
||||
@ -82,7 +82,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
delete dir.media;
|
||||
};
|
||||
|
||||
const removeIds = (dir: DirectoryDTO) => {
|
||||
const removeIds = (dir: DirectoryBaseDTO) => {
|
||||
delete dir.id;
|
||||
dir.media.forEach((media: MediaDTO) => {
|
||||
delete media.id;
|
||||
@ -100,7 +100,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
}
|
||||
}
|
||||
if (dir.directories) {
|
||||
dir.directories.forEach((directory: DirectoryDTO) => {
|
||||
dir.directories.forEach((directory: DirectoryBaseDTO) => {
|
||||
removeIds(directory);
|
||||
});
|
||||
}
|
||||
@ -117,7 +117,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
p2.name = 'Test.jpg';
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -142,7 +142,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -169,9 +169,9 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent1);
|
||||
await im.saveToDB(Utils.clone(parent1));
|
||||
await im.saveToDB(Utils.clone(parent1) as ParentDirectoryDTO);
|
||||
DirectoryDTOUtils.packDirectory(parent2);
|
||||
await im.saveToDB(Utils.clone(parent2));
|
||||
await im.saveToDB(Utils.clone(parent2) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
{
|
||||
@ -198,7 +198,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
it('should select preview', async () => {
|
||||
const selectDirectory = async (gmTest: GalleryManagerTest, dir: DirectoryDTO) => {
|
||||
const selectDirectory = async (gmTest: GalleryManagerTest, dir: DirectoryBaseDTO): Promise<ParentDirectoryDTO> => {
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gmTest.selectParentDir(conn, dir.name, dir.path);
|
||||
await gmTest.fillParentDir(conn, selected);
|
||||
@ -225,9 +225,9 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
.to.deep.equalInAnyOrder(cloned);
|
||||
};
|
||||
|
||||
const saveToDBAndCheck = async (dir: DirectoryDTO) => {
|
||||
const saveToDBAndCheck = async (dir: DirectoryBaseDTO) => {
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(dir));
|
||||
await im.saveToDB(Utils.clone(dir) as ParentDirectoryDTO);
|
||||
await checkParent();
|
||||
DirectoryDTOUtils.unpackDirectory(parent);
|
||||
};
|
||||
@ -267,13 +267,13 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(subDir);
|
||||
await im.saveToDB(Utils.clone(subDir));
|
||||
await im.saveToDB(Utils.clone(subDir) as ParentDirectoryDTO);
|
||||
|
||||
parent.directories.push(subDir);
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -301,13 +301,13 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(subDir);
|
||||
await im.saveToDB(Utils.clone(subDir));
|
||||
await im.saveToDB(Utils.clone(subDir) as ParentDirectoryDTO);
|
||||
|
||||
parent.directories.push(subDir);
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -334,7 +334,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -372,7 +372,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -393,7 +393,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
const gpx = TestHelper.getRandomizedGPXEntry(parent, 'GPX1');
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
Config.Client.MetaFile.enabled = true;
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
Config.Client.MetaFile.enabled = false;
|
||||
const conn = await SQLConnection.getConnection();
|
||||
@ -419,13 +419,13 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
const sp1 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto1');
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2');
|
||||
const sp3 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto3');
|
||||
|
||||
DirectoryDTOUtils.packDirectory(subDir);
|
||||
await im.saveToDB(Utils.clone(subDir));
|
||||
await im.saveToDB(Utils.clone(subDir) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, subDir.name, subDir.path);
|
||||
@ -457,9 +457,9 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
const s1 = im.queueForSave(Utils.clone(parent));
|
||||
const s2 = im.queueForSave(Utils.clone(parent));
|
||||
const s3 = im.queueForSave(Utils.clone(parent));
|
||||
const s1 = im.queueForSave(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
const s2 = im.queueForSave(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
const s3 = im.queueForSave(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
await Promise.all([s1, s2, s3]);
|
||||
|
||||
@ -485,7 +485,7 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
const p2 = TestHelper.getRandomizedPhotoEntry(parent, 'Photo2');
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
|
||||
const conn = await SQLConnection.getConnection();
|
||||
const selected = await gm.selectParentDir(conn, parent.name, parent.path);
|
||||
@ -509,14 +509,14 @@ describe('IndexingManager', (sqlHelper: DBTestHelper) => {
|
||||
Config.Client.MetaFile.enabled = true;
|
||||
const parent = TestHelper.getRandomizedDirectoryEntry();
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(Utils.clone(parent));
|
||||
await im.saveToDB(Utils.clone(parent) as ParentDirectoryDTO);
|
||||
const subDir = TestHelper.getRandomizedDirectoryEntry(parent, 'subDir');
|
||||
for (let i = 0; i < 1500; i++) {
|
||||
TestHelper.getRandomizedPhotoEntry(subDir, 'p' + i);
|
||||
}
|
||||
|
||||
DirectoryDTOUtils.packDirectory(parent);
|
||||
await im.saveToDB(subDir);
|
||||
await im.saveToDB(subDir as ParentDirectoryDTO);
|
||||
|
||||
|
||||
const selected = await gm.selectParentDir(conn, subDir.name, subDir.path);
|
||||
|
@ -5,7 +5,7 @@ import {TestHelper} from './TestHelper';
|
||||
import {PhotoDTO} from '../../../../../src/common/entities/PhotoDTO';
|
||||
import {Utils} from '../../../../../src/common/Utils';
|
||||
import {PersonWithSampleRegion} from '../../../../../src/common/entities/PersonDTO';
|
||||
import {DirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {ParentDirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {VideoDTO} from '../../../../../src/common/entities/VideoDTO';
|
||||
import {SQLConnection} from '../../../../../src/backend/model/database/sql/SQLConnection';
|
||||
import {PersonEntry} from '../../../../../src/backend/model/database/sql/enitites/PersonEntry';
|
||||
@ -23,7 +23,7 @@ describe = DBTestHelper.describe();
|
||||
describe('PersonManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
let dir: DirectoryDTO;
|
||||
let dir: ParentDirectoryDTO;
|
||||
|
||||
let v: VideoDTO;
|
||||
let p: PhotoDTO;
|
||||
@ -34,7 +34,7 @@ describe('PersonManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
const setUpSqlDB = async () => {
|
||||
await sqlHelper.initDB();
|
||||
const directory: DirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
const directory: ParentDirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
p = TestHelper.getPhotoEntry1(directory);
|
||||
p2 = TestHelper.getPhotoEntry2(directory);
|
||||
const pFaceLessTmp = TestHelper.getPhotoEntry3(directory);
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
ToDateSearch
|
||||
} from '../../../../../src/common/entities/SearchQueryDTO';
|
||||
import {IndexingManager} from '../../../../../src/backend/model/database/sql/IndexingManager';
|
||||
import {DirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {DirectoryBaseDTO, ParentDirectoryDTO, SubDirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {TestHelper} from './TestHelper';
|
||||
import {ObjectManagers} from '../../../../../src/backend/model/ObjectManagers';
|
||||
import {GalleryManager} from '../../../../../src/backend/model/database/sql/GalleryManager';
|
||||
@ -51,7 +51,7 @@ describe = DBTestHelper.describe(); // fake it os IDE plays nicely (recognize th
|
||||
|
||||
class IndexingManagerTest extends IndexingManager {
|
||||
|
||||
public async saveToDB(scannedDirectory: DirectoryDTO): Promise<void> {
|
||||
public async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
return super.saveToDB(scannedDirectory);
|
||||
}
|
||||
}
|
||||
@ -89,9 +89,9 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
* |- p4
|
||||
*/
|
||||
|
||||
let dir: DirectoryDTO;
|
||||
let subDir: DirectoryDTO;
|
||||
let subDir2: DirectoryDTO;
|
||||
let dir: ParentDirectoryDTO;
|
||||
let subDir: SubDirectoryDTO;
|
||||
let subDir2: SubDirectoryDTO;
|
||||
let v: VideoDTO;
|
||||
let p: PhotoDTO;
|
||||
let p2: PhotoDTO;
|
||||
@ -101,7 +101,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
|
||||
|
||||
const setUpTestGallery = async (): Promise<void> => {
|
||||
const directory: DirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
const directory: ParentDirectoryDTO = TestHelper.getDirectoryEntry();
|
||||
subDir = TestHelper.getDirectoryEntry(directory, 'The Phantom Menace');
|
||||
subDir2 = TestHelper.getDirectoryEntry(directory, 'Return of the Jedi');
|
||||
p = TestHelper.getPhotoEntry1(directory);
|
||||
@ -198,30 +198,31 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
});
|
||||
|
||||
const searchifyMedia = <T extends FileDTO | PhotoDTO>(m: T): T => {
|
||||
const tmpM = m.directory.media;
|
||||
const tmpD = m.directory.directories;
|
||||
const tmpP = m.directory.preview;
|
||||
const tmpMT = m.directory.metaFile;
|
||||
delete m.directory.directories;
|
||||
delete m.directory.media;
|
||||
delete m.directory.preview;
|
||||
delete m.directory.metaFile;
|
||||
const tmpDir: DirectoryBaseDTO = m.directory as DirectoryBaseDTO;
|
||||
const tmpM = tmpDir.media;
|
||||
const tmpD = tmpDir.directories;
|
||||
const tmpP = tmpDir.preview;
|
||||
const tmpMT = tmpDir.metaFile;
|
||||
delete tmpDir.directories;
|
||||
delete tmpDir.media;
|
||||
delete tmpDir.preview;
|
||||
delete tmpDir.metaFile;
|
||||
const ret = Utils.clone(m);
|
||||
delete ret.directory.lastScanned;
|
||||
delete ret.directory.lastModified;
|
||||
delete ret.directory.mediaCount;
|
||||
delete (ret.directory as DirectoryBaseDTO).lastScanned;
|
||||
delete (ret.directory as DirectoryBaseDTO).lastModified;
|
||||
delete (ret.directory as DirectoryBaseDTO).mediaCount;
|
||||
if ((ret as PhotoDTO).metadata &&
|
||||
((ret as PhotoDTO).metadata as PhotoMetadata).faces && !((ret as PhotoDTO).metadata as PhotoMetadata).faces.length) {
|
||||
delete ((ret as PhotoDTO).metadata as PhotoMetadata).faces;
|
||||
}
|
||||
m.directory.directories = tmpD;
|
||||
m.directory.media = tmpM;
|
||||
m.directory.preview = tmpP;
|
||||
m.directory.metaFile = tmpMT;
|
||||
tmpDir.directories = tmpD;
|
||||
tmpDir.media = tmpM;
|
||||
tmpDir.preview = tmpP;
|
||||
tmpDir.metaFile = tmpMT;
|
||||
return ret;
|
||||
};
|
||||
|
||||
const searchifyDir = (d: DirectoryDTO): DirectoryDTO => {
|
||||
const searchifyDir = (d: DirectoryBaseDTO): DirectoryBaseDTO => {
|
||||
const tmpM = d.media;
|
||||
const tmpD = d.directories;
|
||||
const tmpP = d.preview;
|
||||
@ -242,7 +243,7 @@ describe('SearchManager', (sqlHelper: DBTestHelper) => {
|
||||
const removeDir = (result: SearchResultDTO) => {
|
||||
result.media = result.media.map(m => searchifyMedia(m));
|
||||
result.metaFile = result.metaFile.map(m => searchifyMedia(m));
|
||||
result.directories = result.directories.map(m => searchifyDir(m));
|
||||
result.directories = result.directories.map(m => searchifyDir(m) as SubDirectoryDTO);
|
||||
return Utils.clone(result);
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
PositionMetaData,
|
||||
PreviewPhotoDTO
|
||||
} from '../../../../../src/common/entities/PhotoDTO';
|
||||
import {DirectoryDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {DirectoryBaseDTO} from '../../../../../src/common/entities/DirectoryDTO';
|
||||
import {FileDTO} from '../../../../../src/common/entities/FileDTO';
|
||||
import {DiskMangerWorker} from '../../../../../src/backend/model/threading/DiskMangerWorker';
|
||||
|
||||
@ -26,7 +26,7 @@ export class TestHelper {
|
||||
|
||||
static creationCounter = 0;
|
||||
|
||||
public static getDirectoryEntry(parent: DirectoryDTO = null, name = 'wars dir'): DirectoryEntity {
|
||||
public static getDirectoryEntry(parent: DirectoryBaseDTO = null, name = 'wars dir'): DirectoryEntity {
|
||||
|
||||
const dir = new DirectoryEntity();
|
||||
dir.name = name;
|
||||
@ -45,7 +45,7 @@ export class TestHelper {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static getPhotoEntry(dir: DirectoryDTO): PhotoEntity {
|
||||
public static getPhotoEntry(dir: DirectoryBaseDTO): PhotoEntity {
|
||||
const sd = new MediaDimensionEntity();
|
||||
sd.height = 200;
|
||||
sd.width = 200;
|
||||
@ -91,7 +91,7 @@ export class TestHelper {
|
||||
return d;
|
||||
}
|
||||
|
||||
public static getVideoEntry(dir: DirectoryDTO): VideoEntity {
|
||||
public static getVideoEntry(dir: DirectoryBaseDTO): VideoEntity {
|
||||
const sd = new MediaDimensionEntity();
|
||||
sd.height = 200;
|
||||
sd.width = 200;
|
||||
@ -115,13 +115,13 @@ export class TestHelper {
|
||||
return d;
|
||||
}
|
||||
|
||||
public static getVideoEntry1(dir: DirectoryDTO): VideoEntity {
|
||||
public static getVideoEntry1(dir: DirectoryBaseDTO): VideoEntity {
|
||||
const p = TestHelper.getVideoEntry(dir);
|
||||
p.name = 'swVideo.mp4';
|
||||
return p;
|
||||
}
|
||||
|
||||
public static getPhotoEntry1(dir: DirectoryDTO): PhotoEntity {
|
||||
public static getPhotoEntry1(dir: DirectoryBaseDTO): PhotoEntity {
|
||||
const p = TestHelper.getPhotoEntry(dir);
|
||||
|
||||
p.metadata.caption = 'Han Solo\'s dice';
|
||||
@ -158,7 +158,7 @@ export class TestHelper {
|
||||
return p;
|
||||
}
|
||||
|
||||
public static getPhotoEntry2(dir: DirectoryDTO): PhotoEntity {
|
||||
public static getPhotoEntry2(dir: DirectoryBaseDTO): PhotoEntity {
|
||||
const p = TestHelper.getPhotoEntry(dir);
|
||||
|
||||
p.metadata.caption = 'Light saber';
|
||||
@ -190,7 +190,7 @@ export class TestHelper {
|
||||
return p;
|
||||
}
|
||||
|
||||
public static getPhotoEntry3(dir: DirectoryDTO): PhotoEntity {
|
||||
public static getPhotoEntry3(dir: DirectoryBaseDTO): PhotoEntity {
|
||||
const p = TestHelper.getPhotoEntry(dir);
|
||||
|
||||
p.metadata.caption = 'Amber stone';
|
||||
@ -218,7 +218,7 @@ export class TestHelper {
|
||||
return p;
|
||||
}
|
||||
|
||||
public static getPhotoEntry4(dir: DirectoryDTO): PhotoEntity {
|
||||
public static getPhotoEntry4(dir: DirectoryBaseDTO): PhotoEntity {
|
||||
const p = TestHelper.getPhotoEntry(dir);
|
||||
|
||||
p.metadata.caption = 'Millennium falcon';
|
||||
@ -250,9 +250,9 @@ export class TestHelper {
|
||||
return p;
|
||||
}
|
||||
|
||||
public static getRandomizedDirectoryEntry(parent: DirectoryDTO = null, forceStr: string = null): DirectoryDTO<MediaDTO> {
|
||||
public static getRandomizedDirectoryEntry(parent: DirectoryBaseDTO = null, forceStr: string = null): DirectoryBaseDTO<MediaDTO> {
|
||||
|
||||
const dir: DirectoryDTO = {
|
||||
const dir: DirectoryBaseDTO = {
|
||||
id: null,
|
||||
name: DiskMangerWorker.dirName(forceStr || Math.random().toString(36).substring(7)),
|
||||
path: DiskMangerWorker.pathFromParent({path: '', name: '.'}),
|
||||
@ -272,7 +272,7 @@ export class TestHelper {
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static getRandomizedGPXEntry(dir: DirectoryDTO, forceStr: string = null): FileDTO {
|
||||
public static getRandomizedGPXEntry(dir: DirectoryBaseDTO, forceStr: string = null): FileDTO {
|
||||
const d: FileDTO = {
|
||||
id: null,
|
||||
name: forceStr + '_' + Math.random().toString(36).substring(7) + '.gpx',
|
||||
@ -305,7 +305,7 @@ export class TestHelper {
|
||||
return f;
|
||||
}
|
||||
|
||||
public static getRandomizedPhotoEntry(dir: DirectoryDTO, forceStr: string = null, faces: number = 2): PhotoDTO {
|
||||
public static getRandomizedPhotoEntry(dir: DirectoryBaseDTO, forceStr: string = null, faces: number = 2): PhotoDTO {
|
||||
|
||||
|
||||
const rndStr = (): string => {
|
||||
@ -372,7 +372,7 @@ export class TestHelper {
|
||||
return p;
|
||||
}
|
||||
|
||||
static updatePreview(dir: DirectoryDTO): void {
|
||||
static updatePreview(dir: DirectoryBaseDTO): void {
|
||||
if (dir.media.length > 0) {
|
||||
dir.preview = dir.media.sort((a, b): number => b.metadata.creationDate - a.metadata.creationDate)[0];
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user