mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
task manager UI imporvement, removing depricated indexing task
This commit is contained in:
parent
a952d927b6
commit
76b439289a
@ -11,7 +11,6 @@ import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
|||||||
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
||||||
import {ProjectPath} from '../ProjectPath';
|
import {ProjectPath} from '../ProjectPath';
|
||||||
import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass';
|
import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass';
|
||||||
import {IndexingDTO} from '../../common/entities/settings/IndexingDTO';
|
|
||||||
import {ISQLGalleryManager} from '../model/sql/IGalleryManager';
|
import {ISQLGalleryManager} from '../model/sql/IGalleryManager';
|
||||||
|
|
||||||
const LOG_TAG = '[AdminMWs]';
|
const LOG_TAG = '[AdminMWs]';
|
||||||
@ -523,57 +522,4 @@ export class AdminMWs {
|
|||||||
return next(new ErrorDTO(ErrorCodes.TASK_ERROR, 'Task error: ' + JSON.stringify(err, null, ' '), err));
|
return next(new ErrorDTO(ErrorCodes.TASK_ERROR, 'Task error: ' + JSON.stringify(err, null, ' '), err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static startIndexing(req: Request, res: Response, next: NextFunction) {
|
|
||||||
try {
|
|
||||||
const createThumbnails: boolean = (<IndexingDTO>req.body).createThumbnails || false;
|
|
||||||
ObjectManagers.getInstance().IndexingTaskManager.startIndexing(createThumbnails);
|
|
||||||
req.resultPipe = 'ok';
|
|
||||||
return next();
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
|
||||||
}
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static getIndexingProgress(req: Request, res: Response, next: NextFunction) {
|
|
||||||
try {
|
|
||||||
req.resultPipe = ObjectManagers.getInstance().IndexingTaskManager.getProgress();
|
|
||||||
return next();
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
|
||||||
}
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static cancelIndexing(req: Request, res: Response, next: NextFunction) {
|
|
||||||
try {
|
|
||||||
ObjectManagers.getInstance().IndexingTaskManager.cancelIndexing();
|
|
||||||
req.resultPipe = 'ok';
|
|
||||||
return next();
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
|
||||||
}
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async resetIndexes(req: Express.Request, res: Response, next: NextFunction) {
|
|
||||||
try {
|
|
||||||
await ObjectManagers.getInstance().IndexingTaskManager.reset();
|
|
||||||
req.resultPipe = 'ok';
|
|
||||||
return next();
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
|
||||||
}
|
|
||||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import {ISearchManager} from './interfaces/ISearchManager';
|
|||||||
import {SQLConnection} from './sql/SQLConnection';
|
import {SQLConnection} from './sql/SQLConnection';
|
||||||
import {ISharingManager} from './interfaces/ISharingManager';
|
import {ISharingManager} from './interfaces/ISharingManager';
|
||||||
import {Logger} from '../Logger';
|
import {Logger} from '../Logger';
|
||||||
import {IIndexingTaskManager} from './interfaces/IIndexingTaskManager';
|
|
||||||
import {IIndexingManager} from './interfaces/IIndexingManager';
|
import {IIndexingManager} from './interfaces/IIndexingManager';
|
||||||
import {IPersonManager} from './interfaces/IPersonManager';
|
import {IPersonManager} from './interfaces/IPersonManager';
|
||||||
import {IVersionManager} from './interfaces/IVersionManager';
|
import {IVersionManager} from './interfaces/IVersionManager';
|
||||||
@ -19,7 +18,6 @@ export class ObjectManagers {
|
|||||||
private _searchManager: ISearchManager;
|
private _searchManager: ISearchManager;
|
||||||
private _sharingManager: ISharingManager;
|
private _sharingManager: ISharingManager;
|
||||||
private _indexingManager: IIndexingManager;
|
private _indexingManager: IIndexingManager;
|
||||||
private _indexingTaskManager: IIndexingTaskManager;
|
|
||||||
private _personManager: IPersonManager;
|
private _personManager: IPersonManager;
|
||||||
private _versionManager: IVersionManager;
|
private _versionManager: IVersionManager;
|
||||||
private _taskManager: ITaskManager;
|
private _taskManager: ITaskManager;
|
||||||
@ -49,13 +47,6 @@ export class ObjectManagers {
|
|||||||
this._indexingManager = value;
|
this._indexingManager = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
get IndexingTaskManager(): IIndexingTaskManager {
|
|
||||||
return this._indexingTaskManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
set IndexingTaskManager(value: IIndexingTaskManager) {
|
|
||||||
this._indexingTaskManager = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get GalleryManager(): IGalleryManager {
|
get GalleryManager(): IGalleryManager {
|
||||||
return this._galleryManager;
|
return this._galleryManager;
|
||||||
@ -124,7 +115,6 @@ export class ObjectManagers {
|
|||||||
const UserManager = require('./memory/UserManager').UserManager;
|
const UserManager = require('./memory/UserManager').UserManager;
|
||||||
const SearchManager = require('./memory/SearchManager').SearchManager;
|
const SearchManager = require('./memory/SearchManager').SearchManager;
|
||||||
const SharingManager = require('./memory/SharingManager').SharingManager;
|
const SharingManager = require('./memory/SharingManager').SharingManager;
|
||||||
const IndexingTaskManager = require('./memory/IndexingTaskManager').IndexingTaskManager;
|
|
||||||
const IndexingManager = require('./memory/IndexingManager').IndexingManager;
|
const IndexingManager = require('./memory/IndexingManager').IndexingManager;
|
||||||
const PersonManager = require('./memory/PersonManager').PersonManager;
|
const PersonManager = require('./memory/PersonManager').PersonManager;
|
||||||
const VersionManager = require('./memory/VersionManager').VersionManager;
|
const VersionManager = require('./memory/VersionManager').VersionManager;
|
||||||
@ -132,7 +122,6 @@ export class ObjectManagers {
|
|||||||
ObjectManagers.getInstance().UserManager = new UserManager();
|
ObjectManagers.getInstance().UserManager = new UserManager();
|
||||||
ObjectManagers.getInstance().SearchManager = new SearchManager();
|
ObjectManagers.getInstance().SearchManager = new SearchManager();
|
||||||
ObjectManagers.getInstance().SharingManager = new SharingManager();
|
ObjectManagers.getInstance().SharingManager = new SharingManager();
|
||||||
ObjectManagers.getInstance().IndexingTaskManager = new IndexingTaskManager();
|
|
||||||
ObjectManagers.getInstance().IndexingManager = new IndexingManager();
|
ObjectManagers.getInstance().IndexingManager = new IndexingManager();
|
||||||
ObjectManagers.getInstance().PersonManager = new PersonManager();
|
ObjectManagers.getInstance().PersonManager = new PersonManager();
|
||||||
ObjectManagers.getInstance().VersionManager = new VersionManager();
|
ObjectManagers.getInstance().VersionManager = new VersionManager();
|
||||||
@ -146,7 +135,6 @@ export class ObjectManagers {
|
|||||||
const UserManager = require('./sql/UserManager').UserManager;
|
const UserManager = require('./sql/UserManager').UserManager;
|
||||||
const SearchManager = require('./sql/SearchManager').SearchManager;
|
const SearchManager = require('./sql/SearchManager').SearchManager;
|
||||||
const SharingManager = require('./sql/SharingManager').SharingManager;
|
const SharingManager = require('./sql/SharingManager').SharingManager;
|
||||||
const IndexingTaskManager = require('./sql/IndexingTaskManager').IndexingTaskManager;
|
|
||||||
const IndexingManager = require('./sql/IndexingManager').IndexingManager;
|
const IndexingManager = require('./sql/IndexingManager').IndexingManager;
|
||||||
const PersonManager = require('./sql/PersonManager').PersonManager;
|
const PersonManager = require('./sql/PersonManager').PersonManager;
|
||||||
const VersionManager = require('./sql/VersionManager').VersionManager;
|
const VersionManager = require('./sql/VersionManager').VersionManager;
|
||||||
@ -154,7 +142,6 @@ export class ObjectManagers {
|
|||||||
ObjectManagers.getInstance().UserManager = new UserManager();
|
ObjectManagers.getInstance().UserManager = new UserManager();
|
||||||
ObjectManagers.getInstance().SearchManager = new SearchManager();
|
ObjectManagers.getInstance().SearchManager = new SearchManager();
|
||||||
ObjectManagers.getInstance().SharingManager = new SharingManager();
|
ObjectManagers.getInstance().SharingManager = new SharingManager();
|
||||||
ObjectManagers.getInstance().IndexingTaskManager = new IndexingTaskManager();
|
|
||||||
ObjectManagers.getInstance().IndexingManager = new IndexingManager();
|
ObjectManagers.getInstance().IndexingManager = new IndexingManager();
|
||||||
ObjectManagers.getInstance().PersonManager = new PersonManager();
|
ObjectManagers.getInstance().PersonManager = new PersonManager();
|
||||||
ObjectManagers.getInstance().VersionManager = new VersionManager();
|
ObjectManagers.getInstance().VersionManager = new VersionManager();
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import {TaskProgressDTO} from '../../../common/entities/settings/TaskProgressDTO';
|
|
||||||
|
|
||||||
export interface IIndexingTaskManager {
|
|
||||||
startIndexing(createThumbnails?: boolean): void;
|
|
||||||
|
|
||||||
getProgress(): TaskProgressDTO;
|
|
||||||
|
|
||||||
cancelIndexing(): void;
|
|
||||||
|
|
||||||
reset(): Promise<void>;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import {IIndexingTaskManager} from '../interfaces/IIndexingTaskManager';
|
|
||||||
import {TaskProgressDTO} from '../../../common/entities/settings/TaskProgressDTO';
|
|
||||||
|
|
||||||
export class IndexingTaskManager implements IIndexingTaskManager {
|
|
||||||
|
|
||||||
startIndexing(): void {
|
|
||||||
throw new Error('not supported by memory DB');
|
|
||||||
}
|
|
||||||
|
|
||||||
getProgress(): TaskProgressDTO {
|
|
||||||
throw new Error('not supported by memory DB');
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelIndexing(): void {
|
|
||||||
throw new Error('not supported by memory DB');
|
|
||||||
}
|
|
||||||
|
|
||||||
reset(): Promise<void> {
|
|
||||||
throw new Error('Method not implemented.');
|
|
||||||
}
|
|
||||||
}
|
|
@ -153,7 +153,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
|||||||
.createQueryBuilder('media')
|
.createQueryBuilder('media')
|
||||||
.select('SUM(media.metadata.fileSize)', 'sum')
|
.select('SUM(media.metadata.fileSize)', 'sum')
|
||||||
.getRawOne();
|
.getRawOne();
|
||||||
return sum;
|
return sum || 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async countPhotos(): Promise<number> {
|
async countPhotos(): Promise<number> {
|
||||||
|
@ -1,118 +0,0 @@
|
|||||||
import {IIndexingTaskManager} from '../interfaces/IIndexingTaskManager';
|
|
||||||
import {TaskProgressDTO} from '../../../common/entities/settings/TaskProgressDTO';
|
|
||||||
import {ObjectManagers} from '../ObjectManagers';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import {SQLConnection} from './SQLConnection';
|
|
||||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
|
||||||
import {Logger} from '../../Logger';
|
|
||||||
import {RendererInput, ThumbnailSourceType, ThumbnailWorker} from '../threading/ThumbnailWorker';
|
|
||||||
import {Config} from '../../../common/config/private/Config';
|
|
||||||
import {MediaDTO} from '../../../common/entities/MediaDTO';
|
|
||||||
import {ProjectPath} from '../../ProjectPath';
|
|
||||||
import {ThumbnailGeneratorMWs} from '../../middlewares/thumbnail/ThumbnailGeneratorMWs';
|
|
||||||
|
|
||||||
const LOG_TAG = '[IndexingTaskManager]';
|
|
||||||
|
|
||||||
export class IndexingTaskManager implements IIndexingTaskManager {
|
|
||||||
directoriesToIndex: string[] = [];
|
|
||||||
indexingProgress: TaskProgressDTO = null;
|
|
||||||
enabled = false;
|
|
||||||
private indexNewDirectory = async (createThumbnails: boolean = false) => {
|
|
||||||
if (this.directoriesToIndex.length === 0) {
|
|
||||||
this.indexingProgress = null;
|
|
||||||
if (global.gc) {
|
|
||||||
global.gc();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const directory = this.directoriesToIndex.shift();
|
|
||||||
this.indexingProgress.comment = directory;
|
|
||||||
this.indexingProgress.left = this.directoriesToIndex.length;
|
|
||||||
const scanned = await ObjectManagers.getInstance().IndexingManager.indexDirectory(directory);
|
|
||||||
if (this.enabled === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.indexingProgress.progress++;
|
|
||||||
this.indexingProgress.time.current = Date.now();
|
|
||||||
for (let i = 0; i < scanned.directories.length; i++) {
|
|
||||||
this.directoriesToIndex.push(path.join(scanned.directories[i].path, scanned.directories[i].name));
|
|
||||||
}
|
|
||||||
if (createThumbnails) {
|
|
||||||
for (let i = 0; i < scanned.media.length; i++) {
|
|
||||||
try {
|
|
||||||
const media = scanned.media[i];
|
|
||||||
const mPath = path.join(ProjectPath.ImageFolder, media.directory.path, media.directory.name, media.name);
|
|
||||||
const thPath = path.join(ProjectPath.ThumbnailFolder,
|
|
||||||
ThumbnailGeneratorMWs.generateThumbnailName(mPath, Config.Client.Thumbnail.thumbnailSizes[0]));
|
|
||||||
if (fs.existsSync(thPath)) { // skip existing thumbnails
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
await ThumbnailWorker.render(<RendererInput>{
|
|
||||||
type: MediaDTO.isVideo(media) ? ThumbnailSourceType.Video : ThumbnailSourceType.Image,
|
|
||||||
mediaPath: mPath,
|
|
||||||
size: Config.Client.Thumbnail.thumbnailSizes[0],
|
|
||||||
thPath: thPath,
|
|
||||||
makeSquare: false,
|
|
||||||
qualityPriority: Config.Server.thumbnail.qualityPriority
|
|
||||||
}, Config.Server.thumbnail.processingLibrary);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
Logger.error(LOG_TAG, 'Error during indexing job: ' + e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
process.nextTick(() => {
|
|
||||||
this.indexNewDirectory(createThumbnails).catch(console.error);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
startIndexing(createThumbnails: boolean = false): void {
|
|
||||||
if (this.directoriesToIndex.length === 0 && this.enabled === false) {
|
|
||||||
Logger.info(LOG_TAG, 'Starting indexing');
|
|
||||||
this.indexingProgress = {
|
|
||||||
progress: 0,
|
|
||||||
left: 0,
|
|
||||||
comment: '',
|
|
||||||
time: {
|
|
||||||
start: Date.now(),
|
|
||||||
current: Date.now()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.directoriesToIndex.push('/');
|
|
||||||
this.enabled = true;
|
|
||||||
this.indexNewDirectory(createThumbnails).catch(console.error);
|
|
||||||
} else {
|
|
||||||
Logger.info(LOG_TAG, 'Already indexing..');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getProgress(): TaskProgressDTO {
|
|
||||||
return this.indexingProgress;
|
|
||||||
}
|
|
||||||
|
|
||||||
cancelIndexing(): void {
|
|
||||||
Logger.info(LOG_TAG, 'Canceling indexing');
|
|
||||||
this.directoriesToIndex = [];
|
|
||||||
this.indexingProgress = null;
|
|
||||||
this.enabled = false;
|
|
||||||
if (global.gc) {
|
|
||||||
global.gc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async reset(): Promise<void> {
|
|
||||||
Logger.info(LOG_TAG, 'Resetting DB');
|
|
||||||
this.directoriesToIndex = [];
|
|
||||||
this.indexingProgress = null;
|
|
||||||
this.enabled = false;
|
|
||||||
const connection = await SQLConnection.getConnection();
|
|
||||||
return connection
|
|
||||||
.getRepository(DirectoryEntity)
|
|
||||||
.createQueryBuilder('directory')
|
|
||||||
.delete()
|
|
||||||
.execute().then(() => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,7 +7,7 @@ declare const process: any;
|
|||||||
|
|
||||||
export abstract class Task<T = void> implements ITask<T> {
|
export abstract class Task<T = void> implements ITask<T> {
|
||||||
|
|
||||||
protected progress: TaskProgressDTO;
|
protected progress: TaskProgressDTO = null;
|
||||||
protected running = false;
|
protected running = false;
|
||||||
protected config: T;
|
protected config: T;
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export abstract class Task<T = void> implements ITask<T> {
|
|||||||
|
|
||||||
public start(config: T): void {
|
public start(config: T): void {
|
||||||
if (this.running === false && this.Supported) {
|
if (this.running === false && this.Supported) {
|
||||||
Logger.info('[Task]', 'running task:' + this.Name);
|
Logger.info('[Task]', 'Running task: ' + this.Name);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.progress = {
|
this.progress = {
|
||||||
progress: 0,
|
progress: 0,
|
||||||
@ -45,15 +45,20 @@ export abstract class Task<T = void> implements ITask<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public stop(): void {
|
public stop(): void {
|
||||||
Logger.info('[Task]', 'stopping task' + this.Name);
|
Logger.info('[Task]', 'Stopping task: ' + this.Name);
|
||||||
this.progress = null;
|
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
this.onFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract async step(): Promise<TaskProgressDTO>;
|
protected abstract async step(): Promise<TaskProgressDTO>;
|
||||||
|
|
||||||
protected abstract async init(): Promise<void>;
|
protected abstract async init(): Promise<void>;
|
||||||
|
|
||||||
|
private onFinish(): void {
|
||||||
|
this.progress = null;
|
||||||
|
Logger.info('[Task]', 'Task finished: ' + this.Name);
|
||||||
|
}
|
||||||
|
|
||||||
private run() {
|
private run() {
|
||||||
process.nextTick(async () => {
|
process.nextTick(async () => {
|
||||||
try {
|
try {
|
||||||
@ -64,6 +69,7 @@ export abstract class Task<T = void> implements ITask<T> {
|
|||||||
this.progress = await this.step();
|
this.progress = await this.step();
|
||||||
if (this.progress == null) { // finished
|
if (this.progress == null) { // finished
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
this.onFinish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run();
|
this.run();
|
||||||
|
@ -18,7 +18,9 @@ export class TaskManager implements ITaskManager {
|
|||||||
|
|
||||||
getProgresses(): { [id: string]: TaskProgressDTO } {
|
getProgresses(): { [id: string]: TaskProgressDTO } {
|
||||||
const m: { [id: string]: TaskProgressDTO } = {};
|
const m: { [id: string]: TaskProgressDTO } = {};
|
||||||
TaskRepository.Instance.getAvailableTasks().forEach(t => m[t.Name] = t.Progress);
|
TaskRepository.Instance.getAvailableTasks()
|
||||||
|
.filter(t => t.Progress)
|
||||||
|
.forEach(t => m[t.Name] = t.Progress);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +37,9 @@ export class TaskManager implements ITaskManager {
|
|||||||
const t = this.findTask(taskName);
|
const t = this.findTask(taskName);
|
||||||
if (t) {
|
if (t) {
|
||||||
t.stop();
|
t.stop();
|
||||||
|
if (global.gc) {
|
||||||
|
global.gc();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logger.warn(LOG_TAG, 'cannot find task to stop:' + taskName);
|
Logger.warn(LOG_TAG, 'cannot find task to stop:' + taskName);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ export class AdminRouter {
|
|||||||
this.addGetStatistic(app);
|
this.addGetStatistic(app);
|
||||||
this.addGetDuplicates(app);
|
this.addGetDuplicates(app);
|
||||||
this.addTasks(app);
|
this.addTasks(app);
|
||||||
this.addIndexGallery(app);
|
|
||||||
this.addSettings(app);
|
this.addSettings(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,33 +31,6 @@ export class AdminRouter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static addIndexGallery(app: Express) {
|
|
||||||
app.get('/api/admin/indexes/job/progress',
|
|
||||||
AuthenticationMWs.authenticate,
|
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
|
||||||
AdminMWs.getIndexingProgress,
|
|
||||||
RenderingMWs.renderResult
|
|
||||||
);
|
|
||||||
app.post('/api/admin/indexes/job',
|
|
||||||
AuthenticationMWs.authenticate,
|
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
|
||||||
AdminMWs.startIndexing,
|
|
||||||
RenderingMWs.renderResult
|
|
||||||
);
|
|
||||||
app.delete('/api/admin/indexes/job',
|
|
||||||
AuthenticationMWs.authenticate,
|
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
|
||||||
AdminMWs.cancelIndexing,
|
|
||||||
RenderingMWs.renderResult
|
|
||||||
);
|
|
||||||
app.delete('/api/admin/indexes',
|
|
||||||
AuthenticationMWs.authenticate,
|
|
||||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
|
||||||
AdminMWs.resetIndexes,
|
|
||||||
RenderingMWs.renderResult
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static addTasks(app: Express) {
|
private static addTasks(app: Express) {
|
||||||
app.get('/api/admin/tasks/available',
|
app.get('/api/admin/tasks/available',
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
@ -2,7 +2,7 @@ export type fieldType = 'string' | 'number' | 'boolean';
|
|||||||
|
|
||||||
|
|
||||||
export enum DefaultsTasks {
|
export enum DefaultsTasks {
|
||||||
Indexing, 'Database Reset', Dummy
|
Indexing = 1, 'Database Reset' = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigTemplateEntry {
|
export interface ConfigTemplateEntry {
|
||||||
@ -12,11 +12,6 @@ export interface ConfigTemplateEntry {
|
|||||||
defaultValue: any;
|
defaultValue: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
export interface NestedFieldType {
|
|
||||||
[key: string]: fieldType | NestedFieldType;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
export interface TaskDTO {
|
export interface TaskDTO {
|
||||||
Name: string;
|
Name: string;
|
||||||
ConfigTemplate: ConfigTemplateEntry[];
|
ConfigTemplate: ConfigTemplateEntry[];
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-md-2 control-label" for="excludeFolderList" i18n>Exclude Folder List</label>
|
<label class="col-md-2 control-label" for="excludeFolderList" i18n>Exclude Folder List</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="text" class="form-control" placeholder=""
|
<input type="text" class="form-control" placeholder="/media/images/family/private;private;family/private"
|
||||||
id="excludeFolderList"
|
id="excludeFolderList"
|
||||||
[(ngModel)]="excludeFolderList"
|
[(ngModel)]="excludeFolderList"
|
||||||
name="excludeFolderList" required>
|
name="excludeFolderList" required>
|
||||||
@ -67,7 +67,7 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-md-2 control-label" for="excludeFileList" i18n>Exclude File List</label>
|
<label class="col-md-2 control-label" for="excludeFileList" i18n>Exclude File List</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="text" class="form-control" placeholder=".ignore; .pg2ignore"
|
<input type="text" class="form-control" placeholder=".ignore;.pg2ignore"
|
||||||
id="excludeFileList"
|
id="excludeFileList"
|
||||||
[(ngModel)]="excludeFileList"
|
[(ngModel)]="excludeFileList"
|
||||||
name="excludeFileList" required>
|
name="excludeFileList" required>
|
||||||
@ -150,20 +150,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 col-6">
|
<div class="col-md-2 col-6">
|
||||||
<span class="oi oi-folder" title="Folders" i18n-title aria-hidden="true"> </span>
|
<span class="oi oi-folder" title="Folders" i18n-title aria-hidden="true"> </span>
|
||||||
{{statistic ? statistic.directories : '...'}}
|
{{_settingsService.statistic.value ? _settingsService.statistic.value.directories : '...'}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 col-6">
|
<div class="col-md-2 col-6">
|
||||||
<span class="oi oi-camera-slr" title="Photos" i18n-title aria-hidden="true"> </span>
|
<span class="oi oi-camera-slr" title="Photos" i18n-title aria-hidden="true"> </span>
|
||||||
{{statistic ? statistic.photos : '...'}}
|
{{_settingsService.statistic.value ? _settingsService.statistic.value.photos : '...'}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 col-6">
|
<div class="col-md-2 col-6">
|
||||||
<span class="oi oi-video" title="Videos" i18n-title aria-hidden="true"> </span>
|
<span class="oi oi-video" title="Videos" i18n-title aria-hidden="true"> </span>
|
||||||
{{statistic ? statistic.videos : '...'}}
|
{{_settingsService.statistic.value ? _settingsService.statistic.value.videos : '...'}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 col-6">
|
<div class="col-md-2 col-6">
|
||||||
<span class="oi oi-pie-chart" title="Size" i18n-title aria-hidden="true"> </span>
|
<span class="oi oi-pie-chart" title="Size" i18n-title aria-hidden="true"> </span>
|
||||||
{{statistic ? (statistic.diskUsage | fileSize) : '...'}}
|
{{_settingsService.statistic.value ? (_settingsService.statistic.value.diskUsage | fileSize) : '...'}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,6 @@ import {IndexingConfig, ReIndexingSensitivity} from '../../../../../common/confi
|
|||||||
import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
import {SettingsComponent} from '../_abstract/abstract.settings.component';
|
||||||
import {Utils} from '../../../../../common/Utils';
|
import {Utils} from '../../../../../common/Utils';
|
||||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||||
import {StatisticDTO} from '../../../../../common/entities/settings/StatisticDTO';
|
|
||||||
import {ScheduledTasksService} from '../scheduled-tasks.service';
|
import {ScheduledTasksService} from '../scheduled-tasks.service';
|
||||||
import {DefaultsTasks} from '../../../../../common/entities/task/TaskDTO';
|
import {DefaultsTasks} from '../../../../../common/entities/task/TaskDTO';
|
||||||
|
|
||||||
@ -24,7 +23,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
|
|
||||||
|
|
||||||
types: { key: number; value: string }[] = [];
|
types: { key: number; value: string }[] = [];
|
||||||
statistic: StatisticDTO;
|
|
||||||
|
|
||||||
constructor(_authService: AuthenticationService,
|
constructor(_authService: AuthenticationService,
|
||||||
_navigation: NavigationService,
|
_navigation: NavigationService,
|
||||||
@ -59,11 +57,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
super.ngOnDestroy();
|
|
||||||
this.tasksService.unsubscribeFromProgress();
|
|
||||||
}
|
|
||||||
|
|
||||||
get excludeFolderList(): string {
|
get excludeFolderList(): string {
|
||||||
return this.settings.excludeFolderList.join(';');
|
return this.settings.excludeFolderList.join(';');
|
||||||
}
|
}
|
||||||
@ -80,6 +73,11 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
this.settings.excludeFileList = value.split(';');
|
this.settings.excludeFileList = value.split(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
super.ngOnDestroy();
|
||||||
|
this.tasksService.unsubscribeFromProgress();
|
||||||
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.tasksService.subscribeToProgress();
|
this.tasksService.subscribeToProgress();
|
||||||
@ -98,9 +96,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (this._settingsService.isSupported()) {
|
|
||||||
this.statistic = await this._settingsService.getStatistic();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,7 +104,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
this.error = '';
|
this.error = '';
|
||||||
try {
|
try {
|
||||||
await this.tasksService.start(DefaultsTasks[DefaultsTasks.Indexing], {createThumbnails: !!createThumbnails});
|
await this.tasksService.start(DefaultsTasks[DefaultsTasks.Indexing], {createThumbnails: !!createThumbnails});
|
||||||
await this.tasksService.forceUpdate();
|
|
||||||
this.notification.info(this.i18n('Folder indexing started'));
|
this.notification.info(this.i18n('Folder indexing started'));
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
return true;
|
return true;
|
||||||
@ -129,7 +123,6 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
this.error = '';
|
this.error = '';
|
||||||
try {
|
try {
|
||||||
await this.tasksService.stop(DefaultsTasks[DefaultsTasks.Indexing]);
|
await this.tasksService.stop(DefaultsTasks[DefaultsTasks.Indexing]);
|
||||||
await this.tasksService.forceUpdate();
|
|
||||||
this.notification.info(this.i18n('Folder indexing interrupted'));
|
this.notification.info(this.i18n('Folder indexing interrupted'));
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
return true;
|
return true;
|
||||||
@ -149,8 +142,7 @@ export class IndexingSettingsComponent extends SettingsComponent<IndexingConfig,
|
|||||||
this.error = '';
|
this.error = '';
|
||||||
try {
|
try {
|
||||||
await this.tasksService.start(DefaultsTasks[DefaultsTasks['Database Reset']]);
|
await this.tasksService.start(DefaultsTasks[DefaultsTasks['Database Reset']]);
|
||||||
await this.tasksService.forceUpdate();
|
this.notification.info(this.i18n('Resetting database'));
|
||||||
this.notification.success(this.i18n('Database reset'), this.i18n('Success'));
|
|
||||||
this.inProgress = false;
|
this.inProgress = false;
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -3,19 +3,36 @@ import {NetworkService} from '../../../model/network/network.service';
|
|||||||
import {SettingsService} from '../settings.service';
|
import {SettingsService} from '../settings.service';
|
||||||
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
import {AbstractSettingsService} from '../_abstract/abstract.settings.service';
|
||||||
import {DatabaseType, IndexingConfig} from '../../../../../common/config/private/IPrivateConfig';
|
import {DatabaseType, IndexingConfig} from '../../../../../common/config/private/IPrivateConfig';
|
||||||
import {TaskProgressDTO} from '../../../../../common/entities/settings/TaskProgressDTO';
|
|
||||||
import {BehaviorSubject} from 'rxjs';
|
import {BehaviorSubject} from 'rxjs';
|
||||||
import {IndexingDTO} from '../../../../../common/entities/settings/IndexingDTO';
|
|
||||||
import {StatisticDTO} from '../../../../../common/entities/settings/StatisticDTO';
|
import {StatisticDTO} from '../../../../../common/entities/settings/StatisticDTO';
|
||||||
|
import {ScheduledTasksService} from '../scheduled-tasks.service';
|
||||||
|
import {DefaultsTasks} from '../../../../../common/entities/task/TaskDTO';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class IndexingSettingsService extends AbstractSettingsService<IndexingConfig> {
|
export class IndexingSettingsService extends AbstractSettingsService<IndexingConfig> {
|
||||||
|
|
||||||
|
|
||||||
|
public statistic: BehaviorSubject<StatisticDTO>;
|
||||||
|
|
||||||
constructor(private _networkService: NetworkService,
|
constructor(private _networkService: NetworkService,
|
||||||
|
private _tasksService: ScheduledTasksService,
|
||||||
_settingsService: SettingsService) {
|
_settingsService: SettingsService) {
|
||||||
super(_settingsService);
|
super(_settingsService);
|
||||||
|
this.statistic = new BehaviorSubject(null);
|
||||||
|
const sub = _settingsService.settings.subscribe(() => {
|
||||||
|
if (this.isSupported()) {
|
||||||
|
this.loadStatistic();
|
||||||
|
sub.unsubscribe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._tasksService.onTaskFinish.subscribe((taskName: string) => {
|
||||||
|
if (taskName === DefaultsTasks[DefaultsTasks.Indexing] ||
|
||||||
|
taskName === DefaultsTasks[DefaultsTasks['Database Reset']]) {
|
||||||
|
if (this.isSupported()) {
|
||||||
|
this.loadStatistic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateSettings(settings: IndexingConfig): Promise<void> {
|
public updateSettings(settings: IndexingConfig): Promise<void> {
|
||||||
@ -28,7 +45,7 @@ export class IndexingSettingsService extends AbstractSettingsService<IndexingCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getStatistic() {
|
async loadStatistic() {
|
||||||
return this._networkService.getJson<StatisticDTO>('/admin/statistic');
|
this.statistic.next(await this._networkService.getJson<StatisticDTO>('/admin/statistic'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Injectable} from '@angular/core';
|
import {EventEmitter, Injectable} from '@angular/core';
|
||||||
import {BehaviorSubject} from 'rxjs';
|
import {BehaviorSubject} from 'rxjs';
|
||||||
import {TaskProgressDTO} from '../../../../common/entities/settings/TaskProgressDTO';
|
import {TaskProgressDTO} from '../../../../common/entities/settings/TaskProgressDTO';
|
||||||
import {NetworkService} from '../../model/network/network.service';
|
import {NetworkService} from '../../model/network/network.service';
|
||||||
@ -8,6 +8,7 @@ export class ScheduledTasksService {
|
|||||||
|
|
||||||
|
|
||||||
public progress: BehaviorSubject<{ [key: string]: TaskProgressDTO }>;
|
public progress: BehaviorSubject<{ [key: string]: TaskProgressDTO }>;
|
||||||
|
public onTaskFinish: EventEmitter<string> = new EventEmitter<string>();
|
||||||
timer: number = null;
|
timer: number = null;
|
||||||
private subscribers = 0;
|
private subscribers = 0;
|
||||||
|
|
||||||
@ -28,16 +29,24 @@ export class ScheduledTasksService {
|
|||||||
return this.getProgress();
|
return this.getProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async start(id: string, config?: any) {
|
public async start(id: string, config?: any): Promise<void> {
|
||||||
return await this._networkService.postJson('/admin/tasks/scheduled/' + id + '/start', {config: config});
|
await this._networkService.postJson('/admin/tasks/scheduled/' + id + '/start', {config: config});
|
||||||
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async stop(id: string) {
|
public async stop(id: string): Promise<void> {
|
||||||
return await this._networkService.postJson('/admin/tasks/scheduled/' + id + '/stop');
|
await this._networkService.postJson('/admin/tasks/scheduled/' + id + '/stop');
|
||||||
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getProgress() {
|
protected async getProgress() {
|
||||||
return this.progress.next(await this._networkService.getJson<{ [key: string]: TaskProgressDTO }>('/admin/tasks/scheduled/progress'));
|
const prevPrg = this.progress.value;
|
||||||
|
this.progress.next(await this._networkService.getJson<{ [key: string]: TaskProgressDTO }>('/admin/tasks/scheduled/progress'));
|
||||||
|
for (const prg in prevPrg) {
|
||||||
|
if (!this.progress.value.hasOwnProperty(prg)) {
|
||||||
|
this.onTaskFinish.emit(prg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getProgressPeriodically() {
|
protected getProgressPeriodically() {
|
||||||
|
@ -111,7 +111,6 @@ export class TasksSettingsComponent extends SettingsComponent<TaskConfig, TasksS
|
|||||||
try {
|
try {
|
||||||
this.disableButtons = true;
|
this.disableButtons = true;
|
||||||
await this.tasksService.start(schedule.taskName, schedule.config);
|
await this.tasksService.start(schedule.taskName, schedule.config);
|
||||||
await this.tasksService.forceUpdate();
|
|
||||||
this.notification.info(this.i18n('Task') + ' ' + schedule.taskName + ' ' + this.i18n('started'));
|
this.notification.info(this.i18n('Task') + ' ' + schedule.taskName + ' ' + this.i18n('started'));
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -131,7 +130,6 @@ export class TasksSettingsComponent extends SettingsComponent<TaskConfig, TasksS
|
|||||||
try {
|
try {
|
||||||
this.disableButtons = true;
|
this.disableButtons = true;
|
||||||
await this.tasksService.stop(schedule.taskName);
|
await this.tasksService.stop(schedule.taskName);
|
||||||
await this.tasksService.forceUpdate();
|
|
||||||
this.notification.info(this.i18n('Task') + ' ' + schedule.taskName + ' ' + this.i18n('stopped'));
|
this.notification.info(this.i18n('Task') + ' ' + schedule.taskName + ' ' + this.i18n('stopped'));
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user