mirror of
https://github.com/xuthus83/pigallery2.git
synced 2024-11-03 21:04:03 +08:00
parent
4bd89f474f
commit
ca0579cefd
@ -7,6 +7,7 @@ import { ThumbnailGenerationJob } from './jobs/ThumbnailGenerationJob';
|
||||
import { TempFolderCleaningJob } from './jobs/TempFolderCleaningJob';
|
||||
import { PreviewFillingJob } from './jobs/PreviewFillingJob';
|
||||
import { PreviewRestJob } from './jobs/PreviewResetJob';
|
||||
import {GPXCompressionJob} from './jobs/GPXCompressionJob';
|
||||
|
||||
export class JobRepository {
|
||||
private static instance: JobRepository = null;
|
||||
@ -38,4 +39,5 @@ JobRepository.Instance.register(new PreviewRestJob());
|
||||
JobRepository.Instance.register(new VideoConvertingJob());
|
||||
JobRepository.Instance.register(new PhotoConvertingJob());
|
||||
JobRepository.Instance.register(new ThumbnailGenerationJob());
|
||||
JobRepository.Instance.register(new GPXCompressionJob());
|
||||
JobRepository.Instance.register(new TempFolderCleaningJob());
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { ConfigTemplateEntry } from '../../../../common/entities/job/JobDTO';
|
||||
import { Job } from './Job';
|
||||
import {ConfigTemplateEntry} from '../../../../common/entities/job/JobDTO';
|
||||
import {Job} from './Job';
|
||||
import * as path from 'path';
|
||||
import { DiskManager } from '../../DiskManger';
|
||||
import { DirectoryScanSettings } from '../../threading/DiskMangerWorker';
|
||||
import { Logger } from '../../../Logger';
|
||||
import { Config } from '../../../../common/config/private/Config';
|
||||
import { FileDTO } from '../../../../common/entities/FileDTO';
|
||||
import { SQLConnection } from '../../database/sql/SQLConnection';
|
||||
import { MediaEntity } from '../../database/sql/enitites/MediaEntity';
|
||||
import { PhotoEntity } from '../../database/sql/enitites/PhotoEntity';
|
||||
import { VideoEntity } from '../../database/sql/enitites/VideoEntity';
|
||||
import { backendTexts } from '../../../../common/BackendTexts';
|
||||
import { ProjectPath } from '../../../ProjectPath';
|
||||
import { DatabaseType } from '../../../../common/config/private/PrivateConfig';
|
||||
import {DiskManager} from '../../DiskManger';
|
||||
import {DirectoryScanSettings} from '../../threading/DiskMangerWorker';
|
||||
import {Logger} from '../../../Logger';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
import {SQLConnection} from '../../database/sql/SQLConnection';
|
||||
import {MediaEntity} from '../../database/sql/enitites/MediaEntity';
|
||||
import {PhotoEntity} from '../../database/sql/enitites/PhotoEntity';
|
||||
import {VideoEntity} from '../../database/sql/enitites/VideoEntity';
|
||||
import {backendTexts} from '../../../../common/BackendTexts';
|
||||
import {ProjectPath} from '../../../ProjectPath';
|
||||
import {DatabaseType} from '../../../../common/config/private/PrivateConfig';
|
||||
import {FileEntity} from '../../database/sql/enitites/FileEntity';
|
||||
import {global} from '../../../../../node_modules/@angular/compiler/src/util';
|
||||
import {DirectoryBaseDTO, DirectoryDTOUtils} from '../../../../common/entities/DirectoryDTO';
|
||||
|
||||
const LOG_TAG = '[FileJob]';
|
||||
|
||||
/**
|
||||
* Abstract class for thumbnail creation, file deleting etc.
|
||||
*/
|
||||
export abstract class FileJob<
|
||||
S extends { indexedOnly: boolean } = { indexedOnly: boolean }
|
||||
> extends Job<S> {
|
||||
export abstract class FileJob<S extends { indexedOnly: boolean } = { indexedOnly: boolean }> extends Job<S> {
|
||||
public readonly ConfigTemplate: ConfigTemplateEntry[] = [];
|
||||
directoryQueue: string[] = [];
|
||||
fileQueue: string[] = [];
|
||||
@ -109,6 +110,7 @@ export abstract class FileJob<
|
||||
for (const item of scanned.directories) {
|
||||
this.directoryQueue.push(path.join(item.path, item.name));
|
||||
}
|
||||
DirectoryDTOUtils.addReferences(scanned as DirectoryBaseDTO);
|
||||
if (this.scanFilter.noPhoto !== true || this.scanFilter.noVideo !== true) {
|
||||
const scannedAndFiltered = await this.filterMediaFiles(scanned.media);
|
||||
for (const item of scannedAndFiltered) {
|
||||
@ -138,38 +140,67 @@ export abstract class FileJob<
|
||||
}
|
||||
|
||||
private async loadAllMediaFilesFromDB(): Promise<void> {
|
||||
if (this.scanFilter.noVideo === true && this.scanFilter.noPhoto === true) {
|
||||
if (this.scanFilter.noVideo === true &&
|
||||
this.scanFilter.noPhoto === true &&
|
||||
this.scanFilter.noMetaFile === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.Progress.log('Loading files from db');
|
||||
Logger.silly(LOG_TAG, 'Loading files from db');
|
||||
|
||||
const connection = await SQLConnection.getConnection();
|
||||
if (this.scanFilter.noVideo === false ||
|
||||
this.scanFilter.noPhoto === false) {
|
||||
|
||||
let usedEntity = MediaEntity;
|
||||
let usedEntity = MediaEntity;
|
||||
|
||||
if (this.scanFilter.noVideo === true) {
|
||||
usedEntity = PhotoEntity;
|
||||
} else if (this.scanFilter.noPhoto === true) {
|
||||
usedEntity = VideoEntity;
|
||||
if (this.scanFilter.noVideo === true) {
|
||||
usedEntity = PhotoEntity;
|
||||
} else if (this.scanFilter.noPhoto === true) {
|
||||
usedEntity = VideoEntity;
|
||||
}
|
||||
|
||||
const result = await connection
|
||||
.getRepository(usedEntity)
|
||||
.createQueryBuilder('media')
|
||||
.select(['media.name', 'directory.name', 'directory.path'])
|
||||
.leftJoin('media.directory', 'directory')
|
||||
.getMany();
|
||||
|
||||
const scannedAndFiltered = await this.filterMediaFiles(result);
|
||||
for (const item of scannedAndFiltered) {
|
||||
this.fileQueue.push(
|
||||
path.join(
|
||||
ProjectPath.ImageFolder,
|
||||
item.directory.path,
|
||||
item.directory.name,
|
||||
item.name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.scanFilter.noMetaFile === false) {
|
||||
|
||||
const result = await connection
|
||||
.getRepository(usedEntity)
|
||||
.createQueryBuilder('media')
|
||||
.select(['media.name', 'media.id'])
|
||||
.leftJoinAndSelect('media.directory', 'directory')
|
||||
.getMany();
|
||||
const result = await connection
|
||||
.getRepository(FileEntity)
|
||||
.createQueryBuilder('file')
|
||||
.select(['file.name', 'directory.name', 'directory.path'])
|
||||
.leftJoin('file.directory', 'directory')
|
||||
.getMany();
|
||||
|
||||
for (const item of result) {
|
||||
this.fileQueue.push(
|
||||
path.join(
|
||||
ProjectPath.ImageFolder,
|
||||
item.directory.path,
|
||||
item.directory.name,
|
||||
item.name
|
||||
)
|
||||
);
|
||||
|
||||
const scannedAndFiltered = await this.filterMetaFiles(result);
|
||||
for (const item of scannedAndFiltered) {
|
||||
this.fileQueue.push(
|
||||
path.join(
|
||||
ProjectPath.ImageFolder,
|
||||
item.directory.path,
|
||||
item.directory.name,
|
||||
item.name
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
37
src/backend/model/jobs/jobs/GPXCompressionJob.ts
Normal file
37
src/backend/model/jobs/jobs/GPXCompressionJob.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {DefaultsJobs} from '../../../../common/entities/job/JobDTO';
|
||||
import {FileJob} from './FileJob';
|
||||
import {PhotoProcessing} from '../../fileprocessing/PhotoProcessing';
|
||||
import {GPXProcessing} from '../../GPXProcessing';
|
||||
import {FileDTO} from '../../../../common/entities/FileDTO';
|
||||
import {Logger} from '../../../Logger';
|
||||
|
||||
export class GPXCompressionJob extends FileJob {
|
||||
public readonly Name = DefaultsJobs[DefaultsJobs['GPX Compression']];
|
||||
|
||||
constructor() {
|
||||
super({noVideo: true, noPhoto: true, noMetaFile: false});
|
||||
}
|
||||
|
||||
protected async filterMetaFiles(files: FileDTO[]): Promise<FileDTO[]> {
|
||||
return files.filter(file => file.name.toLowerCase().endsWith('.gpx'));
|
||||
}
|
||||
|
||||
public get Supported(): boolean {
|
||||
return Config.Client.MetaFile.GPXCompressing.enabled === true;
|
||||
}
|
||||
|
||||
protected async shouldProcess(fPath: string): Promise<boolean> {
|
||||
return !(await GPXProcessing.compressedGPXExist(
|
||||
fPath
|
||||
));
|
||||
}
|
||||
|
||||
protected async processFile(fPath: string): Promise<void> {
|
||||
try {
|
||||
await GPXProcessing.compressGPX(fPath);
|
||||
} catch (e) {
|
||||
Logger.warn('GPXCompressionJob', ' Could not compress gpx at: ' + fPath);
|
||||
}
|
||||
}
|
||||
}
|
@ -133,7 +133,7 @@ export class DiskMangerWorker {
|
||||
// nothing to scan, we are here for the empty dir
|
||||
if (
|
||||
settings.noPhoto === true &&
|
||||
settings.noMetadata === true &&
|
||||
settings.noMetaFile === true &&
|
||||
settings.noVideo === true
|
||||
) {
|
||||
return directory;
|
||||
@ -270,6 +270,6 @@ export interface DirectoryScanSettings {
|
||||
noVideo?: boolean;
|
||||
noPhoto?: boolean;
|
||||
noDirectory?: boolean;
|
||||
noMetadata?: boolean;
|
||||
noMetadata?: boolean; // skip parsing images for metadata like exif, iptc
|
||||
noChildDirPhotos?: boolean;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ export enum DefaultsJobs {
|
||||
'Temp Folder Cleaning' = 6,
|
||||
'Preview Filling' = 7,
|
||||
'Preview Reset' = 8,
|
||||
'GPX Compression' = 9,
|
||||
}
|
||||
|
||||
export interface ConfigTemplateEntry {
|
||||
|
@ -31,8 +31,6 @@ export class BackendtextService {
|
||||
switch (job as DefaultsJobs) {
|
||||
case DefaultsJobs.Indexing:
|
||||
return $localize`Indexing`;
|
||||
case DefaultsJobs['Preview Filling']:
|
||||
return $localize`Preview Filling`;
|
||||
case DefaultsJobs['Database Reset']:
|
||||
return $localize`Database Reset`;
|
||||
case DefaultsJobs['Thumbnail Generation']:
|
||||
@ -43,6 +41,12 @@ export class BackendtextService {
|
||||
return $localize`Video Converting`;
|
||||
case DefaultsJobs['Temp Folder Cleaning']:
|
||||
return $localize`Temp Folder Cleaning`;
|
||||
case DefaultsJobs['Preview Filling']:
|
||||
return $localize`Preview Filling`;
|
||||
case DefaultsJobs['Preview Reset']:
|
||||
return $localize`Preview Reset`;
|
||||
case DefaultsJobs['GPX Compression']:
|
||||
return $localize`GPX Compression`;
|
||||
default:
|
||||
return DefaultsJobs[job as DefaultsJobs];
|
||||
}
|
||||
|
@ -72,8 +72,8 @@
|
||||
<!-- Modal -->
|
||||
<ng-template #template>
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title pull-left">{{Name}}</h4>
|
||||
<button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
|
||||
<h5 class="modal-title" >{{Name}}</h5>
|
||||
<button type="button" class="btn-close" (click)="modalRef.hide()" data-dismiss="modal" aria-label="Close">
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
@ -7,6 +7,22 @@
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
|
||||
|
||||
<app-settings-entry
|
||||
name="Markdown files"
|
||||
description="Reads *.md files in a directory and shows the next to the map."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.client.markdown">
|
||||
</app-settings-entry>
|
||||
|
||||
<app-settings-entry
|
||||
name="*.pg2conf files"
|
||||
description="Reads *.pg2conf files (You can use it for custom sorting and save search (albums))."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.client.pg2conf">
|
||||
</app-settings-entry>
|
||||
|
||||
<hr/>
|
||||
|
||||
<app-settings-entry
|
||||
name="*.gpx files"
|
||||
description="Reads *.gpx files and renders them on the map."
|
||||
@ -34,21 +50,6 @@
|
||||
[ngModel]="states.server.GPXCompressing.onTheFly">
|
||||
</app-settings-entry>
|
||||
|
||||
<hr/>
|
||||
|
||||
<app-settings-entry
|
||||
name="Markdown files"
|
||||
description="Reads *.md files in a directory and shows the next to the map."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.client.markdown">
|
||||
</app-settings-entry>
|
||||
|
||||
<app-settings-entry
|
||||
name="*.pg2conf files"
|
||||
description="Reads *.pg2conf files (You can use it for custom sorting and save search (albums))."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.client.pg2conf">
|
||||
</app-settings-entry>
|
||||
|
||||
|
||||
<button class="btn btn-success float-end"
|
||||
@ -59,6 +60,21 @@
|
||||
[disabled]=" !changed || inProgress"
|
||||
(click)="reset()" i18n>Reset
|
||||
</button>
|
||||
|
||||
<div [hidden]="!states.client.GPXCompressing.enabled.value || !states.client.gpx.value">
|
||||
<app-settings-job-button class="mt-2 mt-md-0 float-left"
|
||||
[soloRun]="true"
|
||||
(jobError)="error=$event"
|
||||
[allowParallelRun]="false"
|
||||
[jobName]="jobName"></app-settings-job-button>
|
||||
|
||||
<ng-container *ngIf="Progress != null">
|
||||
<br/>
|
||||
<hr/>
|
||||
<app-settings-job-progress [progress]="Progress"></app-settings-job-progress>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -6,6 +6,9 @@ import { NavigationService } from '../../../model/navigation.service';
|
||||
import { NotificationService } from '../../../model/notification.service';
|
||||
import {ClientMetaFileConfig, ClientPhotoConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
import {ServerMetaFileConfig, ServerPhotoConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {DefaultsJobs, JobDTOUtils} from '../../../../../common/entities/job/JobDTO';
|
||||
import {JobProgressDTO, JobProgressStates} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-meta-file',
|
||||
@ -24,7 +27,8 @@ export class MetaFileSettingsComponent extends SettingsComponentDirective<{
|
||||
authService: AuthenticationService,
|
||||
navigation: NavigationService,
|
||||
settingsService: MetaFileSettingsService,
|
||||
notification: NotificationService
|
||||
notification: NotificationService,
|
||||
public jobsService: ScheduledJobsService,
|
||||
) {
|
||||
super(
|
||||
$localize`Meta file`,
|
||||
@ -39,6 +43,17 @@ export class MetaFileSettingsComponent extends SettingsComponentDirective<{
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
readonly jobName = DefaultsJobs[DefaultsJobs['GPX Compression']];
|
||||
|
||||
|
||||
get Progress(): JobProgressDTO {
|
||||
return this.jobsService.progress.value[
|
||||
JobDTOUtils.getHashName(DefaultsJobs[DefaultsJobs['GPX Compression']])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,6 @@ export class PhotoSettingsComponent extends SettingsComponentDirective<{
|
||||
}> {
|
||||
readonly resolutionTypes = [720, 1080, 1440, 2160, 4320];
|
||||
resolutions: { key: number; value: string }[] = [];
|
||||
JobProgressStates = JobProgressStates;
|
||||
|
||||
readonly jobName = DefaultsJobs[DefaultsJobs['Photo Converting']];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user