mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-11-21 17:56:45 +02:00
Fixing lint errors
This commit is contained in:
parent
8571c95b45
commit
b1c9827729
@ -27,7 +27,8 @@
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.component.html"
|
||||
"*.component.html",
|
||||
"index.html"
|
||||
],
|
||||
"parser": "@angular-eslint/template-parser",
|
||||
"parserOptions": {
|
||||
|
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -51,7 +51,7 @@ jobs:
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
- name: tslint
|
||||
- name: lint
|
||||
run: |
|
||||
npm run lint
|
||||
- name: test
|
||||
|
@ -15,7 +15,7 @@ class ProjectPathClass {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
normalizeRelative(pathStr: string): any {
|
||||
normalizeRelative(pathStr: string): string {
|
||||
return path.join(pathStr, path.sep);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import * as cluster from 'cluster';
|
||||
import { Server } from './server';
|
||||
import { Worker } from './model/threading/Worker';
|
||||
import {Server} from './server';
|
||||
import {Worker} from './model/threading/Worker';
|
||||
|
||||
if ((cluster as any).isMaster) {
|
||||
new Server();
|
||||
|
@ -4,6 +4,7 @@ import * as archiver from 'archiver';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { ErrorCodes, ErrorDTO } from '../../common/entities/Error';
|
||||
import {
|
||||
DirectoryBaseDTO,
|
||||
DirectoryDTOUtils,
|
||||
ParentDirectoryDTO,
|
||||
} from '../../common/entities/DirectoryDTO';
|
||||
@ -32,7 +33,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
const directoryName = req.params['directory'] || '/';
|
||||
const absoluteDirectoryName = path.join(
|
||||
ProjectPath.ImageFolder,
|
||||
@ -91,7 +92,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Other.enableDownloadZip === false) {
|
||||
return next();
|
||||
}
|
||||
@ -120,7 +121,7 @@ export class GalleryMWs {
|
||||
console.log('zip ' + archive.pointer() + ' bytes');
|
||||
});
|
||||
|
||||
archive.on('error', (err: any) => {
|
||||
archive.on('error', (err: Error) => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
@ -151,7 +152,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
@ -175,7 +176,7 @@ export class GalleryMWs {
|
||||
delete (m as PhotoDTO).metadata.positionData;
|
||||
}
|
||||
if (m.directory) {
|
||||
delete (m.directory as any).id;
|
||||
delete (m.directory as DirectoryBaseDTO).id;
|
||||
}
|
||||
Utils.removeNullOrEmptyObj(m);
|
||||
}
|
||||
@ -216,7 +217,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.params['mediaPath']) {
|
||||
return next();
|
||||
}
|
||||
@ -248,7 +249,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
@ -272,7 +273,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (
|
||||
Config.Client.Search.enabled === false ||
|
||||
!req.params['searchQueryDTO']
|
||||
@ -315,7 +316,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Search.AutoComplete.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
@ -345,7 +346,7 @@ export class GalleryMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (
|
||||
Config.Client.RandomPhoto.enabled === false ||
|
||||
!req.params['searchQueryDTO']
|
||||
|
@ -3,7 +3,7 @@ import { UserRoles } from '../../common/entities/UserDTO';
|
||||
import { NotificationManager } from '../model/NotifocationManager';
|
||||
|
||||
export class NotificationMWs {
|
||||
public static list(req: Request, res: Response, next: NextFunction): any {
|
||||
public static list(req: Request, res: Response, next: NextFunction): void {
|
||||
if (req.session['user'].role >= UserRoles.Admin) {
|
||||
req.resultPipe = NotificationManager.notifications;
|
||||
} else if (NotificationManager.notifications.length > 0) {
|
||||
|
@ -12,7 +12,7 @@ export class PersonMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.params['name']) {
|
||||
return next();
|
||||
}
|
||||
@ -39,7 +39,7 @@ export class PersonMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.params['name']) {
|
||||
return next();
|
||||
}
|
||||
@ -64,7 +64,7 @@ export class PersonMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
try {
|
||||
req.resultPipe =
|
||||
await ObjectManagers.getInstance().PersonManager.getAll();
|
||||
@ -85,7 +85,7 @@ export class PersonMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export class RenderingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (typeof req.resultPipe === 'undefined') {
|
||||
return next();
|
||||
}
|
||||
@ -26,7 +26,7 @@ export class RenderingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (!req.session['user']) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'User not exists'));
|
||||
}
|
||||
@ -51,12 +51,12 @@ export class RenderingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const { password, creator, ...sharing } = req.resultPipe;
|
||||
const { password, creator, ...sharing } = req.resultPipe as SharingDTO;
|
||||
RenderingMWs.renderMessage(res, sharing);
|
||||
}
|
||||
|
||||
@ -64,12 +64,12 @@ export class RenderingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const shares: SharingDTO[] = Utils.clone(req.resultPipe);
|
||||
const shares = Utils.clone(req.resultPipe as SharingDTO[]);
|
||||
shares.forEach((s): void => {
|
||||
delete s.password;
|
||||
delete s.creator.password;
|
||||
@ -81,11 +81,11 @@ export class RenderingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
return res.sendFile(req.resultPipe, {
|
||||
return res.sendFile(req.resultPipe as string, {
|
||||
maxAge: 31536000,
|
||||
dotfiles: 'allow',
|
||||
});
|
||||
@ -93,8 +93,7 @@ export class RenderingMWs {
|
||||
|
||||
public static renderOK(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
res: Response
|
||||
): void {
|
||||
const message = new Message<string>(null, 'ok');
|
||||
res.json(message);
|
||||
@ -102,8 +101,7 @@ export class RenderingMWs {
|
||||
|
||||
public static async renderConfig(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
const originalConf = await Config.original();
|
||||
// These are sensitive information, do not send to the client side
|
||||
@ -114,17 +112,17 @@ export class RenderingMWs {
|
||||
originalConf.toJSON({
|
||||
attachState: true,
|
||||
attachVolatile: true,
|
||||
}) as any
|
||||
}) as PrivateConfigClass
|
||||
);
|
||||
res.json(message);
|
||||
}
|
||||
|
||||
public static renderError(
|
||||
err: any,
|
||||
err: Error,
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (err instanceof ErrorDTO) {
|
||||
if (err.details) {
|
||||
Logger.warn('Handled error:');
|
||||
@ -143,8 +141,9 @@ export class RenderingMWs {
|
||||
delete err.detailsStr;
|
||||
}
|
||||
}
|
||||
const message = new Message<any>(err, null);
|
||||
return res.json(message);
|
||||
const message = new Message<null>(err, null);
|
||||
res.json(message);
|
||||
return;
|
||||
}
|
||||
NotificationManager.error('Unknown server error', err, req);
|
||||
return next(err);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { Config } from '../../common/config/private/Config';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
|
||||
export class ServerTimeEntry {
|
||||
public name: string;
|
||||
startHR: any;
|
||||
startHR: [number, number];
|
||||
public endTime: number = null;
|
||||
|
||||
constructor(name: string) {
|
||||
@ -22,10 +22,10 @@ export class ServerTimeEntry {
|
||||
|
||||
export const ServerTime = (id: string, name: string) => {
|
||||
return (
|
||||
target: any,
|
||||
target: unknown,
|
||||
propertyName: string,
|
||||
descriptor: TypedPropertyDescriptor<any>
|
||||
): any => {
|
||||
descriptor: TypedPropertyDescriptor<(req: unknown, res: unknown, next: () => void) => void>
|
||||
): void => {
|
||||
if (Config.Server.Log.logServerTiming === false) {
|
||||
return;
|
||||
}
|
||||
@ -34,7 +34,7 @@ export const ServerTime = (id: string, name: string) => {
|
||||
req.timing = req.timing || {};
|
||||
req.timing[id] = new ServerTimeEntry(name);
|
||||
req.timing[id].start();
|
||||
m(req, res, (err?: any) => {
|
||||
m(req, res, (err?: Error) => {
|
||||
req.timing[id].end();
|
||||
next(err);
|
||||
});
|
||||
@ -56,7 +56,7 @@ export class ServerTimingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (
|
||||
(Config.Server.Log.logServerTiming === false && !forcedDebug) ||
|
||||
!req.timing
|
||||
|
@ -12,7 +12,7 @@ export class SharingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
@ -39,7 +39,7 @@ export class SharingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
@ -104,7 +104,7 @@ export class SharingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
@ -158,7 +158,7 @@ export class SharingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
@ -194,7 +194,7 @@ export class SharingMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export class VersionMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
try {
|
||||
res.header(
|
||||
CustomHeaders.dataVersion,
|
||||
|
@ -101,7 +101,7 @@ export class AdminMWs {
|
||||
): Promise<void> {
|
||||
try {
|
||||
const id = req.params['id'];
|
||||
const JobConfig: any = req.body.config;
|
||||
const JobConfig: unknown = req.body.config;
|
||||
const soloRun: boolean = req.body.soloRun;
|
||||
const allowParallelRun: boolean = req.body.allowParallelRun;
|
||||
await ObjectManagers.getInstance().JobManager.run(
|
||||
|
@ -36,7 +36,7 @@ const LOG_TAG = '[SettingsMWs]';
|
||||
|
||||
export class SettingsMWs {
|
||||
|
||||
public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
@ -77,7 +77,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateMapSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateMapSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -102,7 +102,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updatePreviewSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updatePreviewSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -127,7 +127,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateVideoSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateVideoSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -160,7 +160,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateMetaFileSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateMetaFileSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -187,7 +187,7 @@ export class SettingsMWs {
|
||||
}
|
||||
|
||||
|
||||
public static async updateAlbumsSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateAlbumsSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -213,7 +213,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateShareSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateShareSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -238,7 +238,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateRandomPhotoSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateRandomPhotoSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -263,7 +263,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateSearchSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateSearchSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -288,7 +288,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateFacesSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateFacesSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -313,7 +313,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateAuthenticationSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateAuthenticationSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -339,7 +339,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateThumbnailSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateThumbnailSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -372,7 +372,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updatePhotoSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updatePhotoSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -405,7 +405,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateBasicSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateBasicSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -432,7 +432,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateOtherSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateOtherSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -459,7 +459,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateIndexingSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateIndexingSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
@ -484,7 +484,7 @@ export class SettingsMWs {
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateJobSettings(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||
public static async updateJobSettings(req: Request, res: Response, next: NextFunction): Promise<void> {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { LoginCredential } from '../../../common/entities/LoginCredential';
|
||||
import { UserDTO } from '../../../common/entities/UserDTO';
|
||||
import {LoginCredential} from '../../../common/entities/LoginCredential';
|
||||
import {UserDTO} from '../../../common/entities/UserDTO';
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
resultPipe?: any;
|
||||
resultPipe?: unknown;
|
||||
body?: {
|
||||
loginCredential?: LoginCredential;
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ export class PhotoConverterMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
@ -16,7 +16,7 @@ export class PhotoConverterMWs {
|
||||
if (Config.Client.Media.Photo.Converting.enabled === false) {
|
||||
return res.redirect(req.originalUrl.slice(0, -1 * '\\bestFit'.length));
|
||||
}
|
||||
const fullMediaPath = req.resultPipe;
|
||||
const fullMediaPath = req.resultPipe as string;
|
||||
|
||||
const convertedVideo = PhotoProcessing.generateConvertedPath(
|
||||
fullMediaPath,
|
||||
|
@ -24,13 +24,13 @@ export class ThumbnailGeneratorMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
try {
|
||||
const cw: ContentWrapper = req.resultPipe;
|
||||
const cw: ContentWrapper = req.resultPipe as ContentWrapper;
|
||||
if (cw.notModified === true) {
|
||||
return next();
|
||||
}
|
||||
@ -67,7 +67,7 @@ export class ThumbnailGeneratorMWs {
|
||||
try {
|
||||
const size: number = Config.Client.Media.Thumbnail.personThumbnailSize;
|
||||
|
||||
const persons: PersonWithSampleRegion[] = req.resultPipe;
|
||||
const persons: PersonWithSampleRegion[] = req.resultPipe as PersonWithSampleRegion[];
|
||||
|
||||
for (const item of persons) {
|
||||
if (!item.sampleRegion) {
|
||||
@ -107,11 +107,11 @@ export class ThumbnailGeneratorMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
const person: PersonWithSampleRegion = req.resultPipe;
|
||||
const person: PersonWithSampleRegion = req.resultPipe as PersonWithSampleRegion;
|
||||
try {
|
||||
req.resultPipe = await PhotoProcessing.generatePersonThumbnail(person);
|
||||
return next();
|
||||
@ -129,18 +129,18 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
public static generateThumbnailFactory(
|
||||
sourceType: ThumbnailSourceType
|
||||
): (req: Request, res: Response, next: NextFunction) => Promise<any> {
|
||||
): (req: Request, res: Response, next: NextFunction) => Promise<void> {
|
||||
return async (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> => {
|
||||
): Promise<void> => {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// load parameters
|
||||
const mediaPath = req.resultPipe;
|
||||
const mediaPath = req.resultPipe as string;
|
||||
let size: number =
|
||||
parseInt(req.params.size, 10) ||
|
||||
Config.Client.Media.Thumbnail.thumbnailSizes[0];
|
||||
@ -172,18 +172,18 @@ export class ThumbnailGeneratorMWs {
|
||||
|
||||
public static generateIconFactory(
|
||||
sourceType: ThumbnailSourceType
|
||||
): (req: Request, res: Response, next: NextFunction) => Promise<any> {
|
||||
): (req: Request, res: Response, next: NextFunction) => Promise<void> {
|
||||
return async (
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> => {
|
||||
): Promise<void> => {
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// load parameters
|
||||
const mediaPath = req.resultPipe;
|
||||
const mediaPath = req.resultPipe as string;
|
||||
const size: number = Config.Client.Media.Thumbnail.iconSize;
|
||||
|
||||
try {
|
||||
@ -232,10 +232,11 @@ export class ThumbnailGeneratorMWs {
|
||||
photo.directory.name,
|
||||
photo.name
|
||||
);
|
||||
for (const size of Object.keys(ThumbnailGeneratorMWs.ThumbnailMap)) {
|
||||
for (const _s of Object.keys(ThumbnailGeneratorMWs.ThumbnailMap)) {
|
||||
const size = parseInt(_s)
|
||||
const thPath = PhotoProcessing.generateConvertedPath(
|
||||
fullMediaPath,
|
||||
size as any
|
||||
size
|
||||
);
|
||||
if (fs.existsSync(thPath) !== true) {
|
||||
if (typeof photo.missingThumbnails === 'undefined') {
|
||||
@ -243,7 +244,7 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
// this is a bitwise operation
|
||||
photo.missingThumbnails +=
|
||||
ThumbnailGeneratorMWs.ThumbnailMap[size as any];
|
||||
ThumbnailGeneratorMWs.ThumbnailMap[size];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,11 @@ export class AuthenticationMWs {
|
||||
}
|
||||
try {
|
||||
const user = await AuthenticationMWs.getSharingUser(req);
|
||||
if (!!user) {
|
||||
if (user) {
|
||||
req.session['user'] = user;
|
||||
return next();
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (err) {}
|
||||
|
||||
return next();
|
||||
@ -56,7 +57,7 @@ export class AuthenticationMWs {
|
||||
|
||||
try {
|
||||
const user = await AuthenticationMWs.getSharingUser(req);
|
||||
if (!!user) {
|
||||
if (user) {
|
||||
req.session['user'] = user;
|
||||
return next();
|
||||
}
|
||||
@ -82,6 +83,7 @@ export class AuthenticationMWs {
|
||||
): void {
|
||||
req.params[paramName] = path
|
||||
.normalize(req.params[paramName] || path.sep)
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
.replace(/^(\.\.[\/\\])+/, '');
|
||||
return next();
|
||||
};
|
||||
|
@ -9,7 +9,7 @@ export class UserMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
@ -37,7 +37,7 @@ export class UserMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
@ -62,7 +62,7 @@ export class UserMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
@ -87,7 +87,7 @@ export class UserMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
@ -115,7 +115,7 @@ export class UserMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.USER_MANAGEMENT_DISABLED));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ export class UserRequestConstrainsMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (
|
||||
typeof req.params === 'undefined' ||
|
||||
typeof req.params.id === 'undefined'
|
||||
@ -27,7 +27,7 @@ export class UserRequestConstrainsMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): any {
|
||||
): void {
|
||||
if (
|
||||
typeof req.params === 'undefined' ||
|
||||
typeof req.params.id === 'undefined'
|
||||
@ -46,7 +46,7 @@ export class UserRequestConstrainsMWs {
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): Promise<any> {
|
||||
): Promise<void> {
|
||||
if (
|
||||
typeof req.params === 'undefined' ||
|
||||
typeof req.params.id === 'undefined'
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
export class FFmpegFactory {
|
||||
public static get(): any {
|
||||
const ffmpeg = require('fluent-ffmpeg');
|
||||
@ -6,7 +7,9 @@ export class FFmpegFactory {
|
||||
ffmpeg.setFfmpegPath(ffmpegPath);
|
||||
const ffprobePath = require('ffprobe-static');
|
||||
ffmpeg.setFfprobePath(ffprobePath.path);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
return ffmpeg;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
import { ProjectPath } from '../ProjectPath';
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { Config } from '../../common/config/private/Config';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
|
||||
export class Localizations {
|
||||
constructor() {}
|
||||
|
||||
public static init(): void {
|
||||
const notLanguage = ['assets'];
|
||||
const dirCont = fs
|
||||
.readdirSync(ProjectPath.FrontendFolder)
|
||||
.filter((f): any =>
|
||||
.filter((f): boolean =>
|
||||
fs.statSync(path.join(ProjectPath.FrontendFolder, f)).isDirectory()
|
||||
);
|
||||
Config.Client.languages = dirCont.filter(
|
||||
|
@ -14,7 +14,7 @@ export class NotificationManager {
|
||||
},
|
||||
];
|
||||
|
||||
public static error(message: string, details?: any, req?: Request): void {
|
||||
public static error(message: string, details?: unknown, req?: Request): void {
|
||||
const noti: NotificationDTO = {
|
||||
type: NotificationType.error,
|
||||
message,
|
||||
@ -30,7 +30,7 @@ export class NotificationManager {
|
||||
NotificationManager.notifications.push(noti);
|
||||
}
|
||||
|
||||
public static warning(message: string, details?: any, req?: Request): void {
|
||||
public static warning(message: string, details?: unknown, req?: Request): void {
|
||||
const noti: NotificationDTO = {
|
||||
type: NotificationType.warning,
|
||||
message,
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import { IUserManager } from './database/interfaces/IUserManager';
|
||||
import { IGalleryManager } from './database/interfaces/IGalleryManager';
|
||||
import { ISearchManager } from './database/interfaces/ISearchManager';
|
||||
|
@ -12,6 +12,7 @@ export class PasswordHelper {
|
||||
): boolean {
|
||||
try {
|
||||
return bcrypt.compareSync(password, encryptedPassword);
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {}
|
||||
return false;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { IObjectManager } from './IObjectManager';
|
||||
export interface IJobManager extends IObjectManager {
|
||||
run(
|
||||
jobId: string,
|
||||
config: any,
|
||||
config: unknown,
|
||||
soloRun: boolean,
|
||||
allowParallelRun: boolean
|
||||
): Promise<void>;
|
||||
|
@ -13,5 +13,4 @@ export interface IUserManager extends IObjectManager {
|
||||
|
||||
changeRole(id: number, newRole: UserRoles): Promise<UserDTO>;
|
||||
|
||||
changePassword(request: any): Promise<void>;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
const processDuplicates = (
|
||||
duplicateList: MediaEntity[],
|
||||
equalFn: (a: MediaEntity, b: MediaEntity) => boolean,
|
||||
checkDuplicates: boolean = false
|
||||
checkDuplicates = false
|
||||
): void => {
|
||||
let i = duplicateList.length - 1;
|
||||
while (i >= 0) {
|
||||
@ -224,7 +224,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
if (foundDuplicates) {
|
||||
list.forEach((lm): void => {
|
||||
if (
|
||||
!!foundDuplicates.media.find((m): boolean => m.id === lm.id)
|
||||
foundDuplicates.media.find((m): boolean => m.id === lm.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ const LOG_TAG = '[SQLConnection]';
|
||||
export class SQLConnection {
|
||||
private static connection: Connection = null;
|
||||
|
||||
constructor() {}
|
||||
|
||||
public static async getConnection(): Promise<Connection> {
|
||||
if (this.connection == null) {
|
||||
@ -78,6 +77,7 @@ export class SQLConnection {
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
await getConnection('test').close();
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (err) {}
|
||||
const options: any = this.getDriver(config);
|
||||
options.name = 'test';
|
||||
@ -189,6 +189,7 @@ export class SQLConnection {
|
||||
if (e.sqlMessage === "Unknown database '" + options.database + "'") {
|
||||
Logger.debug(LOG_TAG, 'creating database: ' + options.database);
|
||||
const tmpOption = Utils.clone(options);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
delete tmpOption.database;
|
||||
const tmpConn = await createConnection(tmpOption);
|
||||
@ -206,6 +207,7 @@ export class SQLConnection {
|
||||
let version = null;
|
||||
try {
|
||||
version = (await connection.getRepository(VersionEntity).find())[0];
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (ex) {}
|
||||
if (version && version.version === DataStructureVersion) {
|
||||
return;
|
||||
@ -222,6 +224,7 @@ export class SQLConnection {
|
||||
.getRepository(UserEntity)
|
||||
.createQueryBuilder('user')
|
||||
.getMany();
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (ex) {}
|
||||
await connection.dropDatabase();
|
||||
await connection.synchronize();
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { AutoCompleteItem } from '../../../../common/entities/AutoCompleteItem';
|
||||
import { SearchResultDTO } from '../../../../common/entities/SearchResultDTO';
|
||||
import { SQLConnection } from './SQLConnection';
|
||||
import { PhotoEntity } from './enitites/PhotoEntity';
|
||||
import { DirectoryEntity } from './enitites/DirectoryEntity';
|
||||
import { MediaEntity } from './enitites/MediaEntity';
|
||||
import { PersonEntry } from './enitites/PersonEntry';
|
||||
import { Brackets, SelectQueryBuilder, WhereExpression } from 'typeorm';
|
||||
import { Config } from '../../../../common/config/private/Config';
|
||||
/* eslint-disable no-case-declarations */
|
||||
import {AutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {PhotoEntity} from './enitites/PhotoEntity';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {MediaEntity} from './enitites/MediaEntity';
|
||||
import {PersonEntry} from './enitites/PersonEntry';
|
||||
import {Brackets, SelectQueryBuilder, WhereExpression} from 'typeorm';
|
||||
import {Config} from '../../../../common/config/private/Config';
|
||||
import {
|
||||
ANDSearchQuery,
|
||||
DistanceSearch,
|
||||
@ -25,15 +26,15 @@ import {
|
||||
TextSearchQueryMatchTypes,
|
||||
ToDateSearch,
|
||||
} from '../../../../common/entities/SearchQueryDTO';
|
||||
import { GalleryManager } from './GalleryManager';
|
||||
import { ObjectManagers } from '../../ObjectManagers';
|
||||
import { PhotoDTO } from '../../../../common/entities/PhotoDTO';
|
||||
import { DatabaseType } from '../../../../common/config/private/PrivateConfig';
|
||||
import { ISQLGalleryManager } from './IGalleryManager';
|
||||
import { ISQLSearchManager } from './ISearchManager';
|
||||
import { Utils } from '../../../../common/Utils';
|
||||
import { FileEntity } from './enitites/FileEntity';
|
||||
import { SQL_COLLATE } from './enitites/EntityUtils';
|
||||
import {GalleryManager} from './GalleryManager';
|
||||
import {ObjectManagers} from '../../ObjectManagers';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {DatabaseType} from '../../../../common/config/private/PrivateConfig';
|
||||
import {ISQLGalleryManager} from './IGalleryManager';
|
||||
import {ISQLSearchManager} from './ISearchManager';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {FileEntity} from './enitites/FileEntity';
|
||||
import {SQL_COLLATE} from './enitites/EntityUtils';
|
||||
|
||||
export class SearchManager implements ISQLSearchManager {
|
||||
// This trick enables us to list less rows as faces will be concatenated into one row
|
||||
@ -41,8 +42,8 @@ export class SearchManager implements ISQLSearchManager {
|
||||
// (i.e: leftJoinAndSelect('media.metadata.faces', 'faces') does not work)
|
||||
private FACE_SELECT =
|
||||
Config.Server.Database.type === DatabaseType.mysql
|
||||
? "CONCAT('[' , GROUP_CONCAT( '{\"name\": \"' , person.name , '\", \"box\": {\"top\":' , faces.box.top , ', \"left\":' , faces.box.left , ', \"height\":' , faces.box.height ,', \"width\":' , faces.box.width , '}}' ) ,']') as media_metadataFaces"
|
||||
: "'[' || GROUP_CONCAT( '{\"name\": \"' || person.name || '\", \"box\": {\"top\":' || faces.box.top || ', \"left\":' || faces.box.left || ', \"height\":' || faces.box.height ||', \"width\":' || faces.box.width || '}}' ) ||']' as media_metadataFaces";
|
||||
? 'CONCAT(\'[\' , GROUP_CONCAT( \'{"name": "\' , person.name , \'", "box": {"top":\' , faces.box.top , \', "left":\' , faces.box.left , \', "height":\' , faces.box.height ,\', "width":\' , faces.box.width , \'}}\' ) ,\']\') as media_metadataFaces'
|
||||
: '\'[\' || GROUP_CONCAT( \'{"name": "\' || person.name || \'", "box": {"top":\' || faces.box.top || \', "left":\' || faces.box.left || \', "height":\' || faces.box.height ||\', "width":\' || faces.box.width || \'}}\' ) ||\']\' as media_metadataFaces';
|
||||
private DIRECTORY_SELECT = [
|
||||
'directory.id',
|
||||
'directory.name',
|
||||
@ -147,22 +148,22 @@ export class SearchManager implements ISQLSearchManager {
|
||||
.createQueryBuilder('photo')
|
||||
.select(
|
||||
'photo.metadata.positionData.country as country, ' +
|
||||
'photo.metadata.positionData.state as state, photo.metadata.positionData.city as city'
|
||||
'photo.metadata.positionData.state as state, photo.metadata.positionData.city as city'
|
||||
)
|
||||
.where(
|
||||
'photo.metadata.positionData.country LIKE :text COLLATE ' +
|
||||
SQL_COLLATE,
|
||||
{ text: '%' + text + '%' }
|
||||
SQL_COLLATE,
|
||||
{text: '%' + text + '%'}
|
||||
)
|
||||
.orWhere(
|
||||
'photo.metadata.positionData.state LIKE :text COLLATE ' +
|
||||
SQL_COLLATE,
|
||||
{ text: '%' + text + '%' }
|
||||
SQL_COLLATE,
|
||||
{text: '%' + text + '%'}
|
||||
)
|
||||
.orWhere(
|
||||
'photo.metadata.positionData.city LIKE :text COLLATE ' +
|
||||
SQL_COLLATE,
|
||||
{ text: '%' + text + '%' }
|
||||
SQL_COLLATE,
|
||||
{text: '%' + text + '%'}
|
||||
)
|
||||
.groupBy(
|
||||
'photo.metadata.positionData.country, photo.metadata.positionData.state, photo.metadata.positionData.city'
|
||||
@ -226,7 +227,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
.select('DISTINCT(media.metadata.caption) as caption')
|
||||
.where(
|
||||
'media.metadata.caption LIKE :text COLLATE ' + SQL_COLLATE,
|
||||
{ text: '%' + text + '%' }
|
||||
{text: '%' + text + '%'}
|
||||
)
|
||||
.limit(
|
||||
Config.Client.Search.AutoComplete.targetItemsPerCategory * 2
|
||||
@ -428,16 +429,18 @@ export class SearchManager implements ISQLSearchManager {
|
||||
const queryId = (query as SearchQueryDTOWithID).queryId;
|
||||
switch (query.type) {
|
||||
case SearchQueryTypes.AND:
|
||||
return new Brackets((q): any => {
|
||||
(query as ANDSearchQuery).list.forEach((sq): any =>
|
||||
q.andWhere(this.buildWhereQuery(sq, directoryOnly))
|
||||
return new Brackets((q): unknown => {
|
||||
(query as ANDSearchQuery).list.forEach((sq) => {
|
||||
q.andWhere(this.buildWhereQuery(sq, directoryOnly));
|
||||
}
|
||||
);
|
||||
return q;
|
||||
});
|
||||
case SearchQueryTypes.OR:
|
||||
return new Brackets((q): any => {
|
||||
(query as ANDSearchQuery).list.forEach((sq): any =>
|
||||
q.orWhere(this.buildWhereQuery(sq, directoryOnly))
|
||||
return new Brackets((q): unknown => {
|
||||
(query as ANDSearchQuery).list.forEach((sq) => {
|
||||
q.orWhere(this.buildWhereQuery(sq, directoryOnly));
|
||||
}
|
||||
);
|
||||
return q;
|
||||
});
|
||||
@ -461,33 +464,33 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
const minLat = trimRange(
|
||||
(query as DistanceSearch).from.GPSData.latitude -
|
||||
(query as DistanceSearch).distance * latDelta,
|
||||
(query as DistanceSearch).distance * latDelta,
|
||||
-90,
|
||||
90
|
||||
);
|
||||
const maxLat = trimRange(
|
||||
(query as DistanceSearch).from.GPSData.latitude +
|
||||
(query as DistanceSearch).distance * latDelta,
|
||||
(query as DistanceSearch).distance * latDelta,
|
||||
-90,
|
||||
90
|
||||
);
|
||||
const minLon = trimRange(
|
||||
(query as DistanceSearch).from.GPSData.longitude -
|
||||
((query as DistanceSearch).distance * lonDelta) /
|
||||
Math.cos(minLat * (Math.PI / 180)),
|
||||
((query as DistanceSearch).distance * lonDelta) /
|
||||
Math.cos(minLat * (Math.PI / 180)),
|
||||
-180,
|
||||
180
|
||||
);
|
||||
const maxLon = trimRange(
|
||||
(query as DistanceSearch).from.GPSData.longitude +
|
||||
((query as DistanceSearch).distance * lonDelta) /
|
||||
Math.cos(maxLat * (Math.PI / 180)),
|
||||
((query as DistanceSearch).distance * lonDelta) /
|
||||
Math.cos(maxLat * (Math.PI / 180)),
|
||||
-180,
|
||||
180
|
||||
);
|
||||
|
||||
return new Brackets((q): any => {
|
||||
const textParam: any = {};
|
||||
return new Brackets((q): unknown => {
|
||||
const textParam: { [key: string]: number | string } = {};
|
||||
textParam['maxLat' + queryId] = maxLat;
|
||||
textParam['minLat' + queryId] = minLat;
|
||||
textParam['maxLon' + queryId] = maxLon;
|
||||
@ -534,7 +537,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as FromDateSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Date Query should contain from value'
|
||||
@ -542,7 +545,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
}
|
||||
const relation = (query as TextSearch).negate ? '<' : '>=';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['from' + queryId] = (query as FromDateSearch).value;
|
||||
q.where(
|
||||
`media.metadata.creationDate ${relation} :from${queryId}`,
|
||||
@ -556,7 +559,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as ToDateSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Date Query should contain to value'
|
||||
@ -564,7 +567,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
}
|
||||
const relation = (query as TextSearch).negate ? '>' : '<=';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['to' + queryId] = (query as ToDateSearch).value;
|
||||
q.where(
|
||||
`media.metadata.creationDate ${relation} :to${queryId}`,
|
||||
@ -578,7 +581,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as MinRatingSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Rating Query should contain minvalue'
|
||||
@ -587,7 +590,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
const relation = (query as TextSearch).negate ? '<' : '>=';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['min' + queryId] = (query as MinRatingSearch).value;
|
||||
q.where(
|
||||
`media.metadata.rating ${relation} :min${queryId}`,
|
||||
@ -600,7 +603,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as MaxRatingSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Rating Query should contain max value'
|
||||
@ -610,7 +613,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
const relation = (query as TextSearch).negate ? '>' : '<=';
|
||||
|
||||
if (typeof (query as MaxRatingSearch).value !== 'undefined') {
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['max' + queryId] = (query as MaxRatingSearch).value;
|
||||
q.where(
|
||||
`media.metadata.rating ${relation} :max${queryId}`,
|
||||
@ -624,7 +627,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as MinResolutionSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Resolution Query should contain min value'
|
||||
@ -633,7 +636,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
const relation = (query as TextSearch).negate ? '<' : '>=';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['min' + queryId] =
|
||||
(query as MinResolutionSearch).value * 1000 * 1000;
|
||||
q.where(
|
||||
@ -648,7 +651,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if (typeof (query as MaxResolutionSearch).value === 'undefined') {
|
||||
throw new Error(
|
||||
'Invalid search query: Rating Query should contain min or max value'
|
||||
@ -657,7 +660,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
const relation = (query as TextSearch).negate ? '>' : '<=';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['max' + queryId] =
|
||||
(query as MaxResolutionSearch).value * 1000 * 1000;
|
||||
q.where(
|
||||
@ -672,7 +675,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
if (directoryOnly) {
|
||||
throw new Error('not supported in directoryOnly mode');
|
||||
}
|
||||
return new Brackets((q): any => {
|
||||
return new Brackets((q): unknown => {
|
||||
if ((query as OrientationSearch).landscape) {
|
||||
q.where('media.metadata.size.width >= media.metadata.size.height');
|
||||
} else {
|
||||
@ -707,7 +710,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
const whereFN = (query as TextSearch).negate ? 'andWhere' : 'orWhere';
|
||||
const whereFNRev = (query as TextSearch).negate ? 'orWhere' : 'andWhere';
|
||||
|
||||
const textParam: any = {};
|
||||
const textParam: { [key: string]: unknown } = {};
|
||||
textParam['text' + queryId] = createMatchString(
|
||||
(query as TextSearch).text
|
||||
);
|
||||
@ -729,7 +732,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
|
||||
const directoryPath = GalleryManager.parseRelativeDirePath(dirPathStr);
|
||||
q[whereFN](
|
||||
new Brackets((dq): any => {
|
||||
new Brackets((dq): unknown => {
|
||||
textParam['dirName' + queryId] = createMatchString(
|
||||
directoryPath.name
|
||||
);
|
||||
@ -778,15 +781,13 @@ export class SearchManager implements ISQLSearchManager {
|
||||
q[whereFN](
|
||||
`media.metadata.positionData.country ${LIKE} :text${queryId} COLLATE ${SQL_COLLATE}`,
|
||||
textParam
|
||||
)
|
||||
[whereFN](
|
||||
`media.metadata.positionData.state ${LIKE} :text${queryId} COLLATE ${SQL_COLLATE}`,
|
||||
textParam
|
||||
)
|
||||
[whereFN](
|
||||
`media.metadata.positionData.city ${LIKE} :text${queryId} COLLATE ${SQL_COLLATE}`,
|
||||
textParam
|
||||
);
|
||||
)[whereFN](
|
||||
`media.metadata.positionData.state ${LIKE} :text${queryId} COLLATE ${SQL_COLLATE}`,
|
||||
textParam
|
||||
)[whereFN](
|
||||
`media.metadata.positionData.city ${LIKE} :text${queryId} COLLATE ${SQL_COLLATE}`,
|
||||
textParam
|
||||
);
|
||||
}
|
||||
|
||||
// Matching for array type fields
|
||||
@ -956,7 +957,7 @@ export class SearchManager implements ISQLSearchManager {
|
||||
*/
|
||||
private assignQueryIDs(
|
||||
queryIN: SearchQueryDTO,
|
||||
id = { value: 1 }
|
||||
id = {value: 1}
|
||||
): SearchQueryDTO {
|
||||
// It is possible that one SQL query contains multiple searchQueries
|
||||
// (like: where (<searchQuery1> AND (<searchQuery2>))
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { UserDTO, UserRoles } from '../../../../common/entities/UserDTO';
|
||||
import { IUserManager } from '../interfaces/IUserManager';
|
||||
import { UserEntity } from './enitites/UserEntity';
|
||||
import { SQLConnection } from './SQLConnection';
|
||||
import { PasswordHelper } from '../../PasswordHelper';
|
||||
import { FindOptionsWhere } from 'typeorm';
|
||||
import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {IUserManager} from '../interfaces/IUserManager';
|
||||
import {UserEntity} from './enitites/UserEntity';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {PasswordHelper} from '../../PasswordHelper';
|
||||
import {FindOptionsWhere} from 'typeorm';
|
||||
|
||||
export class UserManager implements IUserManager {
|
||||
constructor() {}
|
||||
|
||||
public async findOne(filter: FindOptionsWhere<UserEntity>): Promise<any> {
|
||||
|
||||
public async findOne(filter: FindOptionsWhere<UserEntity>): Promise<UserEntity> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const pass = filter.password as string;
|
||||
delete filter.password;
|
||||
@ -20,32 +20,29 @@ export class UserManager implements IUserManager {
|
||||
return user;
|
||||
}
|
||||
|
||||
public async find(filter: FindOptionsWhere<UserDTO>): Promise<any> {
|
||||
public async find(filter: FindOptionsWhere<UserDTO>): Promise<UserEntity[]> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
return await connection.getRepository(UserEntity).findBy(filter);
|
||||
}
|
||||
|
||||
public async createUser(user: UserDTO): Promise<any> {
|
||||
public async createUser(user: UserDTO): Promise<UserEntity> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
user.password = PasswordHelper.cryptPassword(user.password);
|
||||
return connection.getRepository(UserEntity).save(user);
|
||||
}
|
||||
|
||||
public async deleteUser(id: number): Promise<any> {
|
||||
public async deleteUser(id: number): Promise<UserEntity> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const user = await connection.getRepository(UserEntity).findOneBy({ id });
|
||||
const user = await connection.getRepository(UserEntity).findOneBy({id});
|
||||
return await connection.getRepository(UserEntity).remove(user);
|
||||
}
|
||||
|
||||
public async changeRole(id: number, newRole: UserRoles): Promise<any> {
|
||||
public async changeRole(id: number, newRole: UserRoles): Promise<UserEntity> {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
const userRepository = connection.getRepository(UserEntity);
|
||||
const user = await userRepository.findOneBy({ id });
|
||||
const user = await userRepository.findOneBy({id});
|
||||
user.role = newRole;
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
public async changePassword(request: any): Promise<void> {
|
||||
throw new Error('not implemented'); // TODO: implement
|
||||
}
|
||||
}
|
||||
|
@ -138,6 +138,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
static async testSharp(): Promise<void> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const sharp = require('sharp');
|
||||
sharp();
|
||||
}
|
||||
|
@ -68,7 +68,9 @@ export class PhotoProcessing {
|
||||
try {
|
||||
await fsp.access(thPath, fsConstants.R_OK);
|
||||
return thPath;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
const margin = {
|
||||
x: Math.round(
|
||||
@ -203,7 +205,9 @@ export class PhotoProcessing {
|
||||
try {
|
||||
await fsp.access(outPath, fsConstants.R_OK);
|
||||
return true;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -220,7 +224,9 @@ export class PhotoProcessing {
|
||||
try {
|
||||
await fsp.access(outPath, fsConstants.R_OK);
|
||||
return outPath;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
// run on other thread
|
||||
const input = {
|
||||
|
@ -60,7 +60,9 @@ export class VideoProcessing {
|
||||
try {
|
||||
await fsp.access(outPath, fsConstants.R_OK);
|
||||
return true;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -71,7 +73,9 @@ export class VideoProcessing {
|
||||
try {
|
||||
await fsp.access(outPath, fsConstants.R_OK);
|
||||
return;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
const metaData = await MetadataLoader.loadVideoMetadata(videoPath);
|
||||
|
||||
|
@ -16,7 +16,9 @@ export class DBRestJob extends Job {
|
||||
return Config.Server.Database.type !== DatabaseType.memory;
|
||||
}
|
||||
|
||||
protected async init(): Promise<void> {}
|
||||
protected async init(): Promise<void> {
|
||||
// abstract function
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
this.Progress.Left = 1;
|
||||
|
@ -81,7 +81,9 @@ export class JobProgress {
|
||||
return this.logs;
|
||||
}
|
||||
|
||||
onChange = (progress: JobProgress): void => {};
|
||||
onChange = (progress: JobProgress): void => {
|
||||
// abstract function
|
||||
};
|
||||
|
||||
log(log: string): void {
|
||||
while (this.logs.length > 10) {
|
||||
|
@ -17,7 +17,9 @@ export class PreviewFillingJob extends Job {
|
||||
return Config.Server.Database.type !== DatabaseType.memory;
|
||||
}
|
||||
|
||||
protected async init(): Promise<void> {}
|
||||
protected async init(): Promise<void> {
|
||||
// abstract function
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
if (!this.directoryToSetPreview) {
|
||||
|
@ -16,7 +16,9 @@ export class PreviewRestJob extends Job {
|
||||
return Config.Server.Database.type !== DatabaseType.memory;
|
||||
}
|
||||
|
||||
protected async init(): Promise<void> {}
|
||||
protected async init(): Promise<void> {
|
||||
// abstract function
|
||||
}
|
||||
|
||||
protected async step(): Promise<boolean> {
|
||||
this.Progress.Left = 1;
|
||||
|
@ -42,7 +42,9 @@ export class TempFolderCleaningJob extends Job {
|
||||
try {
|
||||
await fs.promises.access(originalPath);
|
||||
return true;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,9 @@ export class DiskMangerWorker {
|
||||
try {
|
||||
await fsp.access(path.join(absoluteName, exclude));
|
||||
return true;
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { VideoMetadata } from '../../../common/entities/VideoDTO';
|
||||
import { FaceRegion, PhotoMetadata } from '../../../common/entities/PhotoDTO';
|
||||
import { Config } from '../../../common/config/private/Config';
|
||||
import { Logger } from '../../Logger';
|
||||
import {VideoMetadata} from '../../../common/entities/VideoDTO';
|
||||
import {FaceRegion, PhotoMetadata} from '../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {Logger} from '../../Logger';
|
||||
import * as fs from 'fs';
|
||||
import { imageSize } from 'image-size';
|
||||
import {imageSize} from 'image-size';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import * as ExifReader from 'exifreader';
|
||||
import { ExifParserFactory, OrientationTypes } from 'ts-exif-parser';
|
||||
import { IptcParser } from 'ts-node-iptc';
|
||||
import { FFmpegFactory } from '../FFmpegFactory';
|
||||
import { FfprobeData } from 'fluent-ffmpeg';
|
||||
import { Utils } from '../../../common/Utils';
|
||||
import {ExifParserFactory, OrientationTypes} from 'ts-exif-parser';
|
||||
import {IptcParser} from 'ts-node-iptc';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {FfprobeData} from 'fluent-ffmpeg';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
|
||||
const LOG_TAG = '[MetadataLoader]';
|
||||
const ffmpeg = FFmpegFactory.get();
|
||||
@ -34,7 +34,9 @@ export class MetadataLoader {
|
||||
const stat = fs.statSync(fullPath);
|
||||
metadata.fileSize = stat.size;
|
||||
metadata.creationDate = stat.mtime.getTime();
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
// ignoring errors
|
||||
}
|
||||
try {
|
||||
ffmpeg(fullPath).ffprobe((err: any, data: FfprobeData) => {
|
||||
if (!!err || data === null || !data.streams[0]) {
|
||||
@ -78,7 +80,8 @@ export class MetadataLoader {
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
}
|
||||
metadata.creationDate = metadata.creationDate || 0;
|
||||
|
||||
return resolve(metadata);
|
||||
@ -97,10 +100,10 @@ export class MetadataLoader {
|
||||
fs.read(fd, data, 0, Config.Server.photoMetadataSize, 0, (err) => {
|
||||
fs.closeSync(fd);
|
||||
if (err) {
|
||||
return reject({ file: fullPath, error: err });
|
||||
return reject({file: fullPath, error: err});
|
||||
}
|
||||
const metadata: PhotoMetadata = {
|
||||
size: { width: 1, height: 1 },
|
||||
size: {width: 1, height: 1},
|
||||
creationDate: 0,
|
||||
fileSize: 0,
|
||||
};
|
||||
@ -109,7 +112,9 @@ export class MetadataLoader {
|
||||
const stat = fs.statSync(fullPath);
|
||||
metadata.fileSize = stat.size;
|
||||
metadata.creationDate = stat.mtime.getTime();
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
try {
|
||||
const exif = ExifParserFactory.create(data).parse();
|
||||
@ -202,15 +207,15 @@ export class MetadataLoader {
|
||||
};
|
||||
} else {
|
||||
const info = imageSize(fullPath);
|
||||
metadata.size = { width: info.width, height: info.height };
|
||||
metadata.size = {width: info.width, height: info.height};
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.debug(LOG_TAG, 'Error parsing exif', fullPath, err);
|
||||
try {
|
||||
const info = imageSize(fullPath);
|
||||
metadata.size = { width: info.width, height: info.height };
|
||||
metadata.size = {width: info.width, height: info.height};
|
||||
} catch (e) {
|
||||
metadata.size = { width: 1, height: 1 };
|
||||
metadata.size = {width: 1, height: 1};
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +363,7 @@ export class MetadataLoader {
|
||||
// convert center base box to corner based box
|
||||
box.left = Math.round(Math.max(0, box.left - box.width / 2));
|
||||
box.top = Math.round(Math.max(0, box.top - box.height / 2));
|
||||
faces.push({ name, box });
|
||||
faces.push({name, box});
|
||||
}
|
||||
}
|
||||
if (faces.length > 0) {
|
||||
@ -374,11 +379,13 @@ export class MetadataLoader {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
// ignoring errors
|
||||
}
|
||||
|
||||
return resolve(metadata);
|
||||
} catch (err) {
|
||||
return reject({ file: fullPath, error: err });
|
||||
return reject({file: fullPath, error: err});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import { Metadata, Sharp } from 'sharp';
|
||||
import { Logger } from '../../Logger';
|
||||
import { FfmpegCommand, FfprobeData } from 'fluent-ffmpeg';
|
||||
@ -60,7 +61,7 @@ export class VideoRendererFactory {
|
||||
return new Promise((resolve, reject): void => {
|
||||
Logger.silly('[FFmpeg] rendering thumbnail: ' + input.mediaPath);
|
||||
|
||||
ffmpeg(input.mediaPath).ffprobe((err: any, data: FfprobeData): void => {
|
||||
ffmpeg(input.mediaPath).ffprobe((err: Error, data: FfprobeData): void => {
|
||||
if (!!err || data === null) {
|
||||
return reject('[FFmpeg] ' + err.toString());
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { Utils } from '../../../common/Utils';
|
||||
import { MediaDTO } from '../../../common/entities/MediaDTO';
|
||||
import { ParentDirectoryDTO } from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
declare const process: NodeJS.Process;
|
||||
const LOG_TAG = '[Worker]';
|
||||
|
||||
export class Worker {
|
||||
|
@ -2,6 +2,7 @@ import { Express, NextFunction, Request, Response } from 'express';
|
||||
import { logFN, Logger } from '../Logger';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Express {
|
||||
interface Request {
|
||||
_startTime?: number;
|
||||
|
@ -11,16 +11,17 @@ import { UserDTO } from '../../common/entities/UserDTO';
|
||||
import { ServerTimeEntry } from '../middlewares/ServerTimingMWs';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Express {
|
||||
interface Request {
|
||||
locale?: string;
|
||||
localePath?: string;
|
||||
tpl?: any;
|
||||
tpl?: Record<string, any>;
|
||||
timing?: { [key: string]: ServerTimeEntry };
|
||||
}
|
||||
|
||||
interface Response {
|
||||
tpl?: any;
|
||||
tpl?: Record<string, any>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,7 +151,7 @@ export class PublicRouter {
|
||||
);
|
||||
});
|
||||
|
||||
const renderFile = (subDir: string = '') => {
|
||||
const renderFile = (subDir = '') => {
|
||||
return (req: Request, res: Response) => {
|
||||
const file = path.join(
|
||||
ProjectPath.FrontendFolder,
|
||||
|
@ -4,6 +4,7 @@ import { Request } from 'express';
|
||||
import * as cookieParser from 'cookie-parser';
|
||||
import * as _http from 'http';
|
||||
import { Server as HttpServer } from 'http';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import * as locale from 'locale';
|
||||
import { ObjectManagers } from './model/ObjectManagers';
|
||||
@ -23,9 +24,10 @@ import { ConfigClassBuilder } from 'typeconfig/node';
|
||||
import { ConfigClassOptions } from 'typeconfig/src/decorators/class/IConfigClass';
|
||||
import { DatabaseType } from '../common/config/private/PrivateConfig';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const session = require('cookie-session');
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
declare const process: NodeJS.Process;
|
||||
|
||||
const LOG_TAG = '[server]';
|
||||
|
||||
|
@ -118,7 +118,9 @@ export class SearchQueryParser {
|
||||
if (parts && parts.length === 3) {
|
||||
timestamp = Date.UTC(parts[0], parts[1] - 1, parts[2]); // Note: months are 0-based
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
// If it could not parse as ISO string, try our luck with Date.parse
|
||||
// https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results
|
||||
if (timestamp === null) {
|
||||
@ -223,17 +225,14 @@ export class SearchQueryParser {
|
||||
const prefix = str.startsWith(this.keywords.someOf + ':')
|
||||
? this.keywords.someOf + ':'
|
||||
: new RegExp('^\\d*-' + this.keywords.NSomeOf + ':').exec(str)[0];
|
||||
let tmpList: any = this.parse(str.slice(prefix.length + 1, -1), false); // trim brackets
|
||||
let tmpList: SearchQueryDTO | SearchQueryDTO[] = this.parse(str.slice(prefix.length + 1, -1), false); // trim brackets
|
||||
|
||||
const unfoldList = (q: SearchListQuery): SearchQueryDTO[] => {
|
||||
if (q.list) {
|
||||
if (q.type === SearchQueryTypes.UNKNOWN_RELATION) {
|
||||
return [].concat.apply(
|
||||
[],
|
||||
q.list.map((e) => unfoldList(e as any))
|
||||
); // flatten array
|
||||
return q.list.map((e) => unfoldList(e as SearchListQuery)).flat() // flatten array
|
||||
} else {
|
||||
q.list.forEach((e) => unfoldList(e as any));
|
||||
q.list.forEach((e) => unfoldList(e as SearchListQuery));
|
||||
}
|
||||
}
|
||||
return [q];
|
||||
|
@ -174,7 +174,7 @@ export class Utils {
|
||||
public static enumToArray(EnumType: any): { key: number; value: string }[] {
|
||||
const arr: Array<{ key: number; value: string }> = [];
|
||||
for (const enumMember in EnumType) {
|
||||
if (!EnumType.hasOwnProperty(enumMember)) {
|
||||
if (!EnumType.hasOwn(enumMember)) {
|
||||
continue;
|
||||
}
|
||||
const key = parseInt(enumMember, 10);
|
||||
@ -216,7 +216,7 @@ export class Utils {
|
||||
return curr;
|
||||
}
|
||||
|
||||
public static isUInt32(value: number, max: number = 4294967295): boolean {
|
||||
public static isUInt32(value: number, max = 4294967295): boolean {
|
||||
value = parseInt('' + value, 10);
|
||||
return !isNaN(value) && value >= 0 && value <= max;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import { IPrivateConfig, ServerConfig } from './PrivateConfig';
|
||||
import { ClientConfig } from '../public/ClientConfig';
|
||||
import * as crypto from 'crypto';
|
||||
|
@ -19,7 +19,7 @@ declare namespace ServerInject {
|
||||
export const ConfigInject: ClientClass;
|
||||
}
|
||||
|
||||
export let Config: IWebConfigClass & ClientClass =
|
||||
export const Config: IWebConfigClass & ClientClass =
|
||||
WebConfigClassBuilder.attachInterface(new ClientClass());
|
||||
|
||||
if (
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
export enum JobTriggerType {
|
||||
never = 1,
|
||||
scheduled = 2,
|
||||
|
@ -4,7 +4,6 @@ import { DefaultsJobs } from '../../../common/entities/job/JobDTO';
|
||||
|
||||
@Injectable()
|
||||
export class BackendtextService {
|
||||
constructor() {}
|
||||
|
||||
public get(id: backendText): string {
|
||||
switch (id) {
|
||||
|
@ -19,11 +19,15 @@ class MockUserService {
|
||||
}
|
||||
|
||||
class MockNetworkService {
|
||||
addGlobalErrorHandler(fn: (error: ErrorDTO) => boolean): void {}
|
||||
addGlobalErrorHandler(fn: (error: ErrorDTO) => boolean): void {
|
||||
// mock fn
|
||||
}
|
||||
}
|
||||
|
||||
class MockShareService {
|
||||
onNewUser(user: any): void {}
|
||||
onNewUser(user: any): void {
|
||||
// mock fn
|
||||
}
|
||||
}
|
||||
|
||||
describe('AuthenticationService', () => {
|
||||
|
@ -64,7 +64,7 @@ export class NetworkService {
|
||||
return res;
|
||||
};
|
||||
|
||||
const err = (error: any) => {
|
||||
const err = (error: Error) => {
|
||||
this.loadingBarService.useRef().complete();
|
||||
return this.handleError(error);
|
||||
};
|
||||
@ -76,11 +76,11 @@ export class NetworkService {
|
||||
.catch(err);
|
||||
}
|
||||
|
||||
public postJson<T>(url: string, data: any = {}): Promise<T> {
|
||||
public postJson<T>(url: string, data = {}): Promise<T> {
|
||||
return this.callJson('post', url, data);
|
||||
}
|
||||
|
||||
public putJson<T>(url: string, data: any = {}): Promise<T> {
|
||||
public putJson<T>(url: string, data = {}): Promise<T> {
|
||||
return this.callJson('put', url, data);
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ export class NetworkService {
|
||||
private callJson<T>(
|
||||
method: 'get' | 'post' | 'delete' | 'put',
|
||||
url: string,
|
||||
data: any = {}
|
||||
data = {}
|
||||
): Promise<T> {
|
||||
const body = data;
|
||||
|
||||
@ -113,7 +113,7 @@ export class NetworkService {
|
||||
res.headers.get(CustomHeaders.dataVersion)
|
||||
);
|
||||
}
|
||||
if (!!msg.error) {
|
||||
if (msg.error) {
|
||||
if (msg.error.code) {
|
||||
(msg.error as any).title = ErrorCodes[msg.error.code];
|
||||
}
|
||||
@ -122,7 +122,7 @@ export class NetworkService {
|
||||
return msg.result;
|
||||
};
|
||||
|
||||
const err = (error: any) => {
|
||||
const err = (error: Error) => {
|
||||
this.loadingBarService.useRef().complete();
|
||||
return this.handleError(error);
|
||||
};
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
||||
import { NetworkService } from './network.service';
|
||||
import { UserService } from './user.service';
|
||||
import { LoginCredential } from '../../../../common/entities/LoginCredential';
|
||||
import { LoadingBarService } from '@ngx-loading-bar/core';
|
||||
import { ShareService } from '../../ui/gallery/share.service';
|
||||
import { VersionService } from '../version.service';
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import {HttpClientTestingModule} from '@angular/common/http/testing';
|
||||
import {NetworkService} from './network.service';
|
||||
import {UserService} from './user.service';
|
||||
import {LoginCredential} from '../../../../common/entities/LoginCredential';
|
||||
import {LoadingBarService} from '@ngx-loading-bar/core';
|
||||
import {ShareService} from '../../ui/gallery/share.service';
|
||||
import {VersionService} from '../version.service';
|
||||
|
||||
class MockShareService {
|
||||
wait(): Promise<boolean> {
|
||||
@ -26,7 +26,7 @@ describe('UserService', (): void => {
|
||||
UserService,
|
||||
LoadingBarService,
|
||||
NetworkService,
|
||||
{ provide: ShareService, useClass: MockShareService },
|
||||
{provide: ShareService, useClass: MockShareService},
|
||||
],
|
||||
});
|
||||
});
|
||||
@ -43,7 +43,7 @@ describe('UserService', (): void => {
|
||||
expect(networkService.postJson).toHaveBeenCalled();
|
||||
expect((networkService.postJson as any).calls.argsFor(0)).toEqual([
|
||||
'/user/login',
|
||||
{ loginCredential: credential },
|
||||
{loginCredential: credential},
|
||||
]);
|
||||
}
|
||||
));
|
||||
|
@ -4,7 +4,6 @@ export class PageHelper {
|
||||
(document.compatMode || '') === 'CSS1Compat';
|
||||
private static readonly body = document.getElementsByTagName('body')[0];
|
||||
|
||||
constructor() {}
|
||||
|
||||
public static get ScrollY(): number {
|
||||
return this.supportPageOffset
|
||||
|
@ -2,7 +2,6 @@ import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'duration' })
|
||||
export class DurationPipe implements PipeTransform {
|
||||
constructor() {}
|
||||
|
||||
transform(time: number, separator: ':' | 'string' = 'string'): string {
|
||||
const h = Math.floor(time / 1000 / 60 / 60);
|
||||
|
@ -3,7 +3,6 @@ import { SortingMethods } from '../../../common/entities/SortingMethods';
|
||||
|
||||
@Pipe({ name: 'stringifySorting' })
|
||||
export class StringifySortingMethod implements PipeTransform {
|
||||
constructor() {}
|
||||
|
||||
transform(method: SortingMethods): string {
|
||||
switch (method) {
|
||||
|
@ -1,21 +1,14 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
ElementRef,
|
||||
OnInit,
|
||||
QueryList,
|
||||
ViewChildren,
|
||||
} from '@angular/core';
|
||||
import { AuthenticationService } from '../../model/network/authentication.service';
|
||||
import { UserRoles } from '../../../../common/entities/UserDTO';
|
||||
import { NotificationService } from '../../model/notification.service';
|
||||
import { NotificationType } from '../../../../common/entities/NotificationDTO';
|
||||
import { NavigationService } from '../../model/navigation.service';
|
||||
import { ISettingsComponent } from '../settings/_abstract/ISettingsComponent';
|
||||
import { PageHelper } from '../../model/page.helper';
|
||||
import { SettingsService } from '../settings/settings.service';
|
||||
import { CookieNames } from '../../../../common/CookieNames';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import {AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChildren,} from '@angular/core';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {NotificationType} from '../../../../common/entities/NotificationDTO';
|
||||
import {NavigationService} from '../../model/navigation.service';
|
||||
import {ISettingsComponent} from '../settings/_abstract/ISettingsComponent';
|
||||
import {PageHelper} from '../../model/page.helper';
|
||||
import {SettingsService} from '../settings/settings.service';
|
||||
import {CookieNames} from '../../../../common/CookieNames';
|
||||
import {CookieService} from 'ngx-cookie-service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-admin',
|
||||
@ -25,7 +18,7 @@ import { CookieService } from 'ngx-cookie-service';
|
||||
export class AdminComponent implements OnInit, AfterViewInit {
|
||||
simplifiedMode = true;
|
||||
@ViewChildren('setting') settingsComponents: QueryList<ISettingsComponent>;
|
||||
@ViewChildren('setting', { read: ElementRef })
|
||||
@ViewChildren('setting', {read: ElementRef})
|
||||
settingsComponentsElemRef: QueryList<ElementRef>;
|
||||
contents: ISettingsComponent[] = [];
|
||||
|
||||
@ -50,8 +43,7 @@ export class AdminComponent implements OnInit, AfterViewInit {
|
||||
scrollTo(i: number): void {
|
||||
PageHelper.ScrollY =
|
||||
this.settingsComponentsElemRef
|
||||
.toArray()
|
||||
[i].nativeElement.getBoundingClientRect().top + PageHelper.ScrollY;
|
||||
.toArray()[i].nativeElement.getBoundingClientRect().top + PageHelper.ScrollY;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -8,7 +8,6 @@ export class Person implements PersonDTO {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
constructor() {}
|
||||
|
||||
public static getThumbnailUrl(that: PersonDTO): string {
|
||||
return Utils.concatUrls(
|
||||
|
@ -36,7 +36,7 @@ export class Media extends MediaIcon {
|
||||
this.replacementSizeCache = null;
|
||||
|
||||
const size = this.getThumbnailSize();
|
||||
if (!!this.media.missingThumbnails) {
|
||||
if (this.media.missingThumbnails) {
|
||||
for (const thSize of Config.Client.Media.Thumbnail.thumbnailSizes) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
if (
|
||||
|
@ -21,11 +21,9 @@ export class GalleryBlogComponent implements OnChanges {
|
||||
}
|
||||
return this.markdowns[0].length < 203
|
||||
? this.markdowns[0]
|
||||
: this.markdowns[0].substr(0, 200) + '...';
|
||||
: this.markdowns[0].substring(0, 200) + '...';
|
||||
}
|
||||
|
||||
onError($event: string): void {}
|
||||
|
||||
ngOnChanges(): void {
|
||||
this.loadMarkdown().catch(console.error);
|
||||
}
|
||||
|
@ -1,20 +1,13 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
DirectoryDTOUtils,
|
||||
DirectoryPathDTO,
|
||||
ParentDirectoryDTO,
|
||||
} from '../../../../common/entities/DirectoryDTO';
|
||||
import { Utils } from '../../../../common/Utils';
|
||||
import { Config } from '../../../../common/config/public/Config';
|
||||
import { IAutoCompleteItem } from '../../../../common/entities/AutoCompleteItem';
|
||||
import { SearchResultDTO } from '../../../../common/entities/SearchResultDTO';
|
||||
import { MediaDTO } from '../../../../common/entities/MediaDTO';
|
||||
import { SortingMethods } from '../../../../common/entities/SortingMethods';
|
||||
import { VersionService } from '../../model/version.service';
|
||||
import {
|
||||
SearchQueryDTO,
|
||||
SearchQueryTypes,
|
||||
} from '../../../../common/entities/SearchQueryDTO';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {DirectoryDTOUtils, DirectoryPathDTO, ParentDirectoryDTO,} from '../../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {IAutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../../common/entities/SearchResultDTO';
|
||||
import {MediaDTO} from '../../../../common/entities/MediaDTO';
|
||||
import {SortingMethods} from '../../../../common/entities/SortingMethods';
|
||||
import {VersionService} from '../../model/version.service';
|
||||
import {SearchQueryDTO, SearchQueryTypes,} from '../../../../common/entities/SearchQueryDTO';
|
||||
|
||||
interface CacheItem<T> {
|
||||
timestamp: number;
|
||||
@ -94,7 +87,9 @@ export class GalleryCacheService {
|
||||
for (const item of toRemove) {
|
||||
localStorage.removeItem(item);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
}
|
||||
|
||||
public getSorting(dir: DirectoryPathDTO): SortingMethods {
|
||||
@ -248,7 +243,9 @@ export class GalleryCacheService {
|
||||
DirectoryDTOUtils.unpackDirectory(directory);
|
||||
return directory;
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -329,6 +326,8 @@ export class GalleryCacheService {
|
||||
GalleryCacheService.VERSION,
|
||||
this.versionService.version.value
|
||||
);
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
// ignoring errors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ export class FilterService {
|
||||
],
|
||||
});
|
||||
|
||||
constructor() {}
|
||||
|
||||
public applyFilters(
|
||||
directoryContent: Observable<DirectoryContent>
|
||||
|
@ -245,6 +245,7 @@ export class GalleryGridComponent
|
||||
while (
|
||||
this.renderedPhotoIndex - 1 < index + 1 &&
|
||||
this.renderARow() !== null
|
||||
// eslint-disable-next-line no-empty
|
||||
) {}
|
||||
}
|
||||
|
||||
@ -297,7 +298,7 @@ export class GalleryGridComponent
|
||||
* @param offset Add height to the client height (content is not yet added to the dom, but calculate with it)
|
||||
* @returns boolean
|
||||
*/
|
||||
private shouldRenderMore(offset: number = 0): boolean {
|
||||
private shouldRenderMore(offset = 0): boolean {
|
||||
const bottomOffset = this.getMaxRowHeight() * 2;
|
||||
return (
|
||||
Config.Client.Other.enableOnScrollRendering === false ||
|
||||
@ -310,7 +311,7 @@ export class GalleryGridComponent
|
||||
);
|
||||
}
|
||||
|
||||
private renderPhotos(numberOfPhotos: number = 0): void {
|
||||
private renderPhotos(numberOfPhotos = 0): void {
|
||||
if (!this.media) {
|
||||
return;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ export class GallerySearchQueryBuilderComponent
|
||||
text: '',
|
||||
} as TextSearch;
|
||||
@Output() search = new EventEmitter<void>();
|
||||
@Input() placeholder: string = "Search";
|
||||
@Input() placeholder = "Search";
|
||||
public rawSearchText = '';
|
||||
|
||||
constructor(private searchQueryParserService: SearchQueryParserService) {}
|
||||
@ -79,6 +79,7 @@ export class GallerySearchQueryBuilderComponent
|
||||
return { required: true };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public onTouched(): void {}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
@ -100,7 +101,9 @@ export class GallerySearchQueryBuilderComponent
|
||||
this.propagateChange(this.searchQueryDTO);
|
||||
}
|
||||
|
||||
private propagateChange = (_: any): void => {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
private propagateChange = (_: unknown): void => {};
|
||||
|
||||
private propagateTouch = (_: any): void => {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
private propagateTouch = (_: unknown): void => {};
|
||||
}
|
||||
|
@ -69,27 +69,27 @@ export class GallerySearchQueryEntryComponent
|
||||
}
|
||||
|
||||
get AsListQuery(): SearchListQuery {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as SearchListQuery;
|
||||
}
|
||||
|
||||
public get AsRangeQuery(): RangeSearch {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as RangeSearch;
|
||||
}
|
||||
|
||||
get AsOrientationQuery(): OrientationSearch {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as OrientationSearch;
|
||||
}
|
||||
|
||||
get AsDistanceQuery(): DistanceSearch {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as DistanceSearch;
|
||||
}
|
||||
|
||||
get AsSomeOfQuery(): SomeOfSearchQuery {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as SomeOfSearchQuery;
|
||||
}
|
||||
|
||||
get AsTextQuery(): TextSearch {
|
||||
return this.queryEntry as any;
|
||||
return this.queryEntry as TextSearch;
|
||||
}
|
||||
|
||||
validate(control: FormControl): ValidationErrors {
|
||||
@ -140,13 +140,14 @@ export class GallerySearchQueryEntryComponent
|
||||
this.AsListQuery.list.splice(i, 1);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public onTouched(): void {}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
public writeValue(obj: SearchQueryDTO): void {
|
||||
this.queryEntry = obj;
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: any) => void): void {
|
||||
registerOnChange(fn: (_: unknown) => void): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
@ -166,8 +167,10 @@ export class GallerySearchQueryEntryComponent
|
||||
this.onChange();
|
||||
}
|
||||
|
||||
private propagateChange = (_: any): void => {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
private propagateChange = (_: unknown): void => {};
|
||||
|
||||
private propagateTouch = (_: any): void => {};
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
private propagateTouch = (_: unknown): void => {};
|
||||
}
|
||||
|
||||
|
@ -230,13 +230,14 @@ export class GallerySearchFieldBaseComponent
|
||||
return false;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public onTouched(): void {}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
public writeValue(obj: string): void {
|
||||
this.rawSearchText = obj;
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: any) => void): void {
|
||||
registerOnChange(fn: (_: unknown) => void): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
|
@ -1,27 +1,11 @@
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
forwardRef,
|
||||
Input,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { AutoCompleteService } from '../autocomplete.service';
|
||||
import { SearchQueryDTO } from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {
|
||||
ControlValueAccessor,
|
||||
FormControl,
|
||||
NG_VALIDATORS,
|
||||
NG_VALUE_ACCESSOR,
|
||||
ValidationErrors,
|
||||
Validator,
|
||||
} from '@angular/forms';
|
||||
import { SearchQueryParserService } from '../search-query-parser.service';
|
||||
import { TemplateRef } from '../../../../../../../node_modules/@angular/core';
|
||||
import {
|
||||
BsModalRef,
|
||||
BsModalService,
|
||||
} from '../../../../../../../node_modules/ngx-bootstrap/modal';
|
||||
import {Component, EventEmitter, forwardRef, Input, Output,} from '@angular/core';
|
||||
import {Router, RouterLink} from '@angular/router';
|
||||
import {AutoCompleteService} from '../autocomplete.service';
|
||||
import {SearchQueryDTO} from '../../../../../../common/entities/SearchQueryDTO';
|
||||
import {ControlValueAccessor, FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, ValidationErrors, Validator,} from '@angular/forms';
|
||||
import {SearchQueryParserService} from '../search-query-parser.service';
|
||||
import {TemplateRef} from '../../../../../../../node_modules/@angular/core';
|
||||
import {BsModalRef, BsModalService,} from '../../../../../../../node_modules/ngx-bootstrap/modal';
|
||||
|
||||
@Component({
|
||||
selector: 'app-gallery-search-field',
|
||||
@ -43,8 +27,7 @@ import {
|
||||
],
|
||||
})
|
||||
export class GallerySearchFieldComponent
|
||||
implements ControlValueAccessor, Validator
|
||||
{
|
||||
implements ControlValueAccessor, Validator {
|
||||
@Output() search = new EventEmitter<void>();
|
||||
@Input() placeholder: string;
|
||||
public rawSearchText = '';
|
||||
@ -56,7 +39,8 @@ export class GallerySearchFieldComponent
|
||||
private searchQueryParserService: SearchQueryParserService,
|
||||
private modalService: BsModalService,
|
||||
public router: Router
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public async openSearchModal(template: TemplateRef<any>): Promise<void> {
|
||||
this.searchModalRef = this.modalService.show(template, {
|
||||
@ -70,16 +54,18 @@ export class GallerySearchFieldComponent
|
||||
this.searchModalRef = null;
|
||||
}
|
||||
|
||||
public onTouched(): void {}
|
||||
public onTouched(): void {
|
||||
//ignoring
|
||||
}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
public writeValue(obj: SearchQueryDTO): void {
|
||||
this.searchQueryDTO = obj;
|
||||
this.rawSearchText = this.searchQueryParserService.stringify(
|
||||
this.searchQueryDTO
|
||||
);
|
||||
}
|
||||
|
||||
registerOnChange(fn: (_: any) => void): void {
|
||||
registerOnChange(fn: (_: unknown) => void): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
@ -92,7 +78,7 @@ export class GallerySearchFieldComponent
|
||||
}
|
||||
|
||||
validate(control: FormControl): ValidationErrors {
|
||||
return { required: true };
|
||||
return {required: true};
|
||||
}
|
||||
|
||||
onQueryChange(): void {
|
||||
@ -113,8 +99,12 @@ export class GallerySearchFieldComponent
|
||||
}
|
||||
}
|
||||
|
||||
private propagateChange = (_: any): void => {};
|
||||
private propagateChange = (_: SearchQueryDTO): void => {
|
||||
//ignoring
|
||||
};
|
||||
|
||||
private propagateTouch = (_: any): void => {};
|
||||
private propagateTouch = (_: never): void => {
|
||||
//ignoring
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ export class GallerySearchComponent implements OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
public async openSearchModal(template: TemplateRef<any>): Promise<void> {
|
||||
public async openSearchModal(template: TemplateRef<unknown>): Promise<void> {
|
||||
this.searchModalRef = this.modalService.show(template, {
|
||||
class: 'modal-lg',
|
||||
});
|
||||
@ -100,7 +100,7 @@ export class GallerySearchComponent implements OnDestroy {
|
||||
this.searchModalRef = null;
|
||||
}
|
||||
|
||||
public async openSaveSearchModal(template: TemplateRef<any>): Promise<void> {
|
||||
public async openSaveSearchModal(template: TemplateRef<unknown>): Promise<void> {
|
||||
this.saveSearchModalRef = this.modalService.show(template, {
|
||||
class: 'modal-lg',
|
||||
});
|
||||
|
@ -112,7 +112,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||
this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey;
|
||||
}
|
||||
|
||||
async openModal(template: TemplateRef<any>): Promise<void> {
|
||||
async openModal(template: TemplateRef<unknown>): Promise<void> {
|
||||
await this.get();
|
||||
this.input.password = '';
|
||||
if (this.modalRef) {
|
||||
|
@ -121,7 +121,9 @@ export class ThumbnailLoaderService {
|
||||
): ThumbnailTaskEntity {
|
||||
return this.load(
|
||||
Person.getThumbnailUrl(person),
|
||||
(): void => {},
|
||||
(): void => {
|
||||
// no callback
|
||||
},
|
||||
priority,
|
||||
listener
|
||||
);
|
||||
@ -200,7 +202,7 @@ export class ThumbnailLoaderService {
|
||||
export interface ThumbnailLoadingListener {
|
||||
onStartedLoading: () => void;
|
||||
onLoad: () => void;
|
||||
onError: (error: any) => void;
|
||||
onError: (error: Error) => void;
|
||||
}
|
||||
|
||||
export interface ThumbnailTaskEntity {
|
||||
|
@ -196,7 +196,7 @@ export class Thumbnail extends ThumbnailBase {
|
||||
constructor(
|
||||
private media: Media,
|
||||
thumbnailService: ThumbnailLoaderService,
|
||||
autoLoad: boolean = true
|
||||
autoLoad = true
|
||||
) {
|
||||
super(thumbnailService);
|
||||
if (this.media.isThumbnailAvailable()) {
|
||||
|
@ -19,12 +19,12 @@ import { ISettingsComponent } from './ISettingsComponent';
|
||||
import { WebConfig } from '../../../../../common/config/private/WebConfig';
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
interface ConfigState {
|
||||
value: any;
|
||||
original: any;
|
||||
default: any;
|
||||
readonly: any;
|
||||
onChange: any;
|
||||
interface ConfigState<T = unknown> {
|
||||
value: T;
|
||||
original: T;
|
||||
default: T;
|
||||
readonly: boolean;
|
||||
onChange: ()=>unknown;
|
||||
isEnumType: boolean;
|
||||
isConfigType: boolean;
|
||||
}
|
||||
@ -59,7 +59,7 @@ export abstract class SettingsComponentDirective<
|
||||
public inProgress = false;
|
||||
public error: string = null;
|
||||
public changed = false;
|
||||
public states: RecursiveState = {} as any;
|
||||
public states: RecursiveState = {} as RecursiveState;
|
||||
|
||||
private subscription: Subscription = null;
|
||||
private readonly settingsSubscription: Subscription = null;
|
||||
@ -205,11 +205,11 @@ export abstract class SettingsComponentDirective<
|
||||
}
|
||||
|
||||
stateToSettings(): T {
|
||||
const ret: T = {} as any;
|
||||
const ret: T = {} as T;
|
||||
|
||||
const add = (obj: any, to: any): void => {
|
||||
const add = (obj: Record<string, RecursiveState>, to: Record<string, RecursiveState>): void => {
|
||||
for (const key of Object.keys(obj)) {
|
||||
to[key] = {};
|
||||
to[key] = {} as RecursiveState;
|
||||
if (
|
||||
obj[key].isConfigType ||
|
||||
(typeof obj[key] === 'object' &&
|
||||
|
@ -219,11 +219,13 @@ export class SettingsEntryComponent
|
||||
return { required: true };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public onChange(value: any): void {}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
||||
public onTouched(): void {}
|
||||
|
||||
public writeValue(obj: any): void {
|
||||
public writeValue(obj: IState): void {
|
||||
this.state = obj;
|
||||
this.ngOnChanges();
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ export class JobsSettingsComponent
|
||||
private getNextRunningDate(
|
||||
sch: JobScheduleDTO,
|
||||
list: JobScheduleDTO[],
|
||||
depth: number = 0
|
||||
depth = 0
|
||||
): number {
|
||||
if (depth > list.length) {
|
||||
return 0;
|
||||
|
@ -120,7 +120,7 @@ export class JobProgressComponent implements OnDestroy, OnChanges {
|
||||
}
|
||||
}
|
||||
|
||||
openModal(template: TemplateRef<any>): void {
|
||||
openModal(template: TemplateRef<unknown>): void {
|
||||
this.modalRef = this.modalService.show(template, { class: 'modal-lg' });
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ export class PreviewSettingsComponent
|
||||
);
|
||||
}
|
||||
|
||||
get Config(): any {
|
||||
get Config(): unknown {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ export class ScheduledJobsService {
|
||||
public async start(
|
||||
jobName: string,
|
||||
config?: any,
|
||||
soloStart: boolean = false,
|
||||
soloStart = false,
|
||||
allowParallelRun = false
|
||||
): Promise<void> {
|
||||
try {
|
||||
@ -62,9 +62,7 @@ export class ScheduledJobsService {
|
||||
);
|
||||
// placeholder to force showing running job
|
||||
this.addDummyProgress(jobName, config);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
} finally {
|
||||
delete this.jobStartingStopping[jobName];
|
||||
this.forceUpdate();
|
||||
}
|
||||
@ -88,7 +86,7 @@ export class ScheduledJobsService {
|
||||
);
|
||||
for (const prg of Object.keys(prevPrg)) {
|
||||
if (
|
||||
!this.progress.value.hasOwnProperty(prg) ||
|
||||
!this.progress.value.hasOwn(prg) ||
|
||||
// state changed from running to finished
|
||||
((prevPrg[prg].state === JobProgressStates.running ||
|
||||
prevPrg[prg].state === JobProgressStates.cancelling) &&
|
||||
|
@ -1,20 +1,14 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { SettingsComponentDirective } from '../_abstract/abstract.settings.component';
|
||||
import { AuthenticationService } from '../../../model/network/authentication.service';
|
||||
import { NavigationService } from '../../../model/navigation.service';
|
||||
import { NotificationService } from '../../../model/notification.service';
|
||||
import { ThumbnailSettingsService } from './thumbnail.settings.service';
|
||||
import {
|
||||
DefaultsJobs,
|
||||
JobDTOUtils,
|
||||
} from '../../../../../common/entities/job/JobDTO';
|
||||
import { ScheduledJobsService } from '../scheduled-jobs.service';
|
||||
import {
|
||||
JobProgressDTO,
|
||||
JobProgressStates,
|
||||
} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import { ServerThumbnailConfig } from '../../../../../common/config/private/PrivateConfig';
|
||||
import { ClientThumbnailConfig } from '../../../../../common/config/public/ClientConfig';
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {SettingsComponentDirective} from '../_abstract/abstract.settings.component';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ThumbnailSettingsService} from './thumbnail.settings.service';
|
||||
import {DefaultsJobs, JobDTOUtils,} from '../../../../../common/entities/job/JobDTO';
|
||||
import {ScheduledJobsService} from '../scheduled-jobs.service';
|
||||
import {JobProgressDTO, JobProgressStates,} from '../../../../../common/entities/job/JobProgressDTO';
|
||||
import {ServerThumbnailConfig} from '../../../../../common/config/private/PrivateConfig';
|
||||
import {ClientThumbnailConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-thumbnail',
|
||||
@ -30,8 +24,7 @@ export class ThumbnailSettingsComponent
|
||||
server: ServerThumbnailConfig;
|
||||
client: ClientThumbnailConfig;
|
||||
}>
|
||||
implements OnInit
|
||||
{
|
||||
implements OnInit {
|
||||
JobProgressStates = JobProgressStates;
|
||||
readonly jobName = DefaultsJobs[DefaultsJobs['Thumbnail Generation']];
|
||||
|
||||
@ -56,14 +49,14 @@ export class ThumbnailSettingsComponent
|
||||
);
|
||||
}
|
||||
|
||||
get Config(): any {
|
||||
return { sizes: this.states.client.thumbnailSizes.original[0] };
|
||||
get Config(): { sizes: number } {
|
||||
return {sizes: this.states.client.thumbnailSizes.original[0]};
|
||||
}
|
||||
|
||||
get Progress(): JobProgressDTO {
|
||||
return this.jobsService.progress.value[
|
||||
JobDTOUtils.getHashName(this.jobName, this.Config)
|
||||
];
|
||||
];
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { AuthenticationService } from '../../../model/network/authentication.service';
|
||||
import { UserDTO, UserRoles } from '../../../../../common/entities/UserDTO';
|
||||
import { Utils } from '../../../../../common/Utils';
|
||||
import { UserManagerSettingsService } from './usermanager.settings.service';
|
||||
import { ModalDirective } from 'ngx-bootstrap/modal';
|
||||
import { NavigationService } from '../../../model/navigation.service';
|
||||
import { NotificationService } from '../../../model/notification.service';
|
||||
import { ErrorCodes, ErrorDTO } from '../../../../../common/entities/Error';
|
||||
import { ISettingsComponent } from '../_abstract/ISettingsComponent';
|
||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {AuthenticationService} from '../../../model/network/authentication.service';
|
||||
import {UserDTO, UserRoles} from '../../../../../common/entities/UserDTO';
|
||||
import {Utils} from '../../../../../common/Utils';
|
||||
import {UserManagerSettingsService} from './usermanager.settings.service';
|
||||
import {ModalDirective} from 'ngx-bootstrap/modal';
|
||||
import {NavigationService} from '../../../model/navigation.service';
|
||||
import {NotificationService} from '../../../model/notification.service';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../../../common/entities/Error';
|
||||
import {ISettingsComponent} from '../_abstract/ISettingsComponent';
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings-usermanager',
|
||||
@ -19,9 +19,9 @@ import { ISettingsComponent } from '../_abstract/ISettingsComponent';
|
||||
providers: [UserManagerSettingsService],
|
||||
})
|
||||
export class UserMangerSettingsComponent implements OnInit, ISettingsComponent {
|
||||
@ViewChild('userModal', { static: false }) public childModal: ModalDirective;
|
||||
@ViewChild('userModal', {static: false}) public childModal: ModalDirective;
|
||||
public newUser = {} as UserDTO;
|
||||
public userRoles: any[] = [];
|
||||
public userRoles: { key: number; value: string }[] = [];
|
||||
public users: UserDTO[] = [];
|
||||
public enabled = true;
|
||||
public error: string = null;
|
||||
@ -110,7 +110,7 @@ export class UserMangerSettingsComponent implements OnInit, ISettingsComponent {
|
||||
}
|
||||
|
||||
initNewUser(): void {
|
||||
this.newUser = { role: UserRoles.User } as UserDTO;
|
||||
this.newUser = {role: UserRoles.User} as UserDTO;
|
||||
this.childModal.show();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user