mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-02 09:12:07 +02:00
Creating onDBData change hook and refactoring album preview saving algorithm
This commit is contained in:
parent
bae5559356
commit
48ddb19f7f
@ -12,6 +12,8 @@ import {LocationManager} from './database/LocationManager';
|
||||
import {IAlbumManager} from './database/interfaces/IAlbumManager';
|
||||
import {JobManager} from './jobs/JobManager';
|
||||
import {IPreviewManager} from './database/interfaces/IPreviewManager';
|
||||
import {ParentDirectoryDTO} from '../../common/entities/DirectoryDTO';
|
||||
import {IObjectManager} from './database/interfaces/IObjectManager';
|
||||
|
||||
const LOG_TAG = '[ObjectManagers]';
|
||||
|
||||
@ -19,6 +21,7 @@ export class ObjectManagers {
|
||||
|
||||
private static instance: ObjectManagers = null;
|
||||
|
||||
private readonly managers: IObjectManager[];
|
||||
private galleryManager: IGalleryManager;
|
||||
private userManager: IUserManager;
|
||||
private searchManager: ISearchManager;
|
||||
@ -32,12 +35,20 @@ export class ObjectManagers {
|
||||
private albumManager: IAlbumManager;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.managers = [];
|
||||
}
|
||||
|
||||
get VersionManager(): IVersionManager {
|
||||
return this.versionManager;
|
||||
}
|
||||
|
||||
set VersionManager(value: IVersionManager) {
|
||||
if (this.versionManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.versionManager), 1);
|
||||
}
|
||||
this.versionManager = value;
|
||||
this.managers.push(this.versionManager);
|
||||
}
|
||||
|
||||
get LocationManager(): LocationManager {
|
||||
@ -45,7 +56,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set LocationManager(value: LocationManager) {
|
||||
if (this.locationManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.locationManager), 1);
|
||||
}
|
||||
this.locationManager = value;
|
||||
this.managers.push(this.locationManager);
|
||||
}
|
||||
|
||||
get AlbumManager(): IAlbumManager {
|
||||
@ -53,7 +68,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set AlbumManager(value: IAlbumManager) {
|
||||
if (this.albumManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.albumManager), 1);
|
||||
}
|
||||
this.albumManager = value;
|
||||
this.managers.push(this.albumManager);
|
||||
}
|
||||
|
||||
get PersonManager(): IPersonManager {
|
||||
@ -61,14 +80,23 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set PersonManager(value: IPersonManager) {
|
||||
if (this.personManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.personManager), 1);
|
||||
}
|
||||
this.personManager = value;
|
||||
this.managers.push(this.personManager);
|
||||
}
|
||||
|
||||
get PreviewManager(): IPreviewManager {
|
||||
return this.previewManager;
|
||||
}
|
||||
|
||||
set PreviewManager(value: IPreviewManager) {
|
||||
if (this.previewManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.previewManager), 1);
|
||||
}
|
||||
this.previewManager = value;
|
||||
this.managers.push(this.previewManager);
|
||||
}
|
||||
|
||||
get IndexingManager(): IIndexingManager {
|
||||
@ -76,7 +104,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set IndexingManager(value: IIndexingManager) {
|
||||
if (this.indexingManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.indexingManager), 1);
|
||||
}
|
||||
this.indexingManager = value;
|
||||
this.managers.push(this.indexingManager);
|
||||
}
|
||||
|
||||
|
||||
@ -85,7 +117,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set GalleryManager(value: IGalleryManager) {
|
||||
if (this.galleryManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.galleryManager), 1);
|
||||
}
|
||||
this.galleryManager = value;
|
||||
this.managers.push(this.galleryManager);
|
||||
}
|
||||
|
||||
get UserManager(): IUserManager {
|
||||
@ -93,7 +129,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set UserManager(value: IUserManager) {
|
||||
if (this.userManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.userManager), 1);
|
||||
}
|
||||
this.userManager = value;
|
||||
this.managers.push(this.userManager);
|
||||
}
|
||||
|
||||
get SearchManager(): ISearchManager {
|
||||
@ -101,7 +141,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set SearchManager(value: ISearchManager) {
|
||||
if (this.searchManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.searchManager), 1);
|
||||
}
|
||||
this.searchManager = value;
|
||||
this.managers.push(this.searchManager);
|
||||
}
|
||||
|
||||
get SharingManager(): ISharingManager {
|
||||
@ -109,7 +153,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set SharingManager(value: ISharingManager) {
|
||||
if (this.sharingManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.sharingManager), 1);
|
||||
}
|
||||
this.sharingManager = value;
|
||||
this.managers.push(this.sharingManager);
|
||||
}
|
||||
|
||||
get JobManager(): IJobManager {
|
||||
@ -117,7 +165,11 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
set JobManager(value: IJobManager) {
|
||||
if (this.jobManager) {
|
||||
this.managers.splice(this.managers.indexOf(this.jobManager), 1);
|
||||
}
|
||||
this.jobManager = value;
|
||||
this.managers.push(this.jobManager);
|
||||
}
|
||||
|
||||
public static getInstance(): ObjectManagers {
|
||||
@ -128,6 +180,7 @@ export class ObjectManagers {
|
||||
}
|
||||
|
||||
public static async reset(): Promise<void> {
|
||||
Logger.silly(LOG_TAG, 'Object manager reset begin');
|
||||
if (ObjectManagers.getInstance().IndexingManager &&
|
||||
ObjectManagers.getInstance().IndexingManager.IsSavingInProgress) {
|
||||
await ObjectManagers.getInstance().IndexingManager.SavingReady;
|
||||
@ -140,7 +193,6 @@ export class ObjectManagers {
|
||||
Logger.debug(LOG_TAG, 'Object manager reset');
|
||||
}
|
||||
|
||||
|
||||
public static async InitMemoryManagers(): Promise<void> {
|
||||
await ObjectManagers.reset();
|
||||
this.initManagers('memory');
|
||||
@ -168,4 +220,17 @@ export class ObjectManagers {
|
||||
ObjectManagers.getInstance().LocationManager = new LocationManager();
|
||||
}
|
||||
|
||||
public async onDataChange(changedDir: ParentDirectoryDTO = null): Promise<void> {
|
||||
await this.VersionManager.onNewDataVersion(changedDir);
|
||||
|
||||
for (const manager of this.managers) {
|
||||
if (manager === this.versionManager) {
|
||||
continue;
|
||||
}
|
||||
if (manager.onNewDataVersion) {
|
||||
await manager.onNewDataVersion(changedDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,8 +2,12 @@ import {GPSMetadata} from '../../../common/entities/PhotoDTO';
|
||||
import * as NodeGeocoder from 'node-geocoder';
|
||||
import {LocationLookupException} from '../../exceptions/LocationLookupException';
|
||||
import {LRU} from '../../../common/Utils';
|
||||
import {IObjectManager} from './interfaces/IObjectManager';
|
||||
import {ParentDirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
export class LocationManager {
|
||||
export class LocationManager implements IObjectManager {
|
||||
// onNewDataVersion only need for TypeScript, otherwise the interface is not implemented.
|
||||
readonly onNewDataVersion: (changedDir?: ParentDirectoryDTO) => Promise<void>;
|
||||
readonly geocoder: NodeGeocoder.Geocoder;
|
||||
cache = new LRU<GPSMetadata>(100);
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {SearchQueryDTO} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {AlbumBaseDTO} from '../../../../common/entities/album/AlbumBaseDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IAlbumManager {
|
||||
export interface IAlbumManager extends IObjectManager{
|
||||
/**
|
||||
* Creates a saved search type of album
|
||||
*/
|
||||
@ -27,5 +28,5 @@ export interface IAlbumManager {
|
||||
/**
|
||||
* Updates previews and album counts
|
||||
*/
|
||||
onGalleryIndexUpdate(): Promise<void>;
|
||||
onNewDataVersion(): Promise<void>;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IGalleryManager {
|
||||
export interface IGalleryManager extends IObjectManager {
|
||||
listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<ParentDirectoryDTO>;
|
||||
|
@ -1,10 +1,13 @@
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IIndexingManager {
|
||||
export interface IIndexingManager extends IObjectManager {
|
||||
SavingReady: Promise<void>;
|
||||
IsSavingInProgress: boolean;
|
||||
|
||||
indexDirectory(relativeDirectoryName: string): Promise<ParentDirectoryDTO>;
|
||||
|
||||
resetDB(): Promise<void>;
|
||||
|
||||
saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void>;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {JobProgressDTO} from '../../../../common/entities/job/JobProgressDTO';
|
||||
import {JobDTO} from '../../../../common/entities/job/JobDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IJobManager {
|
||||
export interface IJobManager extends IObjectManager {
|
||||
|
||||
|
||||
run(jobId: string, config: any, soloRun: boolean, allowParallelRun: boolean): Promise<void>;
|
||||
|
5
src/backend/model/database/interfaces/IObjectManager.ts
Normal file
5
src/backend/model/database/interfaces/IObjectManager.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import {ParentDirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
|
||||
export interface IObjectManager {
|
||||
onNewDataVersion?: (changedDir?: ParentDirectoryDTO) => Promise<void>;
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
import {PersonEntry} from '../sql/enitites/PersonEntry';
|
||||
import {PersonDTO} from '../../../../common/entities/PersonDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IPersonManager {
|
||||
export interface IPersonManager extends IObjectManager {
|
||||
getAll(): Promise<PersonEntry[]>;
|
||||
|
||||
get(name: string): Promise<PersonEntry>;
|
||||
|
||||
saveAll(names: string[]): Promise<void>;
|
||||
|
||||
onGalleryIndexUpdate(): Promise<void>;
|
||||
|
||||
updatePerson(name: string, partialPerson: PersonDTO): Promise<PersonEntry>;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {SavedSearchDTO} from '../../../../common/entities/album/SavedSearchDTO';
|
||||
import {PreviewPhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IPreviewManager {
|
||||
export interface IPreviewManager extends IObjectManager {
|
||||
getPreviewForDirectory(dir: { id: number, name: string, path: string }): Promise<PreviewPhotoDTOWithID>;
|
||||
|
||||
getAlbumPreview(album: SavedSearchDTO): Promise<PreviewPhotoDTOWithID>;
|
||||
|
@ -2,8 +2,9 @@ import {AutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {SearchQueryDTO, SearchQueryTypes} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface ISearchManager {
|
||||
export interface ISearchManager extends IObjectManager{
|
||||
autocomplete(text: string, type: SearchQueryTypes): Promise<AutoCompleteItem[]>;
|
||||
|
||||
search(query: SearchQueryDTO): Promise<SearchResultDTO>;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface ISharingManager {
|
||||
export interface ISharingManager extends IObjectManager {
|
||||
findOne(filter: any): Promise<SharingDTO>;
|
||||
|
||||
createSharing(sharing: SharingDTO): Promise<SharingDTO>;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
export interface IUserManager {
|
||||
export interface IUserManager extends IObjectManager {
|
||||
findOne(filter: any): Promise<UserDTO>;
|
||||
|
||||
find(filter: any): Promise<UserDTO[]>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
export interface IVersionManager {
|
||||
getDataVersion(): Promise<string>;
|
||||
import {IObjectManager} from './IObjectManager';
|
||||
|
||||
updateDataVersion(): Promise<void>;
|
||||
export interface IVersionManager extends IObjectManager {
|
||||
getDataVersion(): Promise<string>;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ export class AlbumManager implements IAlbumManager {
|
||||
'directory.path']).getMany();
|
||||
}
|
||||
|
||||
public async onGalleryIndexUpdate(): Promise<void> {
|
||||
public async onNewDataVersion(): Promise<void> {
|
||||
await this.updateAlbums();
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
|
||||
// not indexed since a while, index it in a lazy manner
|
||||
if ((Date.now() - dir.lastScanned > Config.Server.Indexing.cachedFolderTimeout &&
|
||||
Config.Server.Indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) ||
|
||||
Config.Server.Indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) ||
|
||||
Config.Server.Indexing.reIndexingSensitivity >= ReIndexingSensitivity.high) {
|
||||
// on the fly reindexing
|
||||
|
||||
@ -224,7 +224,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
dir.media = [];
|
||||
dir.preview = await ObjectManagers.getInstance().PreviewManager.getPreviewForDirectory(dir);
|
||||
dir.isPartial = true;
|
||||
|
||||
|
||||
if (dir.preview) {
|
||||
dir.preview.readyThumbnails = [];
|
||||
dir.preview.readyIcon = false;
|
||||
|
@ -95,6 +95,23 @@ export class IndexingManager implements IIndexingManager {
|
||||
.execute();
|
||||
}
|
||||
|
||||
public async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
this.isSaving = true;
|
||||
try {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const serverSideConfigs = scannedDirectory.metaFile.filter(m => !!ServerPG2ConfMap[m.name]);
|
||||
scannedDirectory.metaFile = scannedDirectory.metaFile.filter(m => !ServerPG2ConfMap[m.name]);
|
||||
const currentDirId: number = await this.saveParentDir(connection, scannedDirectory);
|
||||
await this.saveChildDirs(connection, currentDirId, scannedDirectory);
|
||||
await this.saveMedia(connection, currentDirId, scannedDirectory.media);
|
||||
await this.saveMetaFiles(connection, currentDirId, scannedDirectory);
|
||||
await IndexingManager.processServerSidePG2Conf(serverSideConfigs);
|
||||
await ObjectManagers.getInstance().onDataChange(scannedDirectory);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Todo fix it, once typeorm support connection pools for sqlite
|
||||
/**
|
||||
* Queues up a directory to save to the DB.
|
||||
@ -359,25 +376,6 @@ export class IndexingManager implements IIndexingManager {
|
||||
|
||||
}
|
||||
|
||||
protected async saveToDB(scannedDirectory: ParentDirectoryDTO): Promise<void> {
|
||||
this.isSaving = true;
|
||||
try {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const serverSideConfigs = scannedDirectory.metaFile.filter(m => !!ServerPG2ConfMap[m.name]);
|
||||
scannedDirectory.metaFile = scannedDirectory.metaFile.filter(m => !ServerPG2ConfMap[m.name]);
|
||||
const currentDirId: number = await this.saveParentDir(connection, scannedDirectory);
|
||||
await this.saveChildDirs(connection, currentDirId, scannedDirectory);
|
||||
await this.saveMedia(connection, currentDirId, scannedDirectory.media);
|
||||
await this.saveMetaFiles(connection, currentDirId, scannedDirectory);
|
||||
await ObjectManagers.getInstance().PersonManager.onGalleryIndexUpdate();
|
||||
await ObjectManagers.getInstance().AlbumManager.onGalleryIndexUpdate();
|
||||
await ObjectManagers.getInstance().VersionManager.updateDataVersion();
|
||||
await IndexingManager.processServerSidePG2Conf(serverSideConfigs);
|
||||
} finally {
|
||||
this.isSaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
private async saveChunk<T>(repository: Repository<any>, entities: T[], size: number): Promise<T[]> {
|
||||
if (entities.length === 0) {
|
||||
return [];
|
||||
|
@ -77,7 +77,7 @@ export class PersonManager implements ISQLPersonManager {
|
||||
|
||||
}
|
||||
|
||||
public async onGalleryIndexUpdate(): Promise<void> {
|
||||
public async onNewDataVersion(): Promise<void> {
|
||||
await this.updateCounts();
|
||||
await this.updateSamplePhotos();
|
||||
await this.loadAll();
|
||||
|
@ -16,7 +16,7 @@ export class VersionManager implements IVersionManager {
|
||||
|
||||
async getDataVersion(): Promise<string> {
|
||||
if (this.latestDirectoryStatus === null) {
|
||||
await this.updateDataVersion();
|
||||
await this.onNewDataVersion();
|
||||
}
|
||||
|
||||
if (!this.latestDirectoryStatus) {
|
||||
@ -31,7 +31,7 @@ export class VersionManager implements IVersionManager {
|
||||
return crypto.createHash('md5').update(versionString).digest('hex');
|
||||
}
|
||||
|
||||
async updateDataVersion(): Promise<void> {
|
||||
async onNewDataVersion(): Promise<void> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const dir = await connection.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder('directory')
|
||||
|
@ -5,7 +5,6 @@ import {SQLConnection} from '../../src/backend/model/database/sql/SQLConnection'
|
||||
import {DatabaseType} from '../../src/common/config/private/PrivateConfig';
|
||||
import {ProjectPath} from '../../src/backend/ProjectPath';
|
||||
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';
|
||||
import {IndexingManager} from '../../src/backend/model/database/sql/IndexingManager';
|
||||
@ -89,8 +88,7 @@ export class DBTestHelper {
|
||||
ObjectManagers.getInstance().IndexingManager.indexDirectory = () => Promise.resolve(null);
|
||||
|
||||
|
||||
const im = new IndexingManagerTest();
|
||||
await im.saveToDB(directory as ParentDirectoryDTO);
|
||||
await ObjectManagers.getInstance().IndexingManager.saveToDB(directory as ParentDirectoryDTO);
|
||||
// not saving subdirs. saveToDB destroys data
|
||||
// await im.saveToDB(subDir);
|
||||
// await im.saveToDB(subDir2);
|
||||
|
Loading…
Reference in New Issue
Block a user