mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-11-24 08:42:24 +02:00
Project cleanup and version bumps
This commit is contained in:
parent
2f0d2a5e59
commit
5f0f09d420
@ -183,9 +183,7 @@
|
||||
<li>prioritizes thumbnail generation (generating thumbnail first for the visible photos)</li>
|
||||
<li>saving generated thumbnails to TEMP folder for reuse</li>
|
||||
<li>supporting several core CPU</li>
|
||||
<li>supporting hardware acceleration (<a href="https://github.com/lovell/sharp">sharp</a> and <a
|
||||
href="https://github.com/aheckmann/gm">gm</a> as optional and JS-based <a
|
||||
href="https://github.com/oliver-moran/jimp">Jimp</a> as fallback)
|
||||
<li>supporting hardware acceleration (<a href="https://github.com/lovell/sharp">sharp</a>)
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -62,7 +62,7 @@ const createDynamicTranslationFile = async (language: string) => {
|
||||
translationXml.xliff.file[0].body[0]['trans-unit'] = filtered;
|
||||
|
||||
// save
|
||||
const builder = new xml2js.Builder({trim: true, normalize: true});
|
||||
const builder = new xml2js.Builder();
|
||||
const xml = builder.buildObject(translationXml);
|
||||
await fsp.writeFile(path.join(folder, `ts-only-msg.${language}.xlf`), xml);
|
||||
|
||||
|
2872
package-lock.json
generated
2872
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
53
package.json
53
package.json
@ -32,16 +32,16 @@
|
||||
"dependencies": {
|
||||
"body-parser": "1.19.0",
|
||||
"cookie-parser": "1.4.5",
|
||||
"cookie-session": "2.0.0-beta.3",
|
||||
"cookie-session": "2.0.0-rc.1",
|
||||
"csurf": "1.11.0",
|
||||
"ejs": "3.1.5",
|
||||
"bcrypt": "5.0.0",
|
||||
"sharp": "0.23.4",
|
||||
"exifreader": "3.12.2",
|
||||
"exifreader": "3.13.0",
|
||||
"express": "4.17.1",
|
||||
"express-unless": "0.5.0",
|
||||
"fluent-ffmpeg": "2.1.2",
|
||||
"image-size": "0.9.1",
|
||||
"image-size": "0.9.3",
|
||||
"jimp": "0.16.1",
|
||||
"locale": "0.1.0",
|
||||
"reflect-metadata": "0.1.13",
|
||||
@ -49,7 +49,7 @@
|
||||
"ts-exif-parser": "0.2.1",
|
||||
"ts-node-iptc": "1.0.11",
|
||||
"typeconfig": "2.0.14",
|
||||
"typeorm": "0.2.21",
|
||||
"typeorm": "0.2.29",
|
||||
"winston": "2.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -70,32 +70,31 @@
|
||||
"@ngx-translate/i18n-polyfill": "1.0.0",
|
||||
"@types/bcrypt": "3.0.0",
|
||||
"@types/bcryptjs": "2.4.2",
|
||||
"@types/chai": "4.2.6",
|
||||
"@types/chai": "4.2.14",
|
||||
"@types/cookie-parser": "1.4.2",
|
||||
"@types/cookie-session": "2.0.37",
|
||||
"@types/csurf": "1.9.36",
|
||||
"@types/ejs": "3.0.0",
|
||||
"@types/express": "4.17.2",
|
||||
"@types/express-jwt": "0.0.42",
|
||||
"@types/fluent-ffmpeg": "2.1.11",
|
||||
"@types/gulp": "4.0.6",
|
||||
"@types/cookie-session": "2.0.42",
|
||||
"@types/csurf": "1.11.0",
|
||||
"@types/ejs": "3.0.5",
|
||||
"@types/express": "4.17.9",
|
||||
"@types/express-jwt": "6.0.0",
|
||||
"@types/fluent-ffmpeg": "2.1.16",
|
||||
"@types/gulp": "4.0.7",
|
||||
"@types/gulp-zip": "4.0.1",
|
||||
"@types/image-size": "0.8.0",
|
||||
"@types/jasmine": "3.5.0",
|
||||
"@types/jsonwebtoken": "8.3.5",
|
||||
"@types/node": "12.12.14",
|
||||
"@types/rimraf": "2.0.3",
|
||||
"@types/sharp": "0.23.1",
|
||||
"@types/jasmine": "3.6.2",
|
||||
"@types/jsonwebtoken": "8.5.0",
|
||||
"@types/node": "14.14.19",
|
||||
"@types/sharp": "0.26.1",
|
||||
"@types/winston": "2.4.4",
|
||||
"@types/xml2js": "0.4.5",
|
||||
"@types/xml2js": "0.4.7",
|
||||
"@yaga/leaflet-ng2": "1.0.0",
|
||||
"bootstrap": "4.4.1",
|
||||
"bootstrap": "4.5.3",
|
||||
"chai": "4.2.0",
|
||||
"chai-http": "4.3.0",
|
||||
"codelyzer": "5.2.0",
|
||||
"core-js": "3.4.7",
|
||||
"codelyzer": "6.0.1",
|
||||
"core-js": "3.8.2",
|
||||
"coveralls": "3.1.0",
|
||||
"ejs-loader": "0.3.5",
|
||||
"ejs-loader": "0.5.0",
|
||||
"gulp": "4.0.2",
|
||||
"gulp-json-editor": "2.5.4",
|
||||
"gulp-typescript": "5.0.1",
|
||||
@ -103,9 +102,9 @@
|
||||
"hammerjs": "2.0.8",
|
||||
"intl": "1.2.5",
|
||||
"jasmine-core": "3.6.0",
|
||||
"jasmine-spec-reporter": "5.0.2",
|
||||
"jasmine-spec-reporter": "6.0.0",
|
||||
"jw-bootstrap-switch-ng2": "2.0.5",
|
||||
"karma": "4.4.1",
|
||||
"karma": "5.2.3",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-cli": "2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||
@ -113,7 +112,7 @@
|
||||
"karma-jasmine-html-reporter": "1.5.4",
|
||||
"karma-remap-istanbul": "0.6.0",
|
||||
"karma-systemjs": "0.16.0",
|
||||
"mocha": "8.1.3",
|
||||
"mocha": "8.2.1",
|
||||
"ng2-cookies": "1.0.12",
|
||||
"ng2-slim-loading-bar": "4.0.0",
|
||||
"ngx-bootstrap": "5.2.0",
|
||||
@ -127,12 +126,12 @@
|
||||
"rxjs-compat": "6.5.3",
|
||||
"terser": "4.4.2",
|
||||
"ts-helpers": "1.1.2",
|
||||
"ts-node": "9.0.0",
|
||||
"ts-node": "9.1.1",
|
||||
"tslint": "6.1.3",
|
||||
"typescript": "3.5.3",
|
||||
"xlf-google-translate": "1.0.0-beta.19",
|
||||
"xml2js": "0.4.23",
|
||||
"zone.js": "0.10.2"
|
||||
"zone.js": "0.11.3"
|
||||
},
|
||||
"//": [
|
||||
"TODO: remove terser version lock once webpack is fixed",
|
||||
|
@ -36,8 +36,8 @@ export class GalleryMWs {
|
||||
try {
|
||||
const directory = await ObjectManagers.getInstance()
|
||||
.GalleryManager.listDirectory(directoryName,
|
||||
parseInt(req.query[QueryParams.gallery.knownLastModified], 10),
|
||||
parseInt(req.query[QueryParams.gallery.knownLastScanned], 10));
|
||||
parseInt(<string>req.query[QueryParams.gallery.knownLastModified], 10),
|
||||
parseInt(<string>req.query[QueryParams.gallery.knownLastScanned], 10));
|
||||
|
||||
if (directory == null) {
|
||||
req.resultPipe = new ContentWrapper(null, null, true);
|
||||
@ -121,7 +121,7 @@ export class GalleryMWs {
|
||||
try {
|
||||
const query: RandomQuery = {};
|
||||
if (req.query.directory) {
|
||||
query.directory = DiskMangerWorker.normalizeDirPath(req.query.directory);
|
||||
query.directory = DiskMangerWorker.normalizeDirPath(<string>req.query.directory);
|
||||
}
|
||||
if (req.query.recursive === 'true') {
|
||||
query.recursive = true;
|
||||
@ -136,10 +136,10 @@ export class GalleryMWs {
|
||||
query.minResolution = parseFloat(req.query.minResolution.toString());
|
||||
}
|
||||
if (req.query.fromDate) {
|
||||
query.fromDate = new Date(req.query.fromDate);
|
||||
query.fromDate = new Date(<string>req.query.fromDate);
|
||||
}
|
||||
if (req.query.toDate) {
|
||||
query.toDate = new Date(req.query.toDate);
|
||||
query.toDate = new Date(<string>req.query.toDate);
|
||||
}
|
||||
if (query.minResolution && query.maxResolution && query.maxResolution < query.minResolution) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'Input error: min resolution is greater than the max resolution'));
|
||||
@ -212,7 +212,7 @@ export class GalleryMWs {
|
||||
|
||||
let type: SearchTypes;
|
||||
if (req.query[QueryParams.gallery.search.type]) {
|
||||
type = parseInt(req.query[QueryParams.gallery.search.type], 10);
|
||||
type = parseInt(<string>req.query[QueryParams.gallery.search.type], 10);
|
||||
}
|
||||
try {
|
||||
const result = await ObjectManagers.getInstance().SearchManager.search(req.params.text, type);
|
||||
|
@ -307,20 +307,16 @@ export class SettingsMWs {
|
||||
|
||||
try {
|
||||
const settings: {
|
||||
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||
server: ServerConfig.PhotoConfig,
|
||||
client: ClientConfig.PhotoConfig
|
||||
} = req.body.settings;
|
||||
|
||||
await ConfigDiagnostics.testThumbnailLib(settings.photoProcessingLibrary);
|
||||
await ConfigDiagnostics.testServerPhotoConfig(settings.server);
|
||||
await ConfigDiagnostics.testClientPhotoConfig(settings.client);
|
||||
Config.Server.Media.photoProcessingLibrary = settings.photoProcessingLibrary;
|
||||
Config.Server.Media.Photo = settings.server;
|
||||
Config.Client.Media.Photo = settings.client;
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = await Config.original();
|
||||
original.Server.Media.photoProcessingLibrary = settings.photoProcessingLibrary;
|
||||
original.Server.Media.Photo = settings.server;
|
||||
original.Client.Media.Photo = settings.client;
|
||||
original.save();
|
||||
|
@ -100,7 +100,7 @@ export class AuthenticationMWs {
|
||||
|
||||
try {
|
||||
const password = (req.body ? req.body.password : null) || null;
|
||||
const sharingKey: string = req.query[QueryParams.gallery.sharingKey_query] || req.params[QueryParams.gallery.sharingKey_params];
|
||||
const sharingKey: string = <string>req.query[QueryParams.gallery.sharingKey_query] || <string>req.params[QueryParams.gallery.sharingKey_params];
|
||||
const sharing = await ObjectManagers.getInstance().SharingManager.findOne({
|
||||
sharingKey: sharingKey
|
||||
});
|
||||
@ -181,7 +181,7 @@ export class AuthenticationMWs {
|
||||
private static async getSharingUser(req: Request) {
|
||||
if (Config.Client.Sharing.enabled === true &&
|
||||
(!!req.query[QueryParams.gallery.sharingKey_query] || !!req.params[QueryParams.gallery.sharingKey_params])) {
|
||||
const sharingKey: string = req.query[QueryParams.gallery.sharingKey_query] || req.params[QueryParams.gallery.sharingKey_params];
|
||||
const sharingKey: string = <string>req.query[QueryParams.gallery.sharingKey_query] || <string>req.params[QueryParams.gallery.sharingKey_params];
|
||||
const sharing = await ObjectManagers.getInstance().SharingManager.findOne({
|
||||
sharingKey: sharingKey
|
||||
});
|
||||
|
@ -1,9 +1,4 @@
|
||||
let bcrypt: any;
|
||||
try {
|
||||
bcrypt = require('bcrypt');
|
||||
} catch (err) {
|
||||
bcrypt = require('bcryptjs');
|
||||
}
|
||||
import * as bcrypt from 'bcrypt';
|
||||
|
||||
export class PasswordHelper {
|
||||
public static cryptPassword(password: string): string {
|
||||
|
@ -13,7 +13,7 @@ const LOG_TAG = '[ConfigDiagnostics]';
|
||||
|
||||
export class ConfigDiagnostics {
|
||||
|
||||
static checkReadWritePermission(path: string) {
|
||||
static checkReadWritePermission(path: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
// tslint:disable-next-line:no-bitwise
|
||||
fs.access(path, fs.constants.R_OK | fs.constants.W_OK, (err) => {
|
||||
@ -48,7 +48,7 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
|
||||
|
||||
static testClientVideoConfig(videoConfig: ClientConfig.VideoConfig) {
|
||||
static testClientVideoConfig(videoConfig: ClientConfig.VideoConfig): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
if (videoConfig.enabled === true) {
|
||||
@ -86,19 +86,12 @@ export class ConfigDiagnostics {
|
||||
sharp();
|
||||
}
|
||||
|
||||
static async testThumbnailLib(processingLibrary: ServerConfig.PhotoProcessingLib) {
|
||||
switch (processingLibrary) {
|
||||
case ServerConfig.PhotoProcessingLib.sharp:
|
||||
await this.testSharp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static async testTempFolder(folder: string) {
|
||||
await this.checkReadWritePermission(folder);
|
||||
}
|
||||
|
||||
static testImageFolder(folder: string) {
|
||||
static testImageFolder(folder: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!fs.existsSync(folder)) {
|
||||
reject('Images folder not exists: \'' + folder + '\'');
|
||||
@ -220,22 +213,19 @@ export class ConfigDiagnostics {
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.Server.Media.photoProcessingLibrary !== ServerConfig.PhotoProcessingLib.Jimp) {
|
||||
try {
|
||||
await ConfigDiagnostics.testThumbnailLib(Config.Server.Media.photoProcessingLibrary);
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
NotificationManager.warning('Thumbnail hardware acceleration is not possible.' +
|
||||
' \'' + ServerConfig.PhotoProcessingLib[Config.Server.Media.photoProcessingLibrary] + '\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation', err.toString());
|
||||
Logger.warn(LOG_TAG, '[Thumbnail hardware acceleration] module error: ', err.toString());
|
||||
Logger.warn(LOG_TAG, 'Thumbnail hardware acceleration is not possible.' +
|
||||
' \'' + ServerConfig.PhotoProcessingLib[Config.Server.Media.photoProcessingLibrary] + '\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation');
|
||||
Config.Server.Media.photoProcessingLibrary = ServerConfig.PhotoProcessingLib.Jimp;
|
||||
}
|
||||
try {
|
||||
await ConfigDiagnostics.testSharp();
|
||||
} catch (ex) {
|
||||
const err: Error = ex;
|
||||
|
||||
Logger.warn(LOG_TAG, '[Thumbnail hardware acceleration] module error: ', err.toString());
|
||||
Logger.warn(LOG_TAG, 'Thumbnail hardware acceleration is not possible.' +
|
||||
' \'sharp\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testTempFolder(Config.Server.Media.tempFolder);
|
||||
} catch (ex) {
|
||||
|
@ -34,13 +34,9 @@ export class PhotoProcessing {
|
||||
Config.Client.Media.Thumbnail.concurrentThumbnailGenerations = 1;
|
||||
}
|
||||
|
||||
if (Config.Server.Threading.enabled === true &&
|
||||
Config.Server.Media.photoProcessingLibrary === ServerConfig.PhotoProcessingLib.Jimp) {
|
||||
this.taskQue = new ThumbnailTH(Config.Client.Media.Thumbnail.concurrentThumbnailGenerations);
|
||||
} else {
|
||||
this.taskQue = new TaskExecuter(Config.Client.Media.Thumbnail.concurrentThumbnailGenerations,
|
||||
(input => PhotoWorker.render(input, Config.Server.Media.photoProcessingLibrary)));
|
||||
}
|
||||
|
||||
this.taskQue = new TaskExecuter(Config.Client.Media.Thumbnail.concurrentThumbnailGenerations,
|
||||
(input => PhotoWorker.render(input)));
|
||||
|
||||
this.initDone = true;
|
||||
}
|
||||
|
@ -2,17 +2,15 @@ import {Metadata, Sharp} from 'sharp';
|
||||
import {Logger} from '../../Logger';
|
||||
import {FfmpegCommand, FfprobeData} from 'fluent-ffmpeg';
|
||||
import {FFmpegFactory} from '../FFmpegFactory';
|
||||
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||
|
||||
export class PhotoWorker {
|
||||
|
||||
private static imageRenderer: (input: RendererInput) => Promise<void> = null;
|
||||
private static videoRenderer: (input: RendererInput) => Promise<void> = null;
|
||||
private static rendererType: ServerConfig.PhotoProcessingLib = null;
|
||||
|
||||
public static render(input: RendererInput, renderer: ServerConfig.PhotoProcessingLib): Promise<void> {
|
||||
public static render(input: RendererInput): Promise<void> {
|
||||
if (input.type === ThumbnailSourceType.Photo) {
|
||||
return this.renderFromImage(input, renderer);
|
||||
return this.renderFromImage(input);
|
||||
}
|
||||
if (input.type === ThumbnailSourceType.Video) {
|
||||
return this.renderFromVideo(input);
|
||||
@ -20,10 +18,9 @@ export class PhotoWorker {
|
||||
throw new Error('Unsupported media type to render thumbnail:' + input.type);
|
||||
}
|
||||
|
||||
public static renderFromImage(input: RendererInput, renderer: ServerConfig.PhotoProcessingLib): Promise<void> {
|
||||
if (PhotoWorker.rendererType !== renderer) {
|
||||
PhotoWorker.imageRenderer = ImageRendererFactory.build(renderer);
|
||||
PhotoWorker.rendererType = renderer;
|
||||
public static renderFromImage(input: RendererInput): Promise<void> {
|
||||
if (PhotoWorker.imageRenderer === null) {
|
||||
PhotoWorker.imageRenderer = ImageRendererFactory.build();
|
||||
}
|
||||
return PhotoWorker.imageRenderer(input);
|
||||
}
|
||||
@ -118,68 +115,10 @@ export class VideoRendererFactory {
|
||||
|
||||
export class ImageRendererFactory {
|
||||
|
||||
public static build(renderer: ServerConfig.PhotoProcessingLib): (input: RendererInput) => Promise<void> {
|
||||
switch (renderer) {
|
||||
case ServerConfig.PhotoProcessingLib.Jimp:
|
||||
return ImageRendererFactory.Jimp();
|
||||
case ServerConfig.PhotoProcessingLib.sharp:
|
||||
return ImageRendererFactory.Sharp();
|
||||
}
|
||||
throw new Error('unknown renderer');
|
||||
public static build(): (input: RendererInput) => Promise<void> {
|
||||
return ImageRendererFactory.Sharp();
|
||||
}
|
||||
|
||||
public static Jimp() {
|
||||
const Jimp = require('jimp');
|
||||
return async (input: RendererInput): Promise<void> => {
|
||||
// generate thumbnail
|
||||
Logger.silly('[JimpThRenderer] rendering thumbnail:' + input.mediaPath);
|
||||
const image = await Jimp.read(input.mediaPath);
|
||||
/**
|
||||
* newWidth * newHeight = size*size
|
||||
* newHeight/newWidth = height/width
|
||||
*
|
||||
* newHeight = (height/width)*newWidth
|
||||
* newWidth * newWidth = (size*size) / (height/width)
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
const ratio = image.bitmap.height / image.bitmap.width;
|
||||
const algo = input.qualityPriority === true ? Jimp.RESIZE_BEZIER : Jimp.RESIZE_NEAREST_NEIGHBOR;
|
||||
|
||||
if (input.cut) {
|
||||
image.crop(
|
||||
input.cut.left,
|
||||
input.cut.top,
|
||||
input.cut.width,
|
||||
input.cut.height
|
||||
);
|
||||
}
|
||||
if (input.makeSquare === false) {
|
||||
if (image.bitmap.width < image.bitmap.height) {
|
||||
image.resize(Math.min(input.size, image.bitmap.width), Jimp.AUTO, algo);
|
||||
} else {
|
||||
image.resize(Jimp.AUTO, Math.min(image.size, image.bitmap.height), algo);
|
||||
}
|
||||
|
||||
} else {
|
||||
image.resize(input.size / Math.min(ratio, 1), Jimp.AUTO, algo);
|
||||
image.crop(0, 0, input.size, input.size);
|
||||
}
|
||||
image.quality(60); // set JPEG quality
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
image.write(input.outPath, (err: Error | null) => { // save
|
||||
if (err) {
|
||||
return reject('[JimpThRenderer] ' + err.toString());
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static Sharp() {
|
||||
const sharp = require('sharp');
|
||||
sharp.cache(false);
|
||||
|
@ -103,7 +103,6 @@ export class ThumbnailTH extends ThreadPool<void> implements ITaskExecuter<Rende
|
||||
return super.executeTask(<ThumbnailTask>{
|
||||
type: WorkerTaskTypes.thumbnail,
|
||||
input: input,
|
||||
renderer: Config.Server.Media.photoProcessingLibrary
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ export class Worker {
|
||||
}
|
||||
break;
|
||||
case WorkerTaskTypes.thumbnail:
|
||||
result = await PhotoWorker.render((<ThumbnailTask>task).input, (<ThumbnailTask>task).renderer);
|
||||
result = await PhotoWorker.render((<ThumbnailTask>task).input);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown worker task type');
|
||||
@ -54,7 +54,6 @@ export interface DiskManagerTask extends WorkerTask {
|
||||
|
||||
export interface ThumbnailTask extends WorkerTask {
|
||||
input: RendererInput;
|
||||
renderer: ServerConfig.PhotoProcessingLib;
|
||||
}
|
||||
|
||||
export module WorkerTask {
|
||||
|
@ -19,10 +19,6 @@ export module ServerConfig {
|
||||
none = 1, error = 2, all = 3
|
||||
}
|
||||
|
||||
export enum PhotoProcessingLib {
|
||||
sharp = 3,
|
||||
Jimp = 1
|
||||
}
|
||||
|
||||
export enum ReIndexingSensitivity {
|
||||
low = 1, medium = 2, high = 3
|
||||
@ -308,8 +304,6 @@ export module ServerConfig {
|
||||
folder: string = 'demo/images';
|
||||
@ConfigProperty({description: 'Thumbnails, coverted photos, videos will be stored here (write permission required)'})
|
||||
tempFolder: string = 'demo/tmp';
|
||||
@ConfigProperty({type: ServerConfig.PhotoProcessingLib})
|
||||
photoProcessingLibrary: PhotoProcessingLib = ServerConfig.PhotoProcessingLib.sharp;
|
||||
@ConfigProperty()
|
||||
Video: VideoConfig = new VideoConfig();
|
||||
@ConfigProperty()
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
<app-settings-entry
|
||||
name="Threading"
|
||||
description="Runs directory scanning and thumbnail generation (only for Jimp) in a different thread."
|
||||
description="Runs directory scanning in a different thread."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.Server.enabled">
|
||||
</app-settings-entry>
|
||||
|
@ -4,29 +4,7 @@
|
||||
{{Name}}</h5>
|
||||
<div class="card-body">
|
||||
<div [hidden]="!error" class="alert alert-danger" role="alert"><strong>Error: </strong>{{error}}</div>
|
||||
<div [hidden]="states.photoProcessingLibrary.value!=PhotoProcessingLib.Jimp"
|
||||
class="alert alert-warning"
|
||||
role="alert" i18n>It is highly recommended to use hardware accelerated (sharp or gm) lib for thumbnail
|
||||
generation
|
||||
</div>
|
||||
|
||||
<div [hidden]="simplifiedMode">
|
||||
|
||||
<app-settings-entry
|
||||
name="Thumbnail generation library"
|
||||
i18n-name
|
||||
[ngModel]="states.photoProcessingLibrary"
|
||||
[optionMap]="libTypesMap"
|
||||
[simplifiedMode]="simplifiedMode"
|
||||
required="true">
|
||||
<small *ngIf="states.photoProcessingLibrary.value==PhotoProcessingLib.sharp"
|
||||
class="form-text text-muted" i18n>Make sure that sharp node module is installed (npm install sharp).
|
||||
</small>
|
||||
</app-settings-entry>
|
||||
|
||||
|
||||
<hr/>
|
||||
</div>
|
||||
<p class="title" i18n>Photo converting:</p>
|
||||
|
||||
<app-settings-entry
|
||||
|
@ -20,13 +20,11 @@ import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
providers: [PhotoSettingsService],
|
||||
})
|
||||
export class PhotoSettingsComponent extends SettingsComponent<{
|
||||
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||
server: ServerConfig.PhotoConfig,
|
||||
client: ClientConfig.PhotoConfig
|
||||
}> {
|
||||
readonly resolutionTypes = [720, 1080, 1440, 2160, 4320];
|
||||
resolutions: { key: number, value: string }[] = [];
|
||||
PhotoProcessingLib = ServerConfig.PhotoProcessingLib;
|
||||
JobProgressStates = JobProgressStates;
|
||||
|
||||
readonly jobName = DefaultsJobs[DefaultsJobs['Photo Converting']];
|
||||
@ -38,7 +36,6 @@ export class PhotoSettingsComponent extends SettingsComponent<{
|
||||
notification: NotificationService,
|
||||
i18n: I18n) {
|
||||
super(i18n('Photo'), _authService, _navigation, _settingsService, notification, i18n, s => ({
|
||||
photoProcessingLibrary: s.Server.Media.photoProcessingLibrary,
|
||||
client: s.Client.Media.Photo,
|
||||
server: s.Server.Media.Photo
|
||||
}));
|
||||
|
@ -7,7 +7,6 @@ import {ClientConfig} from '../../../../../common/config/public/ClientConfig';
|
||||
|
||||
@Injectable()
|
||||
export class PhotoSettingsService extends AbstractSettingsService<{
|
||||
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||
server: ServerConfig.PhotoConfig,
|
||||
client: ClientConfig.PhotoConfig
|
||||
}> {
|
||||
@ -18,7 +17,6 @@ export class PhotoSettingsService extends AbstractSettingsService<{
|
||||
|
||||
|
||||
public updateSettings(settings: {
|
||||
photoProcessingLibrary: ServerConfig.PhotoProcessingLib,
|
||||
server: ServerConfig.PhotoConfig,
|
||||
client: ClientConfig.PhotoConfig
|
||||
}): Promise<void> {
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
<app-settings-entry
|
||||
name="Thumbnail Quality"
|
||||
description="High quality may be slow. Especially with Jimp."
|
||||
description="High quality may be slow."
|
||||
i18n-description i18n-name
|
||||
[ngModel]="states.server.qualityPriority"
|
||||
[simplifiedMode]="simplifiedMode">
|
||||
|
@ -29,7 +29,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).to.be.undefined;
|
||||
done();
|
||||
};
|
||||
@ -45,7 +45,7 @@ describe('Authentication middleware', () => {
|
||||
params: {}
|
||||
};
|
||||
Config.Client.authenticationRequired = true;
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.NOT_AUTHENTICATED);
|
||||
done();
|
||||
@ -136,7 +136,7 @@ describe('Authentication middleware', () => {
|
||||
},
|
||||
sessionOptions: {},
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.ALREADY_AUTHENTICATED);
|
||||
done();
|
||||
@ -156,7 +156,7 @@ describe('Authentication middleware', () => {
|
||||
},
|
||||
sessionOptions: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).to.be.undefined;
|
||||
done();
|
||||
};
|
||||
@ -173,7 +173,7 @@ describe('Authentication middleware', () => {
|
||||
},
|
||||
sessionOptions: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.NOT_AUTHORISED);
|
||||
done();
|
||||
@ -194,7 +194,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -209,7 +209,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -226,7 +226,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.INPUT_ERROR);
|
||||
done();
|
||||
@ -248,7 +248,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).not.to.be.undefined;
|
||||
expect(err.code).to.be.eql(ErrorCodes.CREDENTIAL_NOT_FOUND);
|
||||
done();
|
||||
@ -275,7 +275,7 @@ describe('Authentication middleware', () => {
|
||||
query: {},
|
||||
params: {}
|
||||
};
|
||||
const next = (err: ErrorDTO) => {
|
||||
const next: any = (err: ErrorDTO) => {
|
||||
expect(err).to.be.undefined;
|
||||
expect(req.session.user).to.be.eql('test user');
|
||||
done();
|
||||
|
Loading…
Reference in New Issue
Block a user