diff --git a/benchmark/Benchmark.ts b/benchmark/Benchmark.ts index 2624fd1b..8083c13e 100644 --- a/benchmark/Benchmark.ts +++ b/benchmark/Benchmark.ts @@ -1,29 +1,82 @@ import {BenchmarkResult} from './BenchmarkRunner'; import {ContentWrapper} from '../src/common/entities/ConentWrapper'; +import {Express} from 'express'; +import {Utils} from '../src/common/Utils'; +import {Message} from '../src/common/entities/Message'; export interface BenchmarkStep { name: string; fn: ((input?: any) => Promise); } +/** + * This class converts PiGallery2 Routers to benchamrkable steps to the Benchmark class + */ +class BMExpressApp { + readonly benchmark: Benchmark; + + + constructor(benchmark: Benchmark) { + this.benchmark = benchmark; + } + + get(match: string | string[], ...functions: ((req: any, res: any, next: Function) => void)[]) { + functions.forEach(f => { + this.benchmark.addAStep({ + name: this.camelToSpaceSeparated(f.name), + fn: (request: any) => this.nextToPromise(f, request) + }); + }); + } + + private camelToSpaceSeparated(text: string) { + const result = (text.replace(/([A-Z])/g, ' $1')).toLocaleLowerCase(); + return result.charAt(0).toUpperCase() + result.slice(1); + } + + private nextToPromise(fn: (req: any, res: any, next: Function) => void, request: any) { + return new Promise((resolve, reject) => { + const response = { + header: () => { + }, + json: (data: any) => { + resolve(data); + } + }; + fn(request, response, (err?: any) => { + if (err) { + return reject(err); + } + resolve(request.resultPipe); + }); + }); + } +} + export class Benchmark { steps: BenchmarkStep[] = []; name: string; - inputCB: () => any; + request: any; beforeEach: () => Promise; afterEach: () => Promise; + private readonly bmExpressApp: BMExpressApp; constructor(name: string, - inputCB?: () => any, + request: any = {}, beforeEach?: () => Promise, afterEach?: () => Promise) { this.name = name; - this.inputCB = inputCB; + this.request = request; this.beforeEach = beforeEach; this.afterEach = afterEach; + this.bmExpressApp = new BMExpressApp(this); + } + + get BmExpressApp(): Express { + return (this.bmExpressApp) as Express; } async run(RUNS: number): Promise { @@ -63,7 +116,7 @@ export class Benchmark { return ret; } - outputToBMResult(name: string, output: any[] | ContentWrapper): BenchmarkResult { + outputToBMResult(name: string, output: any[] | ContentWrapper | Message): BenchmarkResult { if (output) { if (Array.isArray(output)) { return { @@ -73,13 +126,31 @@ export class Benchmark { }; } - if (output.directory || output.searchResult) { + if (output instanceof ContentWrapper) { return { name: name, duration: null, contentWrapper: output }; } + if (output instanceof Message) { + const msg = output.result; + if (Array.isArray(msg)) { + return { + name: name, + duration: null, + items: msg.length, + }; + } + + if (msg instanceof ContentWrapper) { + return { + name: name, + duration: null, + contentWrapper: msg + }; + } + } } return { @@ -89,7 +160,7 @@ export class Benchmark { } async scanSteps(): Promise { - let pipe = this.inputCB ? this.inputCB() : null; + const request = Utils.clone(this.request); const stepOutput = new Array(this.steps.length); for (let j = 0; j < this.steps.length; ++j) { @@ -97,9 +168,8 @@ export class Benchmark { await this.beforeEach(); } for (let i = 0; i <= j; ++i) { - pipe = await this.steps[i].fn(pipe); + stepOutput[j] = await this.steps[i].fn(request); } - stepOutput[j] = pipe; if (this.afterEach) { await this.afterEach(); } @@ -108,10 +178,10 @@ export class Benchmark { } async runOneRound(stepTimer: number[]): Promise { - let pipe = this.inputCB ? this.inputCB() : null; + const request = Utils.clone(this.request); for (let i = 0; i < this.steps.length; ++i) { const start = process.hrtime(); - pipe = await this.steps[i].fn(pipe); + await this.steps[i].fn(request); const end = process.hrtime(start); stepTimer[i] += (end[0] * 1000 + end[1] / 1000000); } diff --git a/benchmark/BenchmarkRunner.ts b/benchmark/BenchmarkRunner.ts index 2c47e49a..6409a0ac 100644 --- a/benchmark/BenchmarkRunner.ts +++ b/benchmark/BenchmarkRunner.ts @@ -2,7 +2,6 @@ import {Config} from '../src/common/config/private/Config'; import {ObjectManagers} from '../src/backend/model/ObjectManagers'; import {DiskMangerWorker} from '../src/backend/model/threading/DiskMangerWorker'; import {IndexingManager} from '../src/backend/model/database/sql/IndexingManager'; -import {SearchManager} from '../src/backend/model/database/sql/SearchManager'; import * as util from 'util'; import * as path from 'path'; import * as rimraf from 'rimraf'; @@ -11,18 +10,18 @@ import {Utils} from '../src/common/Utils'; import {DirectoryDTO} from '../src/common/entities/DirectoryDTO'; import {ServerConfig} from '../src/common/config/private/PrivateConfig'; import {ProjectPath} from '../src/backend/ProjectPath'; -import {PersonMWs} from '../src/backend/middlewares/PersonMWs'; -import {ThumbnailGeneratorMWs} from '../src/backend/middlewares/thumbnail/ThumbnailGeneratorMWs'; import {Benchmark} from './Benchmark'; import {IndexingJob} from '../src/backend/model/jobs/jobs/IndexingJob'; import {IJob} from '../src/backend/model/jobs/jobs/IJob'; import {JobProgressStates} from '../src/common/entities/job/JobProgressDTO'; import {JobProgress} from '../src/backend/model/jobs/jobs/JobProgress'; -import {GalleryMWs} from '../src/backend/middlewares/GalleryMWs'; -import {UserDTO, UserRoles} from '../src/common/entities/UserDTO'; import {ContentWrapper} from '../src/common/entities/ConentWrapper'; import {GalleryManager} from '../src/backend/model/database/sql/GalleryManager'; import {PersonManager} from '../src/backend/model/database/sql/PersonManager'; +import {GalleryRouter} from '../src/backend/routes/GalleryRouter'; +import {Express} from 'express'; +import {PersonRouter} from '../src/backend/routes/PersonRouter'; +import {QueryParams} from '../src/common/QueryParams'; const rimrafPR = util.promisify(rimraf); @@ -41,18 +40,49 @@ export class BMIndexingManager extends IndexingManager { } } + +class BMGalleryRouter extends GalleryRouter { + public static addDirectoryList(app: Express) { + GalleryRouter.addDirectoryList(app); + } + + public static addSearch(app: Express) { + GalleryRouter.addSearch(app); + } + + public static addInstantSearch(app: Express) { + GalleryRouter.addInstantSearch(app); + } + + public static addAutoComplete(app: Express) { + GalleryRouter.addAutoComplete(app); + } +} + +class BMPersonRouter extends PersonRouter { + public static addGetPersons(app: Express) { + PersonRouter.addGetPersons(app); + } +} + export class BenchmarkRunner { inited = false; - private biggestPath: string = null; + private biggestDirPath: string = null; + private readonly requestTemplate: any = { + requestPipe: null, + params: {}, + query: {}, + session: {} + }; constructor(public RUNS: number) { - + Config.Client.authenticationRequired = false; } async bmSaveDirectory(): Promise { await this.init(); await this.resetDB(); - const dir = await DiskMangerWorker.scanDirectory(this.biggestPath); + const dir = await DiskMangerWorker.scanDirectory(this.biggestDirPath); const bm = new Benchmark('Saving directory to DB', null, () => this.resetDB()); bm.addAStep({ name: 'Saving directory to DB', @@ -69,7 +99,7 @@ export class BenchmarkRunner { const bm = new Benchmark('Scanning directory'); bm.addAStep({ name: 'Scanning directory', - fn: async () => new ContentWrapper(await DiskMangerWorker.scanDirectory(this.biggestPath)) + fn: async () => new ContentWrapper(await DiskMangerWorker.scanDirectory(this.biggestDirPath)) }); return await bm.run(this.RUNS); } @@ -78,50 +108,25 @@ export class BenchmarkRunner { await this.init(); await this.setupDB(); Config.Server.Indexing.reIndexingSensitivity = ServerConfig.ReIndexingSensitivity.low; - const bm = new Benchmark('List directory', - null, + const req = Utils.clone(this.requestTemplate); + req.params.directory = this.biggestDirPath; + const bm = new Benchmark('List directory', req, async () => { await ObjectManagers.reset(); await ObjectManagers.InitSQLManagers(); }); - bm.addAStep({ - name: 'List directory', - fn: (input) => this.nextToPromise(GalleryMWs.listDirectory, input, {directory: this.biggestPath}) - }); - bm.addAStep({ - name: 'Add Thumbnail information', - fn: (input) => this.nextToPromise(ThumbnailGeneratorMWs.addThumbnailInformation, input) - }); - bm.addAStep({ - name: 'Clean Up Gallery Result', - fn: (input) => this.nextToPromise(GalleryMWs.cleanUpGalleryResults, input) - }); + BMGalleryRouter.addDirectoryList(bm.BmExpressApp); return await bm.run(this.RUNS); } async bmListPersons(): Promise { await this.setupDB(); Config.Server.Indexing.reIndexingSensitivity = ServerConfig.ReIndexingSensitivity.low; - const bm = new Benchmark('Listing Faces', null, async () => { + const bm = new Benchmark('Listing Faces', Utils.clone(this.requestTemplate), async () => { await ObjectManagers.reset(); await ObjectManagers.InitSQLManagers(); }); - bm.addAStep({ - name: 'List Persons', - fn: (input) => this.nextToPromise(PersonMWs.listPersons, input) - }); - bm.addAStep({ - name: 'Add sample photo', - fn: (input) => this.nextToPromise(PersonMWs.addSamplePhotoForAll, input) - }); - bm.addAStep({ - name: 'Add thumbnail info', - fn: (input) => this.nextToPromise(ThumbnailGeneratorMWs.addThumbnailInfoForPersons, input) - }); - bm.addAStep({ - name: 'Remove sample photo', - fn: (input) => this.nextToPromise(PersonMWs.removeSamplePhotoForAll, input) - }); + BMPersonRouter.addGetPersons(bm.BmExpressApp); return await bm.run(this.RUNS); } @@ -131,14 +136,12 @@ export class BenchmarkRunner { const results: { result: BenchmarkResult, searchType: SearchTypes }[] = []; for (let i = 0; i < types.length; i++) { - const bm = new Benchmark('Searching'); - bm.addAStep({ - name: 'Searching', - fn: async () => { - const sm = new SearchManager(); - return new ContentWrapper(null, await sm.search(text, types[i])); - } - }); + const req = Utils.clone(this.requestTemplate); + req.params.text = text; + req.query[QueryParams.gallery.search.type] = types[i]; + const bm = new Benchmark('Searching for `' + text + '` as `' + (types[i] ? SearchTypes[types[i]] : 'any') + '`', req); + BMGalleryRouter.addSearch(bm.BmExpressApp); + results.push({result: await bm.run(this.RUNS), searchType: types[i]}); } return results; @@ -146,27 +149,19 @@ export class BenchmarkRunner { async bmInstantSearch(text: string): Promise { await this.setupDB(); - const bm = new Benchmark('Instant search'); - bm.addAStep({ - name: 'Instant search', - fn: async () => { - const sm = new SearchManager(); - return new ContentWrapper(null, await sm.instantSearch(text)); - } - }); + const req = Utils.clone(this.requestTemplate); + req.params.text = text; + const bm = new Benchmark('Instant search for `' + text + '`', req); + BMGalleryRouter.addInstantSearch(bm.BmExpressApp); return await bm.run(this.RUNS); } async bmAutocomplete(text: string): Promise { await this.setupDB(); - const bm = new Benchmark('Auto complete'); - bm.addAStep({ - name: 'Auto complete', - fn: () => { - const sm = new SearchManager(); - return sm.autocomplete(text); - } - }); + const req = Utils.clone(this.requestTemplate); + req.params.text = text; + const bm = new Benchmark('Auto complete for `' + text + '`', req); + BMGalleryRouter.addAutoComplete(bm.BmExpressApp); return await bm.run(this.RUNS); } @@ -175,19 +170,11 @@ export class BenchmarkRunner { const gm = new GalleryManager(); const pm = new PersonManager(); - const renderDataSize = (size: number) => { - const postFixes = ['B', 'KB', 'MB', 'GB', 'TB']; - let index = 0; - while (size > 1000 && index < postFixes.length - 1) { - size /= 1000; - index++; - } - return size.toFixed(2) + postFixes[index]; - }; + return 'directories: ' + await gm.countDirectories() + ', photos: ' + await gm.countPhotos() + ', videos: ' + await gm.countVideos() + - ', diskUsage : ' + renderDataSize(await gm.countMediaSize()) + + ', diskUsage : ' + Utils.renderDataSize(await gm.countMediaSize()) + ', persons : ' + await pm.countFaces() + ', unique persons (faces): ' + (await pm.getAll()).length; @@ -210,30 +197,14 @@ export class BenchmarkRunner { biggest = dir.media.length; } } - this.biggestPath = biggestPath; - console.log('updating path of biggest dir to: ' + this.biggestPath); + this.biggestDirPath = biggestPath; + console.log('updating path of biggest dir to: ' + this.biggestDirPath); this.inited = true; } - return this.biggestPath; + return this.biggestDirPath; } - private nextToPromise(fn: (req: any, res: any, next: Function) => void, input?: any, params = {}) { - return new Promise((resolve, reject) => { - const request = { - resultPipe: input, - params: params, - query: {}, - session: {user: {name: UserRoles[UserRoles.Admin], role: UserRoles.Admin}} - }; - fn(request, resolve, (err?: any) => { - if (err) { - return reject(err); - } - resolve(request.resultPipe); - }); - }); - } private resetDB = async () => { Config.Server.Threading.enabled = false; diff --git a/benchmark/README.md b/benchmark/README.md index 46edac06..c9856395 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -2,6 +2,8 @@ These results are created mostly for development, but the results are public for curious users. + + ## PiGallery2 v1.5.8, 26.01.2019 **System**: Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz, 16GB Ram, SHDD: 1TB, 5400 rpm diff --git a/benchmark/index.ts b/benchmark/index.ts index 62e017a1..b4947bdb 100644 --- a/benchmark/index.ts +++ b/benchmark/index.ts @@ -1,7 +1,6 @@ import {Config} from '../src/common/config/private/Config'; import {ProjectPath} from '../src/backend/ProjectPath'; import {BenchmarkResult, BenchmarkRunner} from './BenchmarkRunner'; -import {SearchTypes} from '../src/common/entities/AutoCompleteItem'; import {Utils} from '../src/common/Utils'; import {BMConfig} from './BMConfig'; @@ -28,10 +27,10 @@ const printHeader = async (statistic: string) => { const printTableHeader = () => { - printLine('| Action | Sub action | Action details | Average Duration | Details |'); - printLine('|:------:|:----------:|:--------------:|:----------------:|:-------:|'); + printLine('| Action | Sub action | Average Duration | Result |'); + printLine('|:------:|:----------:|:----------------:|:-------:|'); }; -const printResult = (result: BenchmarkResult, actionDetails: string = '', isSubResult = false) => { +const printResult = (result: BenchmarkResult, isSubResult = false) => { console.log('benchmarked: ' + result.name); let details = '-'; if (result.items) { @@ -47,15 +46,13 @@ const printResult = (result: BenchmarkResult, actionDetails: string = '', isSubR } } if (isSubResult) { - printLine('| | ' + result.name + ' | ' + actionDetails + - ' | ' + (result.duration).toFixed(1) + ' ms | ' + details + ' |'); + printLine('| | ' + result.name + ' | ' + (result.duration).toFixed(1) + ' ms | ' + details + ' |'); } else { - printLine('| **' + result.name + '** | | **' + actionDetails + - '** | **' + (result.duration).toFixed(1) + ' ms** | **' + details + '** |'); + printLine('| **' + result.name + '** | | **' + (result.duration).toFixed(1) + ' ms** | **' + details + '** |'); } if (result.subBenchmarks && result.subBenchmarks.length > 1) { for (let i = 0; i < result.subBenchmarks.length; i++) { - printResult(result.subBenchmarks[i], '', true); + printResult(result.subBenchmarks[i], true); } } }; @@ -73,15 +70,9 @@ const run = async () => { printResult(await bm.bmSaveDirectory()); printResult(await bm.bmListDirectory()); printResult(await bm.bmListPersons()); - (await bm.bmAllSearch('a')).forEach(res => { - if (res.searchType !== null) { - printResult(res.result, '`a` as `' + SearchTypes[res.searchType] + '`'); - } else { - printResult(res.result, '`a` as `any`'); - } - }); - printResult(await bm.bmInstantSearch('a'), '`a`'); - printResult(await bm.bmAutocomplete('a'), '`a`'); + (await bm.bmAllSearch('a')).forEach(res => printResult(res.result)); + printResult(await bm.bmInstantSearch('a')); + printResult(await bm.bmAutocomplete('a')); printLine('*Measurements run ' + RUNS + ' times and an average was calculated.'); console.log(resultsText); console.log('run for : ' + ((Date.now() - start)).toFixed(1) + 'ms'); diff --git a/src/backend/middlewares/user/AuthenticationMWs.ts b/src/backend/middlewares/user/AuthenticationMWs.ts index e62d85c2..75dde4b1 100644 --- a/src/backend/middlewares/user/AuthenticationMWs.ts +++ b/src/backend/middlewares/user/AuthenticationMWs.ts @@ -57,14 +57,14 @@ export class AuthenticationMWs { public static normalizePathParam(paramName: string) { - return (req: Request, res: Response, next: NextFunction) => { + return function normalizePathParam(req: Request, res: Response, next: NextFunction) { req.params[paramName] = path.normalize(req.params[paramName] || path.sep).replace(/^(\.\.[\/\\])+/, ''); return next(); }; } public static authorisePath(paramName: string, isDirectory: boolean) { - return (req: Request, res: Response, next: NextFunction) => { + return function authorisePath(req: Request, res: Response, next: NextFunction) { let p: string = req.params[paramName]; if (!isDirectory) { p = path.dirname(p); @@ -80,7 +80,7 @@ export class AuthenticationMWs { public static authorise(role: UserRoles) { - return (req: Request, res: Response, next: NextFunction) => { + return function authorise(req: Request, res: Response, next: NextFunction) { if (req.session.user.role < role) { return next(new ErrorDTO(ErrorCodes.NOT_AUTHORISED)); } diff --git a/src/backend/routes/GalleryRouter.ts b/src/backend/routes/GalleryRouter.ts index 962c32da..6ddca2e1 100644 --- a/src/backend/routes/GalleryRouter.ts +++ b/src/backend/routes/GalleryRouter.ts @@ -29,12 +29,15 @@ export class GalleryRouter { this.addAutoComplete(app); } - private static addDirectoryList(app: Express) { + protected static addDirectoryList(app: Express) { app.get(['/api/gallery/content/:directory(*)', '/api/gallery/', '/api/gallery//'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('directory'), AuthenticationMWs.authorisePath('directory', true), VersionMWs.injectGalleryVersion, + + // specific part GalleryMWs.listDirectory, ThumbnailGeneratorMWs.addThumbnailInformation, GalleryMWs.cleanUpGalleryResults, @@ -43,85 +46,109 @@ export class GalleryRouter { } - private static addGetImage(app: Express) { + protected static addGetImage(app: Express) { app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Photos.join('|') + '))'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, RenderingMWs.renderFile ); } - private static addGetBestFitImage(app: Express) { + protected static addGetBestFitImage(app: Express) { app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Photos.join('|') + '))/bestFit'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, PhotoConverterMWs.convertPhoto, RenderingMWs.renderFile ); } - private static addGetVideo(app: Express) { + protected static addGetVideo(app: Express) { app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Videos.join('|') + '))'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, RenderingMWs.renderFile ); } - private static addGetBestFitVideo(app: Express) { + protected static addGetBestFitVideo(app: Express) { app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Videos.join('|') + '))/bestFit'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, GalleryMWs.loadBestFitVideo, RenderingMWs.renderFile ); } - private static addGetMetaFile(app: Express) { + protected static addGetMetaFile(app: Express) { app.get(['/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.MetaFiles.join('|') + '))'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, RenderingMWs.renderFile ); } - private static addRandom(app: Express) { + protected static addRandom(app: Express) { app.get(['/api/gallery/random'], + // common part AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), VersionMWs.injectGalleryVersion, + + // specific part GalleryMWs.getRandomImage, GalleryMWs.loadFile, RenderingMWs.renderFile ); } - private static addGetPhotoThumbnail(app: Express) { + protected static addGetPhotoThumbnail(app: Express) { app.get('/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Photos.join('|') + '))/thumbnail/:size?', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Photo), RenderingMWs.renderFile ); } - private static addGetVideoThumbnail(app: Express) { + protected static addGetVideoThumbnail(app: Express) { app.get('/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Videos.join('|') + '))/thumbnail/:size?', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Video), RenderingMWs.renderFile @@ -129,33 +156,42 @@ export class GalleryRouter { } - private static addGetVideoIcon(app: Express) { + protected static addGetVideoIcon(app: Express) { app.get('/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Videos.join('|') + '))/icon', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Video), RenderingMWs.renderFile ); } - private static addGetImageIcon(app: Express) { + protected static addGetImageIcon(app: Express) { app.get('/api/gallery/content/:mediaPath(*\.(' + SupportedFormats.Photos.join('|') + '))/icon', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.normalizePathParam('mediaPath'), AuthenticationMWs.authorisePath('mediaPath', false), + + // specific part GalleryMWs.loadFile, ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Photo), RenderingMWs.renderFile ); } - private static addSearch(app: Express) { + protected static addSearch(app: Express) { app.get('/api/search/:text', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), VersionMWs.injectGalleryVersion, + + // specific part GalleryMWs.search, ThumbnailGeneratorMWs.addThumbnailInformation, GalleryMWs.cleanUpGalleryResults, @@ -163,11 +199,14 @@ export class GalleryRouter { ); } - private static addInstantSearch(app: Express) { + protected static addInstantSearch(app: Express) { app.get('/api/instant-search/:text', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), VersionMWs.injectGalleryVersion, + + // specific part GalleryMWs.instantSearch, ThumbnailGeneratorMWs.addThumbnailInformation, GalleryMWs.cleanUpGalleryResults, @@ -175,11 +214,14 @@ export class GalleryRouter { ); } - private static addAutoComplete(app: Express) { + protected static addAutoComplete(app: Express) { app.get('/api/autocomplete/:text', + // common part AuthenticationMWs.authenticate, AuthenticationMWs.authorise(UserRoles.Guest), VersionMWs.injectGalleryVersion, + + // specific part GalleryMWs.autocomplete, RenderingMWs.renderResult ); diff --git a/src/backend/routes/PersonRouter.ts b/src/backend/routes/PersonRouter.ts index ecd17070..23b1964e 100644 --- a/src/backend/routes/PersonRouter.ts +++ b/src/backend/routes/PersonRouter.ts @@ -16,7 +16,7 @@ export class PersonRouter { } - private static updatePerson(app: Express) { + protected static updatePerson(app: Express) { app.post(['/api/person/:name'], // common part AuthenticationMWs.authenticate, @@ -29,7 +29,7 @@ export class PersonRouter { ); } - private static addGetPersons(app: Express) { + protected static addGetPersons(app: Express) { app.get(['/api/person'], // common part AuthenticationMWs.authenticate, @@ -45,7 +45,7 @@ export class PersonRouter { ); } - private static getPersonThumbnail(app: Express) { + protected static getPersonThumbnail(app: Express) { app.get(['/api/person/:name/thumbnail'], // common part AuthenticationMWs.authenticate, diff --git a/src/common/Utils.ts b/src/common/Utils.ts index c77238a9..8ea7fa0d 100644 --- a/src/common/Utils.ts +++ b/src/common/Utils.ts @@ -81,6 +81,16 @@ export class Utils { return true; } + static renderDataSize(size: number) { + const postFixes = ['B', 'KB', 'MB', 'GB', 'TB']; + let index = 0; + while (size > 1000 && index < postFixes.length - 1) { + size /= 1000; + index++; + } + return size.toFixed(2) + postFixes[index]; + } + /** *