1
0
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:
Patrik J. Braun 2022-04-25 18:09:06 +02:00
parent 8571c95b45
commit b1c9827729
80 changed files with 445 additions and 421 deletions

View File

@ -27,7 +27,8 @@
},
{
"files": [
"*.component.html"
"*.component.html",
"index.html"
],
"parser": "@angular-eslint/template-parser",
"parserOptions": {

View File

@ -51,7 +51,7 @@ jobs:
npm ci
npm run build
- name: tslint
- name: lint
run: |
npm run lint
- name: test

View File

@ -15,7 +15,7 @@ class ProjectPathClass {
this.reset();
}
normalizeRelative(pathStr: string): any {
normalizeRelative(pathStr: string): string {
return path.join(pathStr, path.sep);
}

View File

@ -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();

View File

@ -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']

View File

@ -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) {

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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();
}

View File

@ -11,7 +11,7 @@ export class VersionMWs {
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
): Promise<void> {
try {
res.header(
CustomHeaders.dataVersion,

View File

@ -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(

View File

@ -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'));
}

View File

@ -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;
};

View File

@ -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,

View File

@ -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];
}
}
}

View File

@ -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();
};

View File

@ -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));
}

View File

@ -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'

View File

@ -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;
}
}

View File

@ -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(

View File

@ -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,

View File

@ -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';

View File

@ -12,6 +12,7 @@ export class PasswordHelper {
): boolean {
try {
return bcrypt.compareSync(password, encryptedPassword);
// eslint-disable-next-line no-empty
} catch (e) {}
return false;
}

View File

@ -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>;

View File

@ -13,5 +13,4 @@ export interface IUserManager extends IObjectManager {
changeRole(id: number, newRole: UserRoles): Promise<UserDTO>;
changePassword(request: any): Promise<void>;
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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>))

View File

@ -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
}
}

View File

@ -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();
}

View File

@ -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 = {

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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});
}
});
});

View File

@ -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());
}

View File

@ -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 {

View File

@ -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;

View File

@ -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,

View File

@ -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]';

View File

@ -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];

View File

@ -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;
}

View File

@ -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';

View File

@ -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 (

View File

@ -1,3 +1,4 @@
/* eslint-disable no-case-declarations */
export enum JobTriggerType {
never = 1,
scheduled = 2,

View File

@ -4,7 +4,6 @@ import { DefaultsJobs } from '../../../common/entities/job/JobDTO';
@Injectable()
export class BackendtextService {
constructor() {}
public get(id: backendText): string {
switch (id) {

View File

@ -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', () => {

View File

@ -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);
};

View File

@ -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},
]);
}
));

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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 {

View File

@ -8,7 +8,6 @@ export class Person implements PersonDTO {
id: number;
name: string;
constructor() {}
public static getThumbnailUrl(that: PersonDTO): string {
return Utils.concatUrls(

View File

@ -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 (

View File

@ -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);
}

View File

@ -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
}
}
}

View File

@ -120,7 +120,6 @@ export class FilterService {
],
});
constructor() {}
public applyFilters(
directoryContent: Observable<DirectoryContent>

View File

@ -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;
}

View File

@ -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 => {};
}

View File

@ -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 => {};
}

View File

@ -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;
}

View File

@ -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
};
}

View File

@ -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',
});

View File

@ -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) {

View File

@ -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 {

View File

@ -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()) {

View File

@ -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' &&

View File

@ -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();
}

View File

@ -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;

View File

@ -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' });
}

View File

@ -50,7 +50,7 @@ export class PreviewSettingsComponent
);
}
get Config(): any {
get Config(): unknown {
return {};
}

View File

@ -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) &&

View File

@ -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 {

View File

@ -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();
}