Skip to content

Commit

Permalink
implementing indexed statistic
Browse files Browse the repository at this point in the history
  • Loading branch information
bpatrik committed Dec 9, 2018
1 parent 14ef03f commit c98429a
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 47 deletions.
26 changes: 25 additions & 1 deletion backend/middlewares/AdminMWs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
import {Logger} from '../Logger';
import {SQLConnection} from '../model/sql/SQLConnection';
import {DataBaseConfig, DatabaseType, IndexingConfig, IPrivateConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
import {DataBaseConfig, DatabaseType, IndexingConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
import {Config} from '../../common/config/private/Config';
import {ConfigDiagnostics} from '../model/diagnostics/ConfigDiagnostics';
import {ClientConfig} from '../../common/config/public/ConfigClass';
Expand All @@ -12,12 +12,36 @@ import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
import {ProjectPath} from '../ProjectPath';
import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass';
import {IndexingDTO} from '../../common/entities/settings/IndexingDTO';
import {ISQLGalleryManager} from '../model/sql/IGalleryManager';

const LOG_TAG = '[AdminMWs]';

export class AdminMWs {


public static async loadStatistic(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 = <ISQLGalleryManager>ObjectManagerRepository.getInstance().GalleryManager;
try {
req.resultPipe = {
directories: await galleryManager.countDirectories(),
photos: await galleryManager.countPhotos(),
videos: await galleryManager.countVideos(),
diskUsage: await galleryManager.countMediaSize(),
};
return next();
} catch (err) {
if (err instanceof Error) {
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error while getting statistic: ' + err.toString(), err));
}
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error while getting statistic', err));
}
}

public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction) {

if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
Expand Down
31 changes: 31 additions & 0 deletions backend/model/sql/GalleryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,4 +365,35 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
return list;
}

async countDirectories(): Promise<number> {
const connection = await SQLConnection.getConnection();
return await connection.getRepository(DirectoryEntity)
.createQueryBuilder('directory')
.getCount();
}

async countMediaSize(): Promise<number> {
const connection = await SQLConnection.getConnection();
let {sum} = await connection.getRepository(MediaEntity)
.createQueryBuilder('media')
.select('SUM(media.metadata.fileSize)', 'sum')
.getRawOne();
return sum;
}

async countPhotos(): Promise<number> {
const connection = await SQLConnection.getConnection();
return await connection.getRepository(PhotoEntity)
.createQueryBuilder('directory')
.getCount();
}

async countVideos(): Promise<number> {
const connection = await SQLConnection.getConnection();
return await connection.getRepository(VideoEntity)
.createQueryBuilder('directory')
.getCount();
}


}
7 changes: 7 additions & 0 deletions backend/model/sql/IGalleryManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@ export interface ISQLGalleryManager extends IGalleryManager {

indexDirectory(relativeDirectoryName: string): Promise<DirectoryDTO>;

countDirectories(): Promise<number>;

countPhotos(): Promise<number>;

countVideos(): Promise<number>;

countMediaSize(): Promise<number>;
}
9 changes: 9 additions & 0 deletions backend/routes/AdminRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,19 @@ import {Express} from 'express';
export class AdminRouter {
public static route(app: Express) {

this.addGetStatistic(app);
this.addIndexGallery(app);
this.addSettings(app);
}

private static addGetStatistic(app: Express) {
app.get('/api/admin/statistic',
AuthenticationMWs.authenticate,
AuthenticationMWs.authorise(UserRoles.Admin),
AdminMWs.loadStatistic,
RenderingMWs.renderResult
);
}

private static addIndexGallery(app: Express) {
app.get('/api/admin/indexes/job/progress',
Expand Down
6 changes: 6 additions & 0 deletions common/entities/settings/StatisticDTO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface StatisticDTO {
directories: number;
photos: number;
videos: number;
diskUsage: number;
}
5 changes: 3 additions & 2 deletions frontend/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ import {FixOrientationPipe} from './gallery/FixOrientationPipe';
import {VideoSettingsComponent} from './settings/video/video.settings.component';
import {DurationPipe} from './pipes/DurationPipe';
import {MapService} from './gallery/map/map.service';
import {Icon} from 'leaflet';
import {MetaFileSettingsComponent} from './settings/metafiles/metafile.settings.component';
import {ThumbnailLoaderService} from './gallery/thumbnailLoader.service';
import {FileSizePipe} from './pipes/FileSizePipe';


@Injectable()
Expand Down Expand Up @@ -166,7 +166,8 @@ export function translationsFactory(locale: string) {
IconizeSortingMethod,
StringifySortingMethod,
FixOrientationPipe,
DurationPipe
DurationPipe,
FileSizePipe
],
providers: [
{provide: UrlSerializer, useClass: CustomUrlSerializer},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ <h2 class="modal-title" i18n>Info</h2>
<div class="details-sub row">
<div class="col-4">{{media.metadata.size.width}} x {{media.metadata.size.height}}</div>
<div class="col-4" *ngIf="isPhoto()">{{calcMpx()}}MP</div>
<div class="col-4" *ngIf="media.metadata.fileSize">{{calcSize(media.metadata.fileSize)}}</div>
<div class="col-4" *ngIf="media.metadata.fileSize">{{media.metadata.fileSize | fileSize}}</div>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,7 @@ export class InfoPanelLightboxComponent {
}


calcSize(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];
}


isThisYear() {
return (new Date()).getFullYear() ===
Expand Down
19 changes: 19 additions & 0 deletions frontend/app/pipes/FileSizePipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {Pipe, PipeTransform} from '@angular/core';
import {I18n} from '@ngx-translate/i18n-polyfill';


@Pipe({name: 'fileSize'})
export class FileSizePipe implements PipeTransform {


transform(size: number): string {
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];
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.buttons-row {
margin-top: 10px;
margin-bottom: 20px;
}

.statics span.oi {
margin-right: 3px;
}
40 changes: 34 additions & 6 deletions frontend/app/settings/indexing/indexing.settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,31 +79,59 @@ <h5 class="card-header" i18n>
aria-valuemax="100"
style="min-width: 2em;"
[style.width.%]="(_settingsService.progress.value.indexed/(_settingsService.progress.value.left+_settingsService.progress.value.indexed))*100">
{{_settingsService.progress.value.indexed}}/{{_settingsService.progress.value.indexed+_settingsService.progress.value.left}}
{{_settingsService.progress.value.indexed}}
/{{_settingsService.progress.value.indexed + _settingsService.progress.value.left}}
</div>
</div>
</div>

<div class="row justify-content-center">
<div class="row justify-content-center buttons-row">
<button class="btn btn-success"
*ngIf="_settingsService.progress.value == null"
[disabled]="inProgress"
title="Indexes the folders"
i18n-title
(click)="index(false)" i18n>Index</button>
(click)="index(false)" i18n>Index
</button>
<button class="btn btn-primary"
title="Indexes the folders and also creates the thumbnails"
i18n-title
*ngIf="_settingsService.progress.value == null"
[disabled]="inProgress"
(click)="index(true)" i18n>Index with Thumbnails</button>
(click)="index(true)" i18n>Index with Thumbnails
</button>
<button class="btn btn-default"
*ngIf="_settingsService.progress.value != null"
[disabled]="inProgress"
(click)="cancelIndexing()" i18n>Cancel</button>
(click)="cancelIndexing()" i18n>Cancel
</button>
<button class="btn btn-danger"
[disabled]="inProgress"
(click)="resetDatabase()" i18n>Reset Indexes</button>
(click)="resetDatabase()" i18n>Reset Indexes
</button>
</div>
<hr/>
<div class="row statics">
<div class="col-md-4 col-12" i18n>
Statistic:
</div>
<div class="col-md-2 col-6">
<span class="oi oi-folder" title="Folders" i18n-title aria-hidden="true"> </span>
{{statistic ? statistic.directories : '...'}}
</div>
<div class="col-md-2 col-6">
<span class="oi oi-camera-slr" title="Photos" i18n-title aria-hidden="true"> </span>
{{statistic ? statistic.photos : '...'}}
</div>
<div class="col-md-2 col-6">
<span class="oi oi-video" title="Videos" i18n-title aria-hidden="true"> </span>
{{statistic ? statistic.videos : '...'}}

</div>
<div class="col-md-2 col-6">
<span class="oi oi-pie-chart" title="Size" i18n-title aria-hidden="true"> </span>
{{statistic ? (statistic.diskUsage | fileSize) : '...'}}
</div>
</div>
</div>
</div>
Expand Down
3 changes: 3 additions & 0 deletions frontend/app/settings/indexing/indexing.settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {IndexingConfig, ReIndexingSensitivity} from '../../../../common/config/p
import {SettingsComponent} from '../_abstract/abstract.settings.component';
import {Utils} from '../../../../common/Utils';
import {I18n} from '@ngx-translate/i18n-polyfill';
import {StatisticDTO} from '../../../../common/entities/settings/StatisticDTO';

@Component({
selector: 'app-settings-indexing',
Expand All @@ -26,6 +27,7 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
timer: null,
settings: null
};
statistic: StatisticDTO;
private $counter: Observable<number> = null;
updateProgress = async () => {
try {
Expand Down Expand Up @@ -82,6 +84,7 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
}
});
this.updateProgress();
this.statistic = await this._settingsService.getStatistic();
}

ngOnDestroy() {
Expand Down
4 changes: 4 additions & 0 deletions frontend/app/settings/indexing/indexing.settings.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {DatabaseType, IndexingConfig} from '../../../../common/config/private/IP
import {IndexingProgressDTO} from '../../../../common/entities/settings/IndexingProgressDTO';
import {BehaviorSubject} from 'rxjs';
import {IndexingDTO} from '../../../../common/entities/settings/IndexingDTO';
import {StatisticDTO} from '../../../../common/entities/settings/StatisticDTO';

@Injectable()
export class IndexingSettingsService extends AbstractSettingsService<IndexingConfig> {
Expand Down Expand Up @@ -45,4 +46,7 @@ export class IndexingSettingsService extends AbstractSettingsService<IndexingCon
}


getStatistic() {
return this._networkService.getJson<StatisticDTO>('/admin/statistic');
}
}
Loading

0 comments on commit c98429a

Please sign in to comment.