From 849a081cba85294af5f0d834f63e2dff08dc525e Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Thu, 17 Jan 2019 20:17:17 +0100 Subject: [PATCH] implementing duplicate backend --- backend/middlewares/AdminMWs.ts | 19 +++++++++++++++++++ backend/model/sql/GalleryManager.ts | 21 ++++++++++++++++++--- backend/model/sql/IGalleryManager.ts | 3 +++ backend/model/threading/MetadataLoader.ts | 2 +- backend/routes/AdminRouter.ts | 9 +++++++++ 5 files changed, 50 insertions(+), 4 deletions(-) diff --git a/backend/middlewares/AdminMWs.ts b/backend/middlewares/AdminMWs.ts index c3d49386..1984ae17 100644 --- a/backend/middlewares/AdminMWs.ts +++ b/backend/middlewares/AdminMWs.ts @@ -42,6 +42,25 @@ export class AdminMWs { } } + + public static async getDuplicates(req: Request, res: Response, next: NextFunction) { + if (Config.Server.database.type === DatabaseType.memory) { + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Statistic is only available for indexed content')); + } + + + const galleryManager = ObjectManagerRepository.getInstance().GalleryManager; + try { + req.resultPipe = await galleryManager.getPossibleDuplicates(); + return next(); + } catch (err) { + if (err instanceof Error) { + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error while getting duplicates: ' + err.toString(), err)); + } + return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error while getting duplicates', err)); + } + } + public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction) { if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) { diff --git a/backend/model/sql/GalleryManager.ts b/backend/model/sql/GalleryManager.ts index ae13d468..7d2dae52 100644 --- a/backend/model/sql/GalleryManager.ts +++ b/backend/model/sql/GalleryManager.ts @@ -169,6 +169,22 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { .getCount(); } + public async getPossibleDuplicates() { + const connection = await SQLConnection.getConnection(); + const mediaRepository = connection.getRepository(MediaEntity); + + const duplicates = await mediaRepository.createQueryBuilder('media') + .innerJoin(query => query.from(MediaEntity, 'innerMedia') + .select(['innerMedia.name as name', 'innerMedia.metadata.fileSize as fileSize', 'count(*)']) + .groupBy('innerMedia.name, innerMedia.metadata.fileSize') + .having('count(*)>1'), + 'innerMedia', + 'media.name=innerMedia.name AND media.metadata.fileSize = innerMedia.fileSize') + .innerJoinAndSelect('media.directory', 'directory').getMany(); + return duplicates; + + } + protected async selectParentDir(connection: Connection, directoryName: string, directoryParent: string): Promise { const query = connection .getRepository(DirectoryEntity) @@ -196,9 +212,9 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { directory: dir.id }) .leftJoinAndSelect('face.person', 'person') - .select(['face.id', 'face.box.x', + .select(['face.id', 'face.box.x', 'face.box.y', 'face.box.width', 'face.box.height', - 'media.id', 'person.name', 'person.id']) + 'media.id', 'person.name', 'person.id']) .getMany(); for (let i = 0; i < dir.media.length; i++) { dir.media[i].directory = dir; @@ -232,5 +248,4 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager { } } - } diff --git a/backend/model/sql/IGalleryManager.ts b/backend/model/sql/IGalleryManager.ts index 80db0ae5..5f01f269 100644 --- a/backend/model/sql/IGalleryManager.ts +++ b/backend/model/sql/IGalleryManager.ts @@ -1,5 +1,6 @@ import {DirectoryDTO} from '../../../common/entities/DirectoryDTO'; import {IGalleryManager} from '../interfaces/IGalleryManager'; +import {MediaEntity} from './enitites/MediaEntity'; export interface ISQLGalleryManager extends IGalleryManager { listDirectory(relativeDirectoryName: string, @@ -13,4 +14,6 @@ export interface ISQLGalleryManager extends IGalleryManager { countVideos(): Promise; countMediaSize(): Promise; + + getPossibleDuplicates(): Promise; } diff --git a/backend/model/threading/MetadataLoader.ts b/backend/model/threading/MetadataLoader.ts index 34af8896..dea09323 100644 --- a/backend/model/threading/MetadataLoader.ts +++ b/backend/model/threading/MetadataLoader.ts @@ -166,7 +166,7 @@ export class MetadataLoader { metadata.creationDate = (iptcData.date_time ? iptcData.date_time.getTime() : metadata.creationDate); } catch (err) { - Logger.debug(LOG_TAG, 'Error parsing iptc data', fullPath, err); + // Logger.debug(LOG_TAG, 'Error parsing iptc data', fullPath, err); } metadata.creationDate = metadata.creationDate || 0; diff --git a/backend/routes/AdminRouter.ts b/backend/routes/AdminRouter.ts index 5993c66e..ea6b165e 100644 --- a/backend/routes/AdminRouter.ts +++ b/backend/routes/AdminRouter.ts @@ -8,6 +8,7 @@ export class AdminRouter { public static route(app: Express) { this.addGetStatistic(app); + this.addGetDuplicates(app); this.addIndexGallery(app); this.addSettings(app); } @@ -20,6 +21,14 @@ export class AdminRouter { RenderingMWs.renderResult ); } + private static addGetDuplicates(app: Express) { + app.get('/api/admin/duplicates', + AuthenticationMWs.authenticate, + AuthenticationMWs.authorise(UserRoles.Admin), + AdminMWs.getDuplicates, + RenderingMWs.renderResult + ); + } private static addIndexGallery(app: Express) { app.get('/api/admin/indexes/job/progress',