improving tests
This commit is contained in:
parent
9412fcba4d
commit
f8e4542c66
@ -1,3 +1,4 @@
|
||||
dist: trusty
|
||||
language: node_js
|
||||
node_js:
|
||||
- '9'
|
||||
@ -14,3 +15,9 @@ deploy:
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
|
||||
addons:
|
||||
chrome: stable
|
||||
before_install:
|
||||
- # start your web application and listen on `localhost`
|
||||
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 http://localhost &
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import * as winston from "winston";
|
||||
import * as winston from 'winston';
|
||||
|
||||
declare module 'winston' {
|
||||
interface LoggerInstance {
|
||||
@ -10,19 +10,19 @@ declare module 'winston' {
|
||||
export const winstonSettings = {
|
||||
transports: [
|
||||
new winston.transports.Console({
|
||||
level: process.env.NODE_ENV == "production" ? "info" : 'silly',
|
||||
level: process.env.NODE_ENV == 'production' ? 'info' : 'silly',
|
||||
handleExceptions: true,
|
||||
json: false,
|
||||
colorize: true,
|
||||
timestamp: function () {
|
||||
return (new Date()).toLocaleString();
|
||||
},
|
||||
label: "innerLabel",
|
||||
label: 'innerLabel',
|
||||
formatter: (options) => {
|
||||
// Return string will be passed to logger.
|
||||
return options.timestamp() + '[' + winston['config']['colorize'](options.level, options.level.toUpperCase()) + '] ' +
|
||||
(undefined !== options.message ? options.message : '') +
|
||||
(options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '' );
|
||||
(options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : '');
|
||||
},
|
||||
debugStdout: true
|
||||
})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import * as path from "path";
|
||||
import {Config} from "../common/config/private/Config";
|
||||
import * as path from 'path';
|
||||
import {Config} from '../common/config/private/Config';
|
||||
|
||||
class ProjectPathClass {
|
||||
public Root: string;
|
||||
@ -24,10 +24,10 @@ class ProjectPathClass {
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.Root = path.join(__dirname, "/../");
|
||||
this.Root = path.join(__dirname, '/../');
|
||||
this.ImageFolder = this.getAbsolutePath(Config.Server.imagesFolder);
|
||||
this.ThumbnailFolder = this.getAbsolutePath(Config.Server.thumbnail.folder);
|
||||
this.FrontendFolder = path.join(this.Root, 'dist')
|
||||
this.FrontendFolder = path.join(this.Root, 'dist');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import * as cluster from "cluster";
|
||||
import * as cluster from 'cluster';
|
||||
|
||||
if (cluster.isMaster) {
|
||||
const Server = require("./server").Server;
|
||||
new Server();
|
||||
const Server = require('./server').Server;
|
||||
const srv = new Server();
|
||||
} else {
|
||||
const Worker = require("./model/threading/Worker").Worker;
|
||||
const Worker = require('./model/threading/Worker').Worker;
|
||||
Worker.process();
|
||||
}
|
||||
|
||||
@ -1,23 +1,18 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {Logger} from "../Logger";
|
||||
import {SQLConnection} from "../model/sql/SQLConnection";
|
||||
import {
|
||||
DataBaseConfig,
|
||||
DatabaseType,
|
||||
IndexingConfig,
|
||||
ThumbnailConfig
|
||||
} from "../../common/config/private/IPrivateConfig";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {ConfigDiagnostics} from "../model/ConfigDiagnostics";
|
||||
import {ClientConfig} from "../../common/config/public/ConfigClass";
|
||||
import {BasicConfigDTO} from "../../common/entities/settings/BasicConfigDTO";
|
||||
import {OtherConfigDTO} from "../../common/entities/settings/OtherConfigDTO";
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
|
||||
import {Logger} from '../Logger';
|
||||
import {SQLConnection} from '../model/sql/SQLConnection';
|
||||
import {DataBaseConfig, DatabaseType, IndexingConfig, ThumbnailConfig} from '../../common/config/private/IPrivateConfig';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {ConfigDiagnostics} from '../model/ConfigDiagnostics';
|
||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
||||
import {BasicConfigDTO} from '../../common/entities/settings/BasicConfigDTO';
|
||||
import {OtherConfigDTO} from '../../common/entities/settings/OtherConfigDTO';
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
|
||||
|
||||
const LOG_TAG = "[AdminMWs]";
|
||||
const LOG_TAG = '[AdminMWs]';
|
||||
|
||||
export class AdminMWs {
|
||||
|
||||
@ -25,30 +20,30 @@ export class AdminMWs {
|
||||
public static async updateDatabaseSettings(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
const databaseSettings = <DataBaseConfig>req.body.settings;
|
||||
|
||||
try {
|
||||
if (databaseSettings.type != DatabaseType.memory) {
|
||||
if (databaseSettings.type !== DatabaseType.memory) {
|
||||
await SQLConnection.tryConnection(databaseSettings);
|
||||
}
|
||||
Config.Server.database = databaseSettings;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Server.database = databaseSettings;
|
||||
if (databaseSettings.type == DatabaseType.memory) {
|
||||
if (databaseSettings.type === DatabaseType.memory) {
|
||||
original.Client.Sharing.enabled = false;
|
||||
original.Client.Search.enabled = false;
|
||||
}
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
|
||||
ObjectManagerRepository.reset();
|
||||
if (Config.Server.database.type != DatabaseType.memory) {
|
||||
if (Config.Server.database.type !== DatabaseType.memory) {
|
||||
await ObjectManagerRepository.InitSQLManagers();
|
||||
} else {
|
||||
await ObjectManagerRepository.InitMemoryManagers();
|
||||
@ -57,41 +52,41 @@ export class AdminMWs {
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Error while saving database settings: " + err.toString(), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Error while saving database settings: ' + err.toString(), err));
|
||||
}
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Error while saving database settings", err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Error while saving database settings', err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateMapSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testMapConfig(<ClientConfig.MapConfig>req.body.settings);
|
||||
|
||||
Config.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Client.Map = <ClientConfig.MapConfig>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateShareSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
await ConfigDiagnostics.testSharingConfig(<ClientConfig.SharingConfig>req.body.settings, original);
|
||||
|
||||
@ -99,22 +94,22 @@ export class AdminMWs {
|
||||
original.Client.Sharing = <ClientConfig.SharingConfig>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async updateSearchSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
await ConfigDiagnostics.testSearchConfig(<ClientConfig.SearchConfig>req.body.settings, original);
|
||||
|
||||
@ -122,38 +117,38 @@ export class AdminMWs {
|
||||
original.Client.Search = <ClientConfig.SearchConfig>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async updateAuthenticationSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
Config.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Client.authenticationRequired = <boolean>req.body.settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateThumbnailSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
@ -166,28 +161,28 @@ export class AdminMWs {
|
||||
await ConfigDiagnostics.testClientThumbnailConfig(settings.client);
|
||||
Config.Server.thumbnail = settings.server;
|
||||
Config.Client.Thumbnail = settings.client;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Server.thumbnail = settings.server;
|
||||
original.Client.Thumbnail = settings.client;
|
||||
original.save();
|
||||
ProjectPath.reset();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + err.toString(), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + err.toString(), err));
|
||||
}
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async updateBasicSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
@ -197,7 +192,7 @@ export class AdminMWs {
|
||||
Config.Server.imagesFolder = settings.imagesFolder;
|
||||
Config.Client.publicUrl = settings.publicUrl;
|
||||
Config.Client.applicationTitle = settings.applicationTitle;
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Server.port = settings.port;
|
||||
original.Server.imagesFolder = settings.imagesFolder;
|
||||
@ -206,18 +201,18 @@ export class AdminMWs {
|
||||
original.save();
|
||||
ProjectPath.reset();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static async updateOtherSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
@ -226,7 +221,7 @@ export class AdminMWs {
|
||||
Config.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
||||
Config.Client.enableOnScrollThumbnailPrioritising = settings.enableOnScrollThumbnailPrioritising;
|
||||
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Client.enableCache = settings.enableCache;
|
||||
original.Client.enableOnScrollRendering = settings.enableOnScrollRendering;
|
||||
@ -234,33 +229,33 @@ export class AdminMWs {
|
||||
original.Server.enableThreading = settings.enableThreading;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateIndexingSettings(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.settings === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "settings is needed"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'settings is needed'));
|
||||
}
|
||||
|
||||
try {
|
||||
const settings: IndexingConfig = req.body.settings;
|
||||
Config.Server.indexing = settings;
|
||||
|
||||
//only updating explicitly set config (not saving config set by the diagnostics)
|
||||
// only updating explicitly set config (not saving config set by the diagnostics)
|
||||
const original = Config.original();
|
||||
original.Server.indexing = settings;
|
||||
original.save();
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "new config:");
|
||||
Logger.info(LOG_TAG, 'new config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Settings error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Settings error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,10 +263,10 @@ export class AdminMWs {
|
||||
public static startIndexing(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
ObjectManagerRepository.getInstance().IndexingManager.startIndexing();
|
||||
req.resultPipe = "ok";
|
||||
req.resultPipe = 'ok';
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,27 +275,27 @@ export class AdminMWs {
|
||||
req.resultPipe = ObjectManagerRepository.getInstance().IndexingManager.getProgress();
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static cancelIndexing(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
ObjectManagerRepository.getInstance().IndexingManager.cancelIndexing();
|
||||
req.resultPipe = "ok";
|
||||
req.resultPipe = 'ok';
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async resetIndexes(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
await ObjectManagerRepository.getInstance().IndexingManager.reset();
|
||||
req.resultPipe = "ok";
|
||||
req.resultPipe = 'ok';
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, "Indexing error: " + JSON.stringify(err, null, ' '), err));
|
||||
return next(new ErrorDTO(ErrorCodes.SETTINGS_ERROR, 'Indexing error: ' + JSON.stringify(err, null, ' '), err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {DirectoryDTO} from "../../common/entities/DirectoryDTO";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {SearchTypes} from "../../common/entities/AutoCompleteItem";
|
||||
import {ContentWrapper} from "../../common/entities/ConentWrapper";
|
||||
import {PhotoDTO} from "../../common/entities/PhotoDTO";
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {UserDTO} from "../../common/entities/UserDTO";
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {DirectoryDTO} from '../../common/entities/DirectoryDTO';
|
||||
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
|
||||
import {SearchTypes} from '../../common/entities/AutoCompleteItem';
|
||||
import {ContentWrapper} from '../../common/entities/ConentWrapper';
|
||||
import {PhotoDTO} from '../../common/entities/PhotoDTO';
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {UserDTO} from '../../common/entities/UserDTO';
|
||||
|
||||
|
||||
const LOG_TAG = "[GalleryMWs]";
|
||||
const LOG_TAG = '[GalleryMWs]';
|
||||
|
||||
export class GalleryMWs {
|
||||
|
||||
|
||||
public static async listDirectory(req: Request, res: Response, next: NextFunction) {
|
||||
console.log("listDirectory");
|
||||
let directoryName = req.params.directory || "/";
|
||||
console.log('listDirectory');
|
||||
let directoryName = req.params.directory || '/';
|
||||
let absoluteDirectoryName = path.join(ProjectPath.ImageFolder, directoryName);
|
||||
|
||||
if (!fs.statSync(absoluteDirectoryName).isDirectory()) {
|
||||
console.log("not dir");
|
||||
console.log('not dir');
|
||||
return next();
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ export class GalleryMWs {
|
||||
|
||||
const directory = await ObjectManagerRepository.getInstance().GalleryManager.listDirectory(directoryName, req.query.knownLastModified, req.query.knownLastScanned);
|
||||
if (directory == null) {
|
||||
console.log("null dir");
|
||||
console.log('null dir');
|
||||
req.resultPipe = new ContentWrapper(null, null, true);
|
||||
return next();
|
||||
}
|
||||
@ -39,7 +39,7 @@ export class GalleryMWs {
|
||||
console.log(directory);
|
||||
if (req.session.user.permissions &&
|
||||
req.session.user.permissions.length > 0 &&
|
||||
req.session.user.permissions[0] != "/*") {
|
||||
req.session.user.permissions[0] != '/*') {
|
||||
(<DirectoryDTO>directory).directories = (<DirectoryDTO>directory).directories.filter(d =>
|
||||
UserDTO.isDirectoryAvailable(d, req.session.user.permissions));
|
||||
}
|
||||
@ -47,7 +47,7 @@ export class GalleryMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during listing the directory", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during listing the directory', err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ export class GalleryMWs {
|
||||
|
||||
//check if thumbnail already exist
|
||||
if (fs.existsSync(fullImagePath) === false) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "no such file:" + fullImagePath));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'no such file:' + fullImagePath));
|
||||
}
|
||||
if (fs.statSync(fullImagePath).isDirectory()) {
|
||||
return next();
|
||||
@ -122,7 +122,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = new ContentWrapper(null, result);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = new ContentWrapper(null, result);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err));
|
||||
}
|
||||
}
|
||||
|
||||
@ -158,7 +158,7 @@ export class GalleryMWs {
|
||||
req.resultPipe = await ObjectManagerRepository.getInstance().SearchManager.autocomplete(req.params.text);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during searching", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during searching', err));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {NotificationManager} from "../model/NotifocationManager";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {NotificationManager} from '../model/NotifocationManager';
|
||||
|
||||
const LOG_TAG = '[NotificationMWs]';
|
||||
|
||||
const LOG_TAG = "[NotificationMWs]";
|
||||
export class NotificationMWs {
|
||||
|
||||
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {Utils} from "../../common/Utils";
|
||||
import {Message} from "../../common/entities/Message";
|
||||
import {SharingDTO} from "../../common/entities/SharingDTO";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {PrivateConfigClass} from "../../common/config/private/PrivateConfigClass";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {NotificationManager} from "../model/NotifocationManager";
|
||||
import {Logger} from "../Logger";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {Utils} from '../../common/Utils';
|
||||
import {Message} from '../../common/entities/Message';
|
||||
import {SharingDTO} from '../../common/entities/SharingDTO';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {PrivateConfigClass} from '../../common/config/private/PrivateConfigClass';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {NotificationManager} from '../model/NotifocationManager';
|
||||
import {Logger} from '../Logger';
|
||||
|
||||
export class RenderingMWs {
|
||||
|
||||
public static renderResult(req: Request, res: Response, next: NextFunction) {
|
||||
if (typeof req.resultPipe == "undefined")
|
||||
if (typeof req.resultPipe == 'undefined')
|
||||
return next();
|
||||
|
||||
return RenderingMWs.renderMessage(res, req.resultPipe);
|
||||
@ -21,7 +21,7 @@ export class RenderingMWs {
|
||||
|
||||
public static renderSessionUser(req: Request, res: Response, next: NextFunction) {
|
||||
if (!(req.session.user)) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "User not exists"));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'User not exists'));
|
||||
}
|
||||
|
||||
const user = Utils.clone(req.session.user);
|
||||
@ -46,7 +46,7 @@ export class RenderingMWs {
|
||||
}
|
||||
|
||||
public static renderOK(req: Request, res: Response, next: NextFunction) {
|
||||
let message = new Message<string>(null, "ok");
|
||||
let message = new Message<string>(null, 'ok');
|
||||
res.json(message);
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ export class RenderingMWs {
|
||||
if (err instanceof ErrorDTO) {
|
||||
if (err.details) {
|
||||
if (!(req.session.user && req.session.user.role >= UserRoles.Developer)) {
|
||||
Logger.warn("Handled error:", err);
|
||||
Logger.warn('Handled error:', err);
|
||||
delete (err.details);
|
||||
} else {
|
||||
try {
|
||||
@ -75,7 +75,7 @@ export class RenderingMWs {
|
||||
let message = new Message<any>(err, null);
|
||||
return res.json(message);
|
||||
}
|
||||
NotificationManager.error("unknown server error", err);
|
||||
NotificationManager.error('unknown server error', err);
|
||||
return next(err);
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {CreateSharingDTO, SharingDTO} from "../../common/entities/SharingDTO";
|
||||
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {CreateSharingDTO, SharingDTO} from '../../common/entities/SharingDTO';
|
||||
import {ObjectManagerRepository} from '../model/ObjectManagerRepository';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
|
||||
const LOG_TAG = '[SharingMWs]';
|
||||
|
||||
const LOG_TAG = "[SharingMWs]";
|
||||
export class SharingMWs {
|
||||
|
||||
|
||||
@ -26,14 +27,14 @@ export class SharingMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during retrieving sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during retrieving sharing link', err));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static async createSharing(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.createSharing === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "createSharing filed is missing"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'createSharing filed is missing'));
|
||||
}
|
||||
const createSharing: CreateSharingDTO = req.body.createSharing;
|
||||
let sharingKey = SharingMWs.generateKey();
|
||||
@ -50,7 +51,7 @@ export class SharingMWs {
|
||||
}
|
||||
|
||||
|
||||
const directoryName = req.params.directory || "/";
|
||||
const directoryName = req.params.directory || '/';
|
||||
let sharing: SharingDTO = {
|
||||
id: null,
|
||||
sharingKey: sharingKey,
|
||||
@ -68,20 +69,20 @@ export class SharingMWs {
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during creating sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during creating sharing link', err));
|
||||
}
|
||||
}
|
||||
|
||||
public static async updateSharing(req: Request, res: Response, next: NextFunction) {
|
||||
if ((typeof req.body === 'undefined') || (typeof req.body.updateSharing === 'undefined')) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "updateSharing filed is missing"));
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'updateSharing filed is missing'));
|
||||
}
|
||||
const updateSharing: CreateSharingDTO = req.body.updateSharing;
|
||||
const directoryName = req.params.directory || "/";
|
||||
const directoryName = req.params.directory || '/';
|
||||
let sharing: SharingDTO = {
|
||||
id: updateSharing.id,
|
||||
path: directoryName,
|
||||
sharingKey: "",
|
||||
sharingKey: '',
|
||||
password: updateSharing.password,
|
||||
creator: req.session.user,
|
||||
expires: Date.now() + updateSharing.valid,
|
||||
@ -93,7 +94,7 @@ export class SharingMWs {
|
||||
req.resultPipe = await ObjectManagerRepository.getInstance().SharingManager.updateSharing(sharing);
|
||||
return next();
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, "Error during updating sharing link", err));
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, 'Error during updating sharing link', err));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
16
backend/middlewares/customtypings/jimp.d.ts
vendored
16
backend/middlewares/customtypings/jimp.d.ts
vendored
@ -1,10 +1,10 @@
|
||||
declare module "jimp" {
|
||||
function read(filaname);
|
||||
declare module 'jimp' {
|
||||
function read(fileName);
|
||||
|
||||
var RESIZE_NEAREST_NEIGHBOR;
|
||||
var RESIZE_BILINEAR;
|
||||
var RESIZE_BICUBIC;
|
||||
var RESIZE_HERMITE;
|
||||
var RESIZE_BEZIER;
|
||||
var AUTO: any;
|
||||
const RESIZE_NEAREST_NEIGHBOR;
|
||||
const RESIZE_BILINEAR;
|
||||
const RESIZE_BICUBIC;
|
||||
const RESIZE_HERMITE;
|
||||
const RESIZE_BEZIER;
|
||||
const AUTO: any;
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
///<reference path="../customtypings/jimp.d.ts"/>
|
||||
import * as path from "path";
|
||||
import * as crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig";
|
||||
import {ThumbnailTH} from "../../model/threading/ThreadPool";
|
||||
import {RendererInput} from "../../model/threading/ThumbnailWoker";
|
||||
import {ITaskQue, TaskQue} from "../../model/threading/TaskQue";
|
||||
import * as path from 'path';
|
||||
import * as crypto from 'crypto';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
||||
import {ThumbnailTH} from '../../model/threading/ThreadPool';
|
||||
import {RendererInput} from '../../model/threading/ThumbnailWoker';
|
||||
import {ITaskQue, TaskQue} from '../../model/threading/TaskQue';
|
||||
|
||||
|
||||
export class ThumbnailGeneratorMWs {
|
||||
@ -21,20 +21,20 @@ export class ThumbnailGeneratorMWs {
|
||||
private static taskQue: ITaskQue = null;
|
||||
|
||||
public static init() {
|
||||
if (this.initDone == true) {
|
||||
return
|
||||
if (this.initDone === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Config.Server.enableThreading == true ||
|
||||
Config.Server.thumbnail.processingLibrary != ThumbnailProcessingLib.Jimp) {
|
||||
if (Config.Server.enableThreading === true ||
|
||||
Config.Server.thumbnail.processingLibrary !== ThumbnailProcessingLib.Jimp) {
|
||||
Config.Client.concurrentThumbnailGenerations = Math.max(1, os.cpus().length - 1);
|
||||
} else {
|
||||
Config.Client.concurrentThumbnailGenerations = 1;
|
||||
}
|
||||
|
||||
if (Config.Server.enableThreading == true &&
|
||||
Config.Server.thumbnail.processingLibrary == ThumbnailProcessingLib.Jimp) {
|
||||
if (Config.Server.enableThreading === true &&
|
||||
Config.Server.thumbnail.processingLibrary === ThumbnailProcessingLib.Jimp) {
|
||||
this.taskQue = new ThumbnailTH(Config.Client.concurrentThumbnailGenerations);
|
||||
} else {
|
||||
this.taskQue = new TaskQue(Config.Client.concurrentThumbnailGenerations);
|
||||
@ -43,49 +43,13 @@ export class ThumbnailGeneratorMWs {
|
||||
this.initDone = true;
|
||||
}
|
||||
|
||||
private static addThInfoTODir(directory: DirectoryDTO) {
|
||||
if (typeof directory.photos == "undefined") {
|
||||
directory.photos = [];
|
||||
}
|
||||
if (typeof directory.directories == "undefined") {
|
||||
directory.directories = [];
|
||||
}
|
||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.photos);
|
||||
|
||||
for (let i = 0; i < directory.directories.length; i++) {
|
||||
ThumbnailGeneratorMWs.addThInfoTODir(directory.directories[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static addThInfoToPhotos(photos: Array<PhotoDTO>) {
|
||||
let thumbnailFolder = ProjectPath.ThumbnailFolder;
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
let fullImagePath = path.join(ProjectPath.ImageFolder, photos[i].directory.path, photos[i].directory.name, photos[i].name);
|
||||
for (let j = 0; j < Config.Client.Thumbnail.thumbnailSizes.length; j++) {
|
||||
let size = Config.Client.Thumbnail.thumbnailSizes[j];
|
||||
let thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, size));
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
if (typeof photos[i].readyThumbnails == "undefined") {
|
||||
photos[i].readyThumbnails = [];
|
||||
}
|
||||
photos[i].readyThumbnails.push(size);
|
||||
}
|
||||
}
|
||||
let iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.Thumbnail.iconSize));
|
||||
if (fs.existsSync(iconPath) === true) {
|
||||
photos[i].readyIcon = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static addThumbnailInformation(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe)
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
let cw: ContentWrapper = req.resultPipe;
|
||||
if (cw.notModified == true) {
|
||||
const cw: ContentWrapper = req.resultPipe;
|
||||
if (cw.notModified === true) {
|
||||
return next();
|
||||
}
|
||||
if (cw.directory) {
|
||||
@ -101,14 +65,15 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
public static generateThumbnail(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe)
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
//load parameters
|
||||
let imagePath = req.resultPipe;
|
||||
let size: number = parseInt(req.params.size) || Config.Client.Thumbnail.thumbnailSizes[0];
|
||||
// load parameters
|
||||
const imagePath = req.resultPipe;
|
||||
let size: number = parseInt(req.params.size, 10) || Config.Client.Thumbnail.thumbnailSizes[0];
|
||||
|
||||
//validate size
|
||||
// validate size
|
||||
if (Config.Client.Thumbnail.thumbnailSizes.indexOf(size) === -1) {
|
||||
size = Config.Client.Thumbnail.thumbnailSizes[0];
|
||||
}
|
||||
@ -119,37 +84,74 @@ export class ThumbnailGeneratorMWs {
|
||||
}
|
||||
|
||||
public static generateIcon(req: Request, res: Response, next: NextFunction) {
|
||||
if (!req.resultPipe)
|
||||
if (!req.resultPipe) {
|
||||
return next();
|
||||
}
|
||||
|
||||
//load parameters
|
||||
let imagePath = req.resultPipe;
|
||||
let size: number = Config.Client.Thumbnail.iconSize;
|
||||
// load parameters
|
||||
const imagePath = req.resultPipe;
|
||||
const size: number = Config.Client.Thumbnail.iconSize;
|
||||
ThumbnailGeneratorMWs.generateImage(imagePath, size, true, req, res, next);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static addThInfoTODir(directory: DirectoryDTO) {
|
||||
if (typeof directory.photos === 'undefined') {
|
||||
directory.photos = [];
|
||||
}
|
||||
if (typeof directory.directories === 'undefined') {
|
||||
directory.directories = [];
|
||||
}
|
||||
ThumbnailGeneratorMWs.addThInfoToPhotos(directory.photos);
|
||||
|
||||
for (let i = 0; i < directory.directories.length; i++) {
|
||||
ThumbnailGeneratorMWs.addThInfoTODir(directory.directories[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static addThInfoToPhotos(photos: Array<PhotoDTO>) {
|
||||
const thumbnailFolder = ProjectPath.ThumbnailFolder;
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
const fullImagePath = path.join(ProjectPath.ImageFolder, photos[i].directory.path, photos[i].directory.name, photos[i].name);
|
||||
for (let j = 0; j < Config.Client.Thumbnail.thumbnailSizes.length; j++) {
|
||||
const size = Config.Client.Thumbnail.thumbnailSizes[j];
|
||||
const thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, size));
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
if (typeof photos[i].readyThumbnails === 'undefined') {
|
||||
photos[i].readyThumbnails = [];
|
||||
}
|
||||
photos[i].readyThumbnails.push(size);
|
||||
}
|
||||
}
|
||||
const iconPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(fullImagePath, Config.Client.Thumbnail.iconSize));
|
||||
if (fs.existsSync(iconPath) === true) {
|
||||
photos[i].readyIcon = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static async generateImage(imagePath: string, size: number, makeSquare: boolean, req: Request, res: Response, next: NextFunction) {
|
||||
//generate thumbnail path
|
||||
let thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
|
||||
// generate thumbnail path
|
||||
const thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
|
||||
|
||||
|
||||
req.resultPipe = thPath;
|
||||
|
||||
//check if thumbnail already exist
|
||||
// check if thumbnail already exist
|
||||
if (fs.existsSync(thPath) === true) {
|
||||
return next();
|
||||
}
|
||||
|
||||
//create thumbnail folder if not exist
|
||||
// create thumbnail folder if not exist
|
||||
if (!fs.existsSync(ProjectPath.ThumbnailFolder)) {
|
||||
fs.mkdirSync(ProjectPath.ThumbnailFolder);
|
||||
}
|
||||
|
||||
//run on other thread
|
||||
let input = <RendererInput>{
|
||||
// run on other thread
|
||||
const input = <RendererInput>{
|
||||
imagePath: imagePath,
|
||||
size: size,
|
||||
thPath: thPath,
|
||||
@ -160,12 +162,12 @@ export class ThumbnailGeneratorMWs {
|
||||
await this.taskQue.execute(input);
|
||||
return next();
|
||||
} catch (error) {
|
||||
return next(new ErrorDTO(ErrorCodes.THUMBNAIL_GENERATION_ERROR, "Error during generating thumbnail", error));
|
||||
return next(new ErrorDTO(ErrorCodes.THUMBNAIL_GENERATION_ERROR, 'Error during generating thumbnail', error));
|
||||
}
|
||||
}
|
||||
|
||||
private static generateThumbnailName(imagePath: string, size: number): string {
|
||||
return crypto.createHash('md5').update(imagePath).digest('hex') + "_" + size + ".jpg";
|
||||
return crypto.createHash('md5').update(imagePath).digest('hex') + '_' + size + '.jpg';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,42 +1,17 @@
|
||||
///<reference path="../customtypings/ExtendedRequest.d.ts"/>
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {PasswordHelper} from "../../model/PasswordHelper";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {ObjectManagerRepository} from '../../model/ObjectManagerRepository';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {PasswordHelper} from '../../model/PasswordHelper';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
|
||||
export class AuthenticationMWs {
|
||||
|
||||
private static async getSharingUser(req: Request) {
|
||||
if (Config.Client.Sharing.enabled === true &&
|
||||
(!!req.query.sk || !!req.params.sharingKey)) {
|
||||
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
||||
sharingKey: req.query.sk || req.params.sharingKey,
|
||||
});
|
||||
if (!sharing || sharing.expires < Date.now()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Config.Client.Sharing.passwordProtected === true && sharing.password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let path = sharing.path;
|
||||
if (sharing.includeSubfolders == true) {
|
||||
path += "*";
|
||||
}
|
||||
return <UserDTO>{name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]};
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static async tryAuthenticate(req: Request, res: Response, next: NextFunction) {
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
req.session.user = <UserDTO>{name: "Admin", role: UserRoles.Admin};
|
||||
req.session.user = <UserDTO>{name: 'Admin', role: UserRoles.Admin};
|
||||
return next();
|
||||
}
|
||||
try {
|
||||
@ -55,7 +30,7 @@ export class AuthenticationMWs {
|
||||
public static async authenticate(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
if (Config.Client.authenticationRequired === false) {
|
||||
req.session.user = <UserDTO>{name: "Admin", role: UserRoles.Admin};
|
||||
req.session.user = <UserDTO>{name: 'Admin', role: UserRoles.Admin};
|
||||
return next();
|
||||
}
|
||||
try {
|
||||
@ -78,6 +53,21 @@ export class AuthenticationMWs {
|
||||
return next();
|
||||
}
|
||||
|
||||
public static authoriseDirectory(req: Request, res: Response, next: NextFunction) {
|
||||
if (req.session.user.permissions == null ||
|
||||
req.session.user.permissions.length == 0 ||
|
||||
req.session.user.permissions[0] == '/*') {
|
||||
return next();
|
||||
}
|
||||
|
||||
const directoryName = req.params.directory || '/';
|
||||
if (UserDTO.isPathAvailable(directoryName, req.session.user.permissions) == true) {
|
||||
return next();
|
||||
}
|
||||
|
||||
return next(new ErrorDTO(ErrorCodes.PERMISSION_DENIED));
|
||||
}
|
||||
|
||||
public static authorise(role: UserRoles) {
|
||||
return (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.session.user.role < role) {
|
||||
@ -87,19 +77,40 @@ export class AuthenticationMWs {
|
||||
};
|
||||
}
|
||||
|
||||
public static authoriseDirectory(req: Request, res: Response, next: NextFunction) {
|
||||
if (req.session.user.permissions == null ||
|
||||
req.session.user.permissions.length == 0 ||
|
||||
req.session.user.permissions[0] == "/*") {
|
||||
public static async shareLogin(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const directoryName = req.params.directory || "/";
|
||||
if (UserDTO.isPathAvailable(directoryName, req.session.user.permissions) == true) {
|
||||
return next();
|
||||
//not enough parameter
|
||||
if ((!req.query.sk && !req.params.sharingKey)) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, 'no sharing key provided'));
|
||||
}
|
||||
|
||||
try {
|
||||
const password = (req.body ? req.body.password : null) || null;
|
||||
|
||||
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
||||
sharingKey: req.query.sk || req.params.sharingKey,
|
||||
});
|
||||
if (!sharing || sharing.expires < Date.now() ||
|
||||
(Config.Client.Sharing.passwordProtected === true
|
||||
&& sharing.password && !PasswordHelper.comparePassword(password, sharing.password))) {
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
}
|
||||
|
||||
let path = sharing.path;
|
||||
if (sharing.includeSubfolders == true) {
|
||||
path += '*';
|
||||
}
|
||||
|
||||
req.session.user = <UserDTO>{name: 'Guest', role: UserRoles.LimitedGuest, permissions: [path]};
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
|
||||
return next(new ErrorDTO(ErrorCodes.PERMISSION_DENIED));
|
||||
}
|
||||
|
||||
public static inverseAuthenticate(req: Request, res: Response, next: NextFunction) {
|
||||
@ -136,41 +147,28 @@ export class AuthenticationMWs {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static async shareLogin(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
if (Config.Client.Sharing.enabled === false) {
|
||||
return next();
|
||||
}
|
||||
//not enough parameter
|
||||
if ((!req.query.sk && !req.params.sharingKey)) {
|
||||
return next(new ErrorDTO(ErrorCodes.INPUT_ERROR, "no sharing key provided"));
|
||||
}
|
||||
|
||||
try {
|
||||
const password = (req.body ? req.body.password : null) || null;
|
||||
|
||||
private static async getSharingUser(req: Request) {
|
||||
if (Config.Client.Sharing.enabled === true &&
|
||||
(!!req.query.sk || !!req.params.sharingKey)) {
|
||||
const sharing = await ObjectManagerRepository.getInstance().SharingManager.findOne({
|
||||
sharingKey: req.query.sk || req.params.sharingKey,
|
||||
});
|
||||
if (!sharing || sharing.expires < Date.now() ||
|
||||
(Config.Client.Sharing.passwordProtected === true
|
||||
&& sharing.password && !PasswordHelper.comparePassword(password, sharing.password))) {
|
||||
return next(new ErrorDTO(ErrorCodes.CREDENTIAL_NOT_FOUND));
|
||||
if (!sharing || sharing.expires < Date.now()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Config.Client.Sharing.passwordProtected === true && sharing.password) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let path = sharing.path;
|
||||
if (sharing.includeSubfolders == true) {
|
||||
path += "*";
|
||||
path += '*';
|
||||
}
|
||||
return <UserDTO>{name: 'Guest', role: UserRoles.LimitedGuest, permissions: [path]};
|
||||
|
||||
req.session.user = <UserDTO>{name: "Guest", role: UserRoles.LimitedGuest, permissions: [path]};
|
||||
return next();
|
||||
|
||||
} catch (err) {
|
||||
return next(new ErrorDTO(ErrorCodes.GENERAL_ERROR, null, err));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static logout(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {ObjectManagerRepository} from '../../model/ObjectManagerRepository';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
|
||||
export class UserMWs {
|
||||
|
||||
@ -94,7 +94,7 @@ export class UserMWs {
|
||||
let result = await ObjectManagerRepository.getInstance().UserManager.find({});
|
||||
result = Utils.clone(result);
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
result[i].password = "";
|
||||
result[i].password = '';
|
||||
}
|
||||
req.resultPipe = result;
|
||||
next();
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {ErrorCodes, ErrorDTO} from "../../../common/entities/Error";
|
||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {ObjectManagerRepository} from "../../model/ObjectManagerRepository";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {ErrorCodes, ErrorDTO} from '../../../common/entities/Error';
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {ObjectManagerRepository} from '../../model/ObjectManagerRepository';
|
||||
|
||||
export class UserRequestConstrainsMWs {
|
||||
|
||||
@ -38,7 +38,7 @@ export class UserRequestConstrainsMWs {
|
||||
return next();
|
||||
}
|
||||
|
||||
//TODO: fix it!
|
||||
// TODO: fix it!
|
||||
try {
|
||||
const result = await ObjectManagerRepository.getInstance().UserManager.find({minRole: UserRoles.Admin});
|
||||
if (result.length <= 1) {
|
||||
|
||||
@ -1,19 +1,20 @@
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {
|
||||
DataBaseConfig,
|
||||
DatabaseType,
|
||||
IPrivateConfig,
|
||||
ThumbnailConfig,
|
||||
ThumbnailProcessingLib
|
||||
} from "../../common/config/private/IPrivateConfig";
|
||||
import {Logger} from "../Logger";
|
||||
import {NotificationManager} from "./NotifocationManager";
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import {SQLConnection} from "./sql/SQLConnection";
|
||||
import * as fs from "fs";
|
||||
import {ClientConfig} from "../../common/config/public/ConfigClass";
|
||||
} from '../../common/config/private/IPrivateConfig';
|
||||
import {Logger} from '../Logger';
|
||||
import {NotificationManager} from './NotifocationManager';
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
import {SQLConnection} from './sql/SQLConnection';
|
||||
import * as fs from 'fs';
|
||||
import {ClientConfig} from '../../common/config/public/ConfigClass';
|
||||
|
||||
const LOG_TAG = '[ConfigDiagnostics]';
|
||||
|
||||
const LOG_TAG = "[ConfigDiagnostics]";
|
||||
export class ConfigDiagnostics {
|
||||
|
||||
static async testDatabase(databaseConfig: DataBaseConfig) {
|
||||
@ -26,13 +27,13 @@ export class ConfigDiagnostics {
|
||||
static async testThumbnailLib(processingLibrary: ThumbnailProcessingLib) {
|
||||
switch (processingLibrary) {
|
||||
case ThumbnailProcessingLib.sharp:
|
||||
const sharp = require("sharp");
|
||||
const sharp = require('sharp');
|
||||
sharp();
|
||||
break;
|
||||
case ThumbnailProcessingLib.gm:
|
||||
const gm = require("gm");
|
||||
const gm = require('gm');
|
||||
await new Promise((resolve, reject) => {
|
||||
gm(ProjectPath.FrontendFolder + "/assets/icon.png").size((err, value) => {
|
||||
gm(ProjectPath.FrontendFolder + '/assets/icon.png').size((err, value) => {
|
||||
if (err) {
|
||||
return reject(err.toString());
|
||||
}
|
||||
@ -47,7 +48,7 @@ export class ConfigDiagnostics {
|
||||
await new Promise((resolve, reject) => {
|
||||
fs.access(folder, fs.constants.W_OK, (err) => {
|
||||
if (err) {
|
||||
reject({message: "Error during getting write access to temp folder", error: err.toString()});
|
||||
reject({message: 'Error during getting write access to temp folder', error: err.toString()});
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
@ -57,11 +58,11 @@ export class ConfigDiagnostics {
|
||||
static async testImageFolder(folder: string) {
|
||||
await new Promise((resolve, reject) => {
|
||||
if (!fs.existsSync(folder)) {
|
||||
reject("Images folder not exists: '" + folder + "'");
|
||||
reject('Images folder not exists: \'' + folder + '\'');
|
||||
}
|
||||
fs.access(folder, fs.constants.R_OK, (err) => {
|
||||
if (err) {
|
||||
reject({message: "Error during getting read access to images folder", error: err.toString()});
|
||||
reject({message: 'Error during getting read access to images folder', error: err.toString()});
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
@ -76,15 +77,15 @@ export class ConfigDiagnostics {
|
||||
|
||||
static async testClientThumbnailConfig(thumbnailConfig: ClientConfig.ThumbnailConfig) {
|
||||
if (isNaN(thumbnailConfig.iconSize) || thumbnailConfig.iconSize <= 0) {
|
||||
throw "IconSize has to be >= 0 integer, got: " + thumbnailConfig.iconSize;
|
||||
throw 'IconSize has to be >= 0 integer, got: ' + thumbnailConfig.iconSize;
|
||||
}
|
||||
|
||||
if (!thumbnailConfig.thumbnailSizes.length) {
|
||||
throw "At least one thumbnail size is needed";
|
||||
throw 'At least one thumbnail size is needed';
|
||||
}
|
||||
for (let i = 0; i < thumbnailConfig.thumbnailSizes.length; i++) {
|
||||
if (isNaN(thumbnailConfig.thumbnailSizes[i]) || thumbnailConfig.thumbnailSizes[i] <= 0) {
|
||||
throw "Thumbnail size has to be >= 0 integer, got: " + thumbnailConfig.thumbnailSizes[i];
|
||||
throw 'Thumbnail size has to be >= 0 integer, got: ' + thumbnailConfig.thumbnailSizes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,20 +93,20 @@ export class ConfigDiagnostics {
|
||||
|
||||
static async testSearchConfig(search: ClientConfig.SearchConfig, config: IPrivateConfig) {
|
||||
if (search.enabled == true && config.Server.database.type == DatabaseType.memory) {
|
||||
throw "Memory Database do not support searching";
|
||||
throw 'Memory Database do not support searching';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static async testSharingConfig(sharing: ClientConfig.SharingConfig, config: IPrivateConfig) {
|
||||
if (sharing.enabled == true && config.Server.database.type == DatabaseType.memory) {
|
||||
throw "Memory Database do not support sharing";
|
||||
throw 'Memory Database do not support sharing';
|
||||
}
|
||||
}
|
||||
|
||||
static async testMapConfig(map: ClientConfig.MapConfig) {
|
||||
if (map.enabled == true && (!map.googleApiKey || map.googleApiKey.length == 0)) {
|
||||
throw "Maps need a valid google api key";
|
||||
throw 'Maps need a valid google api key';
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,9 +117,9 @@ export class ConfigDiagnostics {
|
||||
try {
|
||||
await ConfigDiagnostics.testDatabase(Config.Server.database);
|
||||
} catch (err) {
|
||||
Logger.warn(LOG_TAG, "[SQL error]", err);
|
||||
Logger.warn(LOG_TAG, "Error during initializing SQL falling back temporally to memory DB");
|
||||
NotificationManager.warning("Error during initializing SQL falling back temporally to memory DB", err);
|
||||
Logger.warn(LOG_TAG, '[SQL error]', err);
|
||||
Logger.warn(LOG_TAG, 'Error during initializing SQL falling back temporally to memory DB');
|
||||
NotificationManager.warning('Error during initializing SQL falling back temporally to memory DB', err);
|
||||
Config.setDatabaseType(DatabaseType.memory);
|
||||
}
|
||||
}
|
||||
@ -127,60 +128,60 @@ export class ConfigDiagnostics {
|
||||
try {
|
||||
await ConfigDiagnostics.testThumbnailLib(Config.Server.thumbnail.processingLibrary);
|
||||
} catch (err) {
|
||||
NotificationManager.warning("Thumbnail hardware acceleration is not possible." +
|
||||
" '" + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + "' node module is not found." +
|
||||
" Falling back temporally to JS based thumbnail generation", err);
|
||||
Logger.warn(LOG_TAG, "[Thumbnail hardware acceleration] module error: ", err);
|
||||
Logger.warn(LOG_TAG, "Thumbnail hardware acceleration is not possible." +
|
||||
" '" + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + "' node module is not found." +
|
||||
" Falling back temporally to JS based thumbnail generation");
|
||||
NotificationManager.warning('Thumbnail hardware acceleration is not possible.' +
|
||||
' \'' + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + '\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation', err);
|
||||
Logger.warn(LOG_TAG, '[Thumbnail hardware acceleration] module error: ', err);
|
||||
Logger.warn(LOG_TAG, 'Thumbnail hardware acceleration is not possible.' +
|
||||
' \'' + ThumbnailProcessingLib[Config.Server.thumbnail.processingLibrary] + '\' node module is not found.' +
|
||||
' Falling back temporally to JS based thumbnail generation');
|
||||
Config.Server.thumbnail.processingLibrary = ThumbnailProcessingLib.Jimp;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testThumbnailFolder(Config.Server.thumbnail.folder)
|
||||
await ConfigDiagnostics.testThumbnailFolder(Config.Server.thumbnail.folder);
|
||||
} catch (err) {
|
||||
NotificationManager.error("Thumbnail folder error", err);
|
||||
Logger.error(LOG_TAG, "Thumbnail folder error", err);
|
||||
NotificationManager.error('Thumbnail folder error', err);
|
||||
Logger.error(LOG_TAG, 'Thumbnail folder error', err);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder)
|
||||
await ConfigDiagnostics.testImageFolder(Config.Server.imagesFolder);
|
||||
} catch (err) {
|
||||
NotificationManager.error("Images folder error", err);
|
||||
Logger.error(LOG_TAG, "Images folder error", err);
|
||||
NotificationManager.error('Images folder error', err);
|
||||
Logger.error(LOG_TAG, 'Images folder error', err);
|
||||
}
|
||||
try {
|
||||
await ConfigDiagnostics.testClientThumbnailConfig(Config.Client.Thumbnail)
|
||||
await ConfigDiagnostics.testClientThumbnailConfig(Config.Client.Thumbnail);
|
||||
} catch (err) {
|
||||
NotificationManager.error("Thumbnail settings error", err);
|
||||
Logger.error(LOG_TAG, "Thumbnail settings error", err);
|
||||
NotificationManager.error('Thumbnail settings error', err);
|
||||
Logger.error(LOG_TAG, 'Thumbnail settings error', err);
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testSearchConfig(Config.Client.Search, Config);
|
||||
} catch (err) {
|
||||
NotificationManager.warning("Search is not supported with these settings. Disabling temporally. Please adjust the config properly.", err);
|
||||
Logger.warn(LOG_TAG, "Search is not supported with these settings, switching off..", err);
|
||||
NotificationManager.warning('Search is not supported with these settings. Disabling temporally. Please adjust the config properly.', err);
|
||||
Logger.warn(LOG_TAG, 'Search is not supported with these settings, switching off..', err);
|
||||
Config.Client.Search.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testSharingConfig(Config.Client.Sharing, Config);
|
||||
} catch (err) {
|
||||
NotificationManager.warning("Sharing is not supported with these settings. Disabling temporally. Please adjust the config properly.", err);
|
||||
Logger.warn(LOG_TAG, "Sharing is not supported with these settings, switching off..", err);
|
||||
NotificationManager.warning('Sharing is not supported with these settings. Disabling temporally. Please adjust the config properly.', err);
|
||||
Logger.warn(LOG_TAG, 'Sharing is not supported with these settings, switching off..', err);
|
||||
Config.Client.Sharing.enabled = false;
|
||||
}
|
||||
|
||||
try {
|
||||
await ConfigDiagnostics.testMapConfig(Config.Client.Map);
|
||||
} catch (err) {
|
||||
NotificationManager.warning("Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.", err);
|
||||
Logger.warn(LOG_TAG, "Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.", err);
|
||||
NotificationManager.warning('Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.', err);
|
||||
Logger.warn(LOG_TAG, 'Maps is not supported with these settings. Disabling temporally. Please adjust the config properly.', err);
|
||||
Config.Client.Map.enabled = false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
///<reference path="exif.d.ts"/>
|
||||
import {DirectoryDTO} from "../../common/entities/DirectoryDTO";
|
||||
import {Logger} from "../Logger";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {DiskManagerTH} from "./threading/ThreadPool";
|
||||
import {DiskMangerWorker} from "./threading/DiskMangerWorker";
|
||||
import {DirectoryDTO} from '../../common/entities/DirectoryDTO';
|
||||
import {Logger} from '../Logger';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {DiskManagerTH} from './threading/ThreadPool';
|
||||
import {DiskMangerWorker} from './threading/DiskMangerWorker';
|
||||
|
||||
|
||||
const LOG_TAG = "[DiskManager]";
|
||||
const LOG_TAG = '[DiskManager]';
|
||||
|
||||
export class DiskManager {
|
||||
static threadPool: DiskManagerTH = null;
|
||||
|
||||
@ -17,7 +18,7 @@ export class DiskManager {
|
||||
}
|
||||
|
||||
public static async scanDirectory(relativeDirectoryName: string): Promise<DirectoryDTO> {
|
||||
Logger.silly(LOG_TAG, "scanning directory:", relativeDirectoryName);
|
||||
Logger.silly(LOG_TAG, 'scanning directory:', relativeDirectoryName);
|
||||
|
||||
|
||||
let directory: DirectoryDTO = null;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
|
||||
export class Localizations {
|
||||
|
||||
@ -12,7 +12,7 @@ export class Localizations {
|
||||
const notLanguage = ['assets'];
|
||||
const dirCont = fs.readdirSync(ProjectPath.FrontendFolder).filter(f => fs.statSync(path.resolve(ProjectPath.FrontendFolder, f)).isDirectory());
|
||||
Config.Client.languages = dirCont.filter(d => notLanguage.indexOf(d) == -1);
|
||||
Config.Client.languages.push("en");
|
||||
Config.Client.languages.push('en');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
import {NotificationDTO, NotificationType} from "../../common/entities/NotificationDTO";
|
||||
import {NotificationDTO, NotificationType} from '../../common/entities/NotificationDTO';
|
||||
|
||||
export class NotificationManager {
|
||||
public static notifications: NotificationDTO[] = [];
|
||||
public static HasNotification: NotificationDTO[] =
|
||||
[
|
||||
{
|
||||
type: NotificationType.info,
|
||||
message: "There are unhandled server notification. Login as Administrator to handle them."
|
||||
message: 'There are unhandled server notification. Login as Administrator to handle them.'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {IUserManager} from "./interfaces/IUserManager";
|
||||
import {IGalleryManager} from "./interfaces/IGalleryManager";
|
||||
import {ISearchManager} from "./interfaces/ISearchManager";
|
||||
import {SQLConnection} from "./sql/SQLConnection";
|
||||
import {ISharingManager} from "./interfaces/ISharingManager";
|
||||
import {Logger} from "../Logger";
|
||||
import {IIndexingManager} from "./interfaces/IIndexingManager";
|
||||
import {IUserManager} from './interfaces/IUserManager';
|
||||
import {IGalleryManager} from './interfaces/IGalleryManager';
|
||||
import {ISearchManager} from './interfaces/ISearchManager';
|
||||
import {SQLConnection} from './sql/SQLConnection';
|
||||
import {ISharingManager} from './interfaces/ISharingManager';
|
||||
import {Logger} from '../Logger';
|
||||
import {IIndexingManager} from './interfaces/IIndexingManager';
|
||||
|
||||
export class ObjectManagerRepository {
|
||||
|
||||
@ -70,11 +70,11 @@ export class ObjectManagerRepository {
|
||||
|
||||
public static async InitMemoryManagers() {
|
||||
await ObjectManagerRepository.reset();
|
||||
const GalleryManager = require("./memory/GalleryManager").GalleryManager;
|
||||
const UserManager = require("./memory/UserManager").UserManager;
|
||||
const SearchManager = require("./memory/SearchManager").SearchManager;
|
||||
const SharingManager = require("./memory/SharingManager").SharingManager;
|
||||
const IndexingManager = require("./memory/IndexingManager").IndexingManager;
|
||||
const GalleryManager = require('./memory/GalleryManager').GalleryManager;
|
||||
const UserManager = require('./memory/UserManager').UserManager;
|
||||
const SearchManager = require('./memory/SearchManager').SearchManager;
|
||||
const SharingManager = require('./memory/SharingManager').SharingManager;
|
||||
const IndexingManager = require('./memory/IndexingManager').IndexingManager;
|
||||
ObjectManagerRepository.getInstance().GalleryManager = new GalleryManager();
|
||||
ObjectManagerRepository.getInstance().UserManager = new UserManager();
|
||||
ObjectManagerRepository.getInstance().SearchManager = new SearchManager();
|
||||
@ -85,17 +85,17 @@ export class ObjectManagerRepository {
|
||||
public static async InitSQLManagers() {
|
||||
await ObjectManagerRepository.reset();
|
||||
await SQLConnection.init();
|
||||
const GalleryManager = require("./sql/GalleryManager").GalleryManager;
|
||||
const UserManager = require("./sql/UserManager").UserManager;
|
||||
const SearchManager = require("./sql/SearchManager").SearchManager;
|
||||
const SharingManager = require("./sql/SharingManager").SharingManager;
|
||||
const IndexingManager = require("./sql/IndexingManager").IndexingManager;
|
||||
const GalleryManager = require('./sql/GalleryManager').GalleryManager;
|
||||
const UserManager = require('./sql/UserManager').UserManager;
|
||||
const SearchManager = require('./sql/SearchManager').SearchManager;
|
||||
const SharingManager = require('./sql/SharingManager').SharingManager;
|
||||
const IndexingManager = require('./sql/IndexingManager').IndexingManager;
|
||||
ObjectManagerRepository.getInstance().GalleryManager = new GalleryManager();
|
||||
ObjectManagerRepository.getInstance().UserManager = new UserManager();
|
||||
ObjectManagerRepository.getInstance().SearchManager = new SearchManager();
|
||||
ObjectManagerRepository.getInstance().SharingManager = new SharingManager();
|
||||
ObjectManagerRepository.getInstance().IndexingManager = new IndexingManager();
|
||||
Logger.debug("SQL DB inited");
|
||||
Logger.debug('SQL DB inited');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
let bcrypt;
|
||||
try {
|
||||
bcrypt = require("bcrypt");
|
||||
bcrypt = require('bcrypt');
|
||||
} catch (err) {
|
||||
bcrypt = require("bcryptjs");
|
||||
bcrypt = require('bcryptjs');
|
||||
}
|
||||
|
||||
export class PasswordHelper {
|
||||
|
||||
11
backend/model/exif.d.ts
vendored
11
backend/model/exif.d.ts
vendored
@ -1,26 +1,31 @@
|
||||
declare module "node-iptc" {
|
||||
declare module 'node-iptc' {
|
||||
|
||||
function e(data): any;
|
||||
|
||||
module e {
|
||||
}
|
||||
|
||||
export = e;
|
||||
export = e;
|
||||
}
|
||||
|
||||
|
||||
declare module "exif-parser" {
|
||||
declare module 'exif-parser' {
|
||||
export interface ExifData {
|
||||
tags: any;
|
||||
imageSize: any;
|
||||
}
|
||||
|
||||
export interface ExifObject {
|
||||
enableTagNames(value: boolean);
|
||||
|
||||
enableImageSize(value: boolean);
|
||||
|
||||
enableReturnTags(value: boolean);
|
||||
|
||||
parse(): ExifData;
|
||||
|
||||
}
|
||||
|
||||
export function create(data: any): ExifObject;
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
|
||||
export interface IGalleryManager {
|
||||
listDirectory(relativeDirectoryName: string,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {IndexingProgressDTO} from "../../../common/entities/settings/IndexingProgressDTO";
|
||||
import {IndexingProgressDTO} from '../../../common/entities/settings/IndexingProgressDTO';
|
||||
|
||||
export interface IIndexingManager {
|
||||
startIndexing(): void;
|
||||
@ -7,5 +7,5 @@ export interface IIndexingManager {
|
||||
|
||||
cancelIndexing(): void;
|
||||
|
||||
reset(): Promise<void> ;
|
||||
reset(): Promise<void>;
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {SearchResultDTO} from "../../../common/entities/SearchResultDTO";
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
|
||||
export interface ISearchManager {
|
||||
autocomplete(text: string): Promise<AutoCompleteItem[]>;
|
||||
|
||||
search(text: string, searchType: SearchTypes): Promise<SearchResultDTO>;
|
||||
|
||||
instantSearch(text: string): Promise<SearchResultDTO>;
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import {SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
import {SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
|
||||
export interface ISharingManager {
|
||||
findOne(filter: any): Promise<SharingDTO>;
|
||||
|
||||
createSharing(sharing: SharingDTO): Promise<SharingDTO>;
|
||||
|
||||
updateSharing(sharing: SharingDTO): Promise<SharingDTO>;
|
||||
}
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
|
||||
export interface IUserManager {
|
||||
findOne(filter: any): Promise<UserDTO>;
|
||||
|
||||
find(filter: any): Promise<UserDTO[]>;
|
||||
|
||||
createUser(user: UserDTO): Promise<UserDTO>;
|
||||
|
||||
deleteUser(id: number): Promise<UserDTO>;
|
||||
|
||||
changeRole(id: number, newRole: UserRoles): Promise<UserDTO>;
|
||||
|
||||
changePassword(request: any): Promise<void>;
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {IGalleryManager} from "../interfaces/IGalleryManager";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {DiskManager} from "../DiskManger";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {ReIndexingSensitivity} from "../../../common/config/private/IPrivateConfig";
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {IGalleryManager} from '../interfaces/IGalleryManager';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {DiskManager} from '../DiskManger';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ReIndexingSensitivity} from '../../../common/config/private/IPrivateConfig';
|
||||
|
||||
export class GalleryManager implements IGalleryManager {
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
import {IIndexingManager} from "../interfaces/IIndexingManager";
|
||||
import {IndexingProgressDTO} from "../../../common/entities/settings/IndexingProgressDTO";
|
||||
import {IIndexingManager} from '../interfaces/IIndexingManager';
|
||||
import {IndexingProgressDTO} from '../../../common/entities/settings/IndexingProgressDTO';
|
||||
|
||||
export class IndexingManager implements IIndexingManager {
|
||||
|
||||
startIndexing(): void {
|
||||
throw new Error("not supported by memory DB");
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
getProgress(): IndexingProgressDTO {
|
||||
throw new Error("not supported by memory DB");
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
cancelIndexing(): void {
|
||||
throw new Error("not supported by memory DB");
|
||||
throw new Error('not supported by memory DB');
|
||||
}
|
||||
|
||||
reset(): Promise<void> {
|
||||
throw new Error("Method not implemented.");
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {ISearchManager} from "../interfaces/ISearchManager";
|
||||
import {SearchResultDTO} from "../../../common/entities/SearchResultDTO";
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {ISearchManager} from '../interfaces/ISearchManager';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
|
||||
export class SearchManager implements ISearchManager {
|
||||
autocomplete(text: string): Promise<AutoCompleteItem[]> {
|
||||
throw new Error("Method not implemented.");
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
search(text: string, searchType: SearchTypes): Promise<SearchResultDTO> {
|
||||
throw new Error("Method not implemented.");
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
instantSearch(text: string): Promise<SearchResultDTO> {
|
||||
throw new Error("Method not implemented.");
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
import {ISharingManager} from "../interfaces/ISharingManager";
|
||||
import {SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
import {ISharingManager} from '../interfaces/ISharingManager';
|
||||
import {SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
|
||||
export class SharingManager implements ISharingManager {
|
||||
|
||||
|
||||
findOne(filter: any): Promise<SharingDTO> {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
createSharing(sharing: SharingDTO): Promise<SharingDTO> {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
updateSharing(sharing: SharingDTO): Promise<SharingDTO> {
|
||||
throw new Error("not implemented");
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {IUserManager} from "../interfaces/IUserManager";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {PasswordHelper} from "../PasswordHelper";
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {IUserManager} from '../interfaces/IUserManager';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {PasswordHelper} from '../PasswordHelper';
|
||||
|
||||
|
||||
export class UserManager implements IUserManager {
|
||||
@ -28,14 +28,14 @@ export class UserManager implements IUserManager {
|
||||
}
|
||||
|
||||
if (!this.db.idCounter) {
|
||||
console.log("creating counter");
|
||||
console.log('creating counter');
|
||||
this.db.idCounter = 1;
|
||||
}
|
||||
|
||||
if (!this.db.users) {
|
||||
this.db.users = [];
|
||||
//TODO: remove defaults
|
||||
this.createUser(<UserDTO>{name: "admin", password: "admin", role: UserRoles.Admin});
|
||||
this.createUser(<UserDTO>{name: 'admin', password: 'admin', role: UserRoles.Admin});
|
||||
}
|
||||
this.saveDB();
|
||||
|
||||
@ -46,7 +46,7 @@ export class UserManager implements IUserManager {
|
||||
const result = await this.find(filter);
|
||||
|
||||
if (result.length == 0) {
|
||||
throw "UserDTO not found";
|
||||
throw 'UserDTO not found';
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
@ -97,7 +97,7 @@ export class UserManager implements IUserManager {
|
||||
}
|
||||
|
||||
public async changePassword(request: any) {
|
||||
throw new Error("not implemented"); //TODO: implement
|
||||
throw new Error('not implemented'); //TODO: implement
|
||||
}
|
||||
|
||||
private loadDB() {
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import {IGalleryManager} from "../interfaces/IGalleryManager";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {DirectoryEntity} from "./enitites/DirectoryEntity";
|
||||
import {SQLConnection} from "./SQLConnection";
|
||||
import {DiskManager} from "../DiskManger";
|
||||
import {PhotoEntity} from "./enitites/PhotoEntity";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {ISQLGalleryManager} from "./IGalleryManager";
|
||||
import {ReIndexingSensitivity} from "../../../common/config/private/IPrivateConfig";
|
||||
import {IGalleryManager} from '../interfaces/IGalleryManager';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {DiskManager} from '../DiskManger';
|
||||
import {PhotoEntity} from './enitites/PhotoEntity';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ISQLGalleryManager} from './IGalleryManager';
|
||||
import {ReIndexingSensitivity} from '../../../common/config/private/IPrivateConfig';
|
||||
|
||||
export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
|
||||
@ -18,7 +18,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
public async listDirectory(relativeDirectoryName: string,
|
||||
knownLastModified?: number,
|
||||
knownLastScanned?: number): Promise<DirectoryDTO> {
|
||||
relativeDirectoryName = path.normalize(path.join("." + path.sep, relativeDirectoryName));
|
||||
relativeDirectoryName = path.normalize(path.join('.' + path.sep, relativeDirectoryName));
|
||||
const directoryName = path.basename(relativeDirectoryName);
|
||||
const directoryParent = path.join(path.dirname(relativeDirectoryName), path.sep);
|
||||
const connection = await SQLConnection.getConnection();
|
||||
@ -26,13 +26,13 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
const lastModified = Math.max(stat.ctime.getTime(), stat.mtime.getTime());
|
||||
let dir = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("directory")
|
||||
.where("directory.name = :name AND directory.path = :path", {
|
||||
.createQueryBuilder('directory')
|
||||
.where('directory.name = :name AND directory.path = :path', {
|
||||
name: directoryName,
|
||||
path: directoryParent
|
||||
})
|
||||
.leftJoinAndSelect("directory.directories", "directories")
|
||||
.leftJoinAndSelect("directory.photos", "photos")
|
||||
.leftJoinAndSelect('directory.directories', 'directories')
|
||||
.leftJoinAndSelect('directory.photos', 'photos')
|
||||
.getOne();
|
||||
|
||||
|
||||
@ -61,11 +61,11 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
for (let i = 0; i < dir.directories.length; i++) {
|
||||
dir.directories[i].photos = await connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo")
|
||||
.where("photo.directory = :dir", {
|
||||
.createQueryBuilder('photo')
|
||||
.where('photo.directory = :dir', {
|
||||
dir: dir.directories[i].id
|
||||
})
|
||||
.orderBy("photo.metadata.creationDate", "ASC")
|
||||
.orderBy('photo.metadata.creationDate', 'ASC')
|
||||
.limit(Config.Server.indexing.folderPreviewSize)
|
||||
.getMany();
|
||||
dir.directories[i].isPartial = true;
|
||||
@ -85,7 +85,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
|
||||
//not indexed since a while, index it in a lazy manner
|
||||
if ((Date.now() - dir.lastScanned > Config.Server.indexing.cachedFolderTimeout &&
|
||||
Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) ||
|
||||
Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.medium) ||
|
||||
Config.Server.indexing.reIndexingSensitivity >= ReIndexingSensitivity.high) {
|
||||
//on the fly reindexing
|
||||
this.indexDirectory(relativeDirectoryName).catch((err) => {
|
||||
@ -132,8 +132,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
const photosRepository = connection.getRepository(PhotoEntity);
|
||||
|
||||
|
||||
let currentDir = await directoryRepository.createQueryBuilder("directory")
|
||||
.where("directory.name = :name AND directory.path = :path", {
|
||||
let currentDir = await directoryRepository.createQueryBuilder('directory')
|
||||
.where('directory.name = :name AND directory.path = :path', {
|
||||
name: scannedDirectory.name,
|
||||
path: scannedDirectory.path
|
||||
}).getOne();
|
||||
@ -147,8 +147,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
currentDir = await directoryRepository.save(<DirectoryEntity>scannedDirectory);
|
||||
}
|
||||
|
||||
let childDirectories = await directoryRepository.createQueryBuilder("directory")
|
||||
.where("directory.parent = :dir", {
|
||||
let childDirectories = await directoryRepository.createQueryBuilder('directory')
|
||||
.where('directory.parent = :dir', {
|
||||
dir: currentDir.id
|
||||
}).getMany();
|
||||
|
||||
@ -185,8 +185,8 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
|
||||
await directoryRepository.remove(childDirectories);
|
||||
|
||||
|
||||
let indexedPhotos = await photosRepository.createQueryBuilder("photo")
|
||||
.where("photo.directory = :dir", {
|
||||
let indexedPhotos = await photosRepository.createQueryBuilder('photo')
|
||||
.where('photo.directory = :dir', {
|
||||
dir: currentDir.id
|
||||
}).getMany();
|
||||
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import "reflect-metadata";
|
||||
import {Connection, ConnectionOptions, createConnection, getConnection} from "typeorm";
|
||||
import {UserEntity} from "./enitites/UserEntity";
|
||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {PhotoEntity} from "./enitites/PhotoEntity";
|
||||
import {DirectoryEntity} from "./enitites/DirectoryEntity";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {SharingEntity} from "./enitites/SharingEntity";
|
||||
import {DataBaseConfig, DatabaseType} from "../../../common/config/private/IPrivateConfig";
|
||||
import {PasswordHelper} from "../PasswordHelper";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {VersionEntity} from "./enitites/VersionEntity";
|
||||
import {Logger} from "../../Logger";
|
||||
import 'reflect-metadata';
|
||||
import {Connection, ConnectionOptions, createConnection, getConnection} from 'typeorm';
|
||||
import {UserEntity} from './enitites/UserEntity';
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {PhotoEntity} from './enitites/PhotoEntity';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {SharingEntity} from './enitites/SharingEntity';
|
||||
import {DataBaseConfig, DatabaseType} from '../../../common/config/private/IPrivateConfig';
|
||||
import {PasswordHelper} from '../PasswordHelper';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {VersionEntity} from './enitites/VersionEntity';
|
||||
import {Logger} from '../../Logger';
|
||||
|
||||
|
||||
export class SQLConnection {
|
||||
@ -27,7 +27,7 @@ export class SQLConnection {
|
||||
if (this.connection == null) {
|
||||
|
||||
let options: any = this.getDriver(Config.Server.database);
|
||||
options.name = "main";
|
||||
options.name = 'main';
|
||||
options.entities = [
|
||||
UserEntity,
|
||||
PhotoEntity,
|
||||
@ -46,11 +46,11 @@ export class SQLConnection {
|
||||
|
||||
public static async tryConnection(config: DataBaseConfig) {
|
||||
try {
|
||||
await getConnection("test").close();
|
||||
await getConnection('test').close();
|
||||
} catch (err) {
|
||||
}
|
||||
const options: any = this.getDriver(config);
|
||||
options.name = "test";
|
||||
options.name = 'test';
|
||||
options.entities = [
|
||||
UserEntity,
|
||||
PhotoEntity,
|
||||
@ -66,6 +66,20 @@ export class SQLConnection {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async init(): Promise<void> {
|
||||
const connection = await this.getConnection();
|
||||
let userRepository = connection.getRepository(UserEntity);
|
||||
let admins = await userRepository.find({role: UserRoles.Admin});
|
||||
if (admins.length == 0) {
|
||||
let a = new UserEntity();
|
||||
a.name = 'admin';
|
||||
a.password = PasswordHelper.cryptPassword('admin');
|
||||
a.role = UserRoles.Admin;
|
||||
await userRepository.save(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static async schemeSync(connection: Connection) {
|
||||
let version = null;
|
||||
try {
|
||||
@ -75,7 +89,7 @@ export class SQLConnection {
|
||||
if (version && version.version == SQLConnection.VERSION) {
|
||||
return;
|
||||
}
|
||||
Logger.info("Updating database scheme");
|
||||
Logger.info('Updating database scheme');
|
||||
if (!version) {
|
||||
version = new VersionEntity();
|
||||
}
|
||||
@ -87,25 +101,11 @@ export class SQLConnection {
|
||||
await connection.getRepository(VersionEntity).save(version);
|
||||
}
|
||||
|
||||
public static async init(): Promise<void> {
|
||||
const connection = await this.getConnection();
|
||||
let userRepository = connection.getRepository(UserEntity);
|
||||
let admins = await userRepository.find({role: UserRoles.Admin});
|
||||
if (admins.length == 0) {
|
||||
let a = new UserEntity();
|
||||
a.name = "admin";
|
||||
a.password = PasswordHelper.cryptPassword("admin");
|
||||
a.role = UserRoles.Admin;
|
||||
await userRepository.save(a);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static getDriver(config: DataBaseConfig): ConnectionOptions {
|
||||
let driver: ConnectionOptions = null;
|
||||
if (config.type == DatabaseType.mysql) {
|
||||
driver = {
|
||||
type: "mysql",
|
||||
type: 'mysql',
|
||||
host: config.mysql.host,
|
||||
port: 3306,
|
||||
username: config.mysql.username,
|
||||
@ -114,7 +114,7 @@ export class SQLConnection {
|
||||
};
|
||||
} else if (config.type == DatabaseType.sqlite) {
|
||||
driver = {
|
||||
type: "sqlite",
|
||||
type: 'sqlite',
|
||||
database: ProjectPath.getAbsolutePath(config.sqlite.storage)
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {ISearchManager} from "../interfaces/ISearchManager";
|
||||
import {SearchResultDTO} from "../../../common/entities/SearchResultDTO";
|
||||
import {SQLConnection} from "./SQLConnection";
|
||||
import {PhotoEntity} from "./enitites/PhotoEntity";
|
||||
import {DirectoryEntity} from "./enitites/DirectoryEntity";
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {ISearchManager} from '../interfaces/ISearchManager';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {PhotoEntity} from './enitites/PhotoEntity';
|
||||
import {DirectoryEntity} from './enitites/DirectoryEntity';
|
||||
|
||||
export class SearchManager implements ISearchManager {
|
||||
|
||||
@ -31,10 +31,10 @@ export class SearchManager implements ISearchManager {
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.metadata.keywords)')
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.limit(5)
|
||||
.getRawMany())
|
||||
.map(r => <Array<string>>r.metadataKeywords.split(","))
|
||||
.map(r => <Array<string>>r.metadataKeywords.split(','))
|
||||
.forEach(keywords => {
|
||||
result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword));
|
||||
});
|
||||
@ -43,14 +43,14 @@ export class SearchManager implements ISearchManager {
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('photo.metadata.positionData.country as country, photo.metadata.positionData.state as state, photo.metadata.positionData.city as city')
|
||||
.where('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.where('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.groupBy('photo.metadata.positionData.country, photo.metadata.positionData.state, photo.metadata.positionData.city')
|
||||
.limit(5)
|
||||
.getRawMany())
|
||||
.filter(pm => !!pm)
|
||||
.map(pm => <Array<string>>[pm.city || "", pm.country || "", pm.state || ""])
|
||||
.map(pm => <Array<string>>[pm.city || '', pm.country || '', pm.state || ''])
|
||||
.forEach(positions => {
|
||||
result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position));
|
||||
});
|
||||
@ -58,7 +58,7 @@ export class SearchManager implements ISearchManager {
|
||||
result = result.concat(this.encapsulateAutoComplete((await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.name)')
|
||||
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.limit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.image));
|
||||
@ -66,7 +66,7 @@ export class SearchManager implements ISearchManager {
|
||||
result = result.concat(this.encapsulateAutoComplete((await directoryRepository
|
||||
.createQueryBuilder('dir')
|
||||
.select('DISTINCT(dir.name)')
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.limit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.directory));
|
||||
@ -88,27 +88,27 @@ export class SearchManager implements ISearchManager {
|
||||
|
||||
let query = connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo")
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.orderBy("photo.metadata.creationDate", "ASC");
|
||||
.createQueryBuilder('photo')
|
||||
.innerJoinAndSelect('photo.directory', 'directory')
|
||||
.orderBy('photo.metadata.creationDate', 'ASC');
|
||||
|
||||
|
||||
if (!searchType || searchType === SearchTypes.directory) {
|
||||
query.orWhere('directory.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
query.orWhere('directory.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'});
|
||||
}
|
||||
|
||||
if (!searchType || searchType === SearchTypes.image) {
|
||||
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'});
|
||||
}
|
||||
|
||||
if (!searchType || searchType === SearchTypes.position) {
|
||||
query.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
query.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'});
|
||||
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.keyword) {
|
||||
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'});
|
||||
}
|
||||
|
||||
result.photos = await query
|
||||
@ -121,8 +121,8 @@ export class SearchManager implements ISearchManager {
|
||||
|
||||
result.directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.createQueryBuilder('dir')
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.limit(201)
|
||||
.getMany();
|
||||
|
||||
@ -146,22 +146,22 @@ export class SearchManager implements ISearchManager {
|
||||
|
||||
result.photos = await connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo")
|
||||
.orderBy("photo.metadata.creationDate", "ASC")
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.createQueryBuilder('photo')
|
||||
.orderBy('photo.metadata.creationDate', 'ASC')
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.country LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.state LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.metadata.positionData.city LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.innerJoinAndSelect('photo.directory', 'directory')
|
||||
.limit(10)
|
||||
.getMany();
|
||||
|
||||
|
||||
result.directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.createQueryBuilder('dir')
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: '%' + text + '%'})
|
||||
.limit(10)
|
||||
.getMany();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {ISharingManager} from "../interfaces/ISharingManager";
|
||||
import {SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
import {SQLConnection} from "./SQLConnection";
|
||||
import {SharingEntity} from "./enitites/SharingEntity";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {PasswordHelper} from "../PasswordHelper";
|
||||
import {ISharingManager} from '../interfaces/ISharingManager';
|
||||
import {SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {SharingEntity} from './enitites/SharingEntity';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {PasswordHelper} from '../PasswordHelper';
|
||||
|
||||
export class SharingManager implements ISharingManager {
|
||||
|
||||
@ -11,8 +11,8 @@ export class SharingManager implements ISharingManager {
|
||||
const connection = await SQLConnection.getConnection();
|
||||
return connection
|
||||
.getRepository(SharingEntity)
|
||||
.createQueryBuilder("share")
|
||||
.where("expires < :now", {now: Date.now()})
|
||||
.createQueryBuilder('share')
|
||||
.where('expires < :now', {now: Date.now()})
|
||||
.delete()
|
||||
.execute();
|
||||
}
|
||||
@ -42,7 +42,7 @@ export class SharingManager implements ISharingManager {
|
||||
});
|
||||
|
||||
if (sharing.timeStamp < Date.now() - Config.Server.sharing.updateTimeout) {
|
||||
throw "Sharing is locked, can't update anymore"
|
||||
throw 'Sharing is locked, can\'t update anymore';
|
||||
}
|
||||
if (inSharing.password == null) {
|
||||
sharing.password = null;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
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 {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {IUserManager} from '../interfaces/IUserManager';
|
||||
import {UserEntity} from './enitites/UserEntity';
|
||||
import {SQLConnection} from './SQLConnection';
|
||||
import {PasswordHelper} from '../PasswordHelper';
|
||||
|
||||
|
||||
export class UserManager implements IUserManager {
|
||||
@ -22,7 +22,7 @@ export class UserManager implements IUserManager {
|
||||
}
|
||||
|
||||
if (pass && !PasswordHelper.comparePassword(pass, user.password)) {
|
||||
throw "No entry found";
|
||||
throw 'No entry found';
|
||||
}
|
||||
return user;
|
||||
|
||||
@ -64,7 +64,7 @@ export class UserManager implements IUserManager {
|
||||
}
|
||||
|
||||
public async changePassword(request: any) {
|
||||
throw new Error("not implemented"); //TODO: implement
|
||||
throw new Error('not implemented'); //TODO: implement
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
||||
import {PhotoEntity} from "./PhotoEntity";
|
||||
import {Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from 'typeorm';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {PhotoEntity} from './PhotoEntity';
|
||||
|
||||
@Entity()
|
||||
export class DirectoryEntity implements DirectoryDTO {
|
||||
@ -23,12 +23,12 @@ export class DirectoryEntity implements DirectoryDTO {
|
||||
/**
|
||||
* Last time the directory was fully scanned, not only for a few photos to create a preview
|
||||
*/
|
||||
@Column({type: "bigint", nullable: true})
|
||||
@Column({type: 'bigint', nullable: true})
|
||||
public lastScanned: number;
|
||||
|
||||
isPartial?: boolean;
|
||||
|
||||
@ManyToOne(type => DirectoryEntity, directory => directory.directories, {onDelete: "CASCADE"})
|
||||
@ManyToOne(type => DirectoryEntity, directory => directory.directories, {onDelete: 'CASCADE'})
|
||||
public parent: DirectoryEntity;
|
||||
|
||||
@OneToMany(type => DirectoryEntity, dir => dir.parent)
|
||||
|
||||
@ -1,37 +1,30 @@
|
||||
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {
|
||||
CameraMetadata,
|
||||
GPSMetadata,
|
||||
ImageSize,
|
||||
PhotoDTO,
|
||||
PhotoMetadata,
|
||||
PositionMetaData
|
||||
} from "../../../../common/entities/PhotoDTO";
|
||||
import {DirectoryEntity} from "./DirectoryEntity";
|
||||
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm';
|
||||
import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata, PositionMetaData} from '../../../../common/entities/PhotoDTO';
|
||||
import {DirectoryEntity} from './DirectoryEntity';
|
||||
|
||||
|
||||
@Entity()
|
||||
export class CameraMetadataEntity implements CameraMetadata {
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
ISO: number;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
model: string;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
maker: string;
|
||||
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
fStop: number;
|
||||
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
exposure: number;
|
||||
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
focalLength: number;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
lens: string;
|
||||
}
|
||||
|
||||
@ -39,21 +32,21 @@ export class CameraMetadataEntity implements CameraMetadata {
|
||||
@Entity()
|
||||
export class GPSMetadataEntity implements GPSMetadata {
|
||||
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
latitude: number;
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
longitude: number;
|
||||
@Column("int", {nullable: true})
|
||||
@Column('int', {nullable: true})
|
||||
altitude: number;
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class ImageSizeEntity implements ImageSize {
|
||||
|
||||
@Column("int")
|
||||
@Column('int')
|
||||
width: number;
|
||||
|
||||
@Column("int")
|
||||
@Column('int')
|
||||
height: number;
|
||||
}
|
||||
|
||||
@ -64,13 +57,13 @@ export class PositionMetaDataEntity implements PositionMetaData {
|
||||
@Column(type => GPSMetadataEntity)
|
||||
GPSData: GPSMetadataEntity;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
country: string;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
state: string;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
city: string;
|
||||
}
|
||||
|
||||
@ -78,7 +71,7 @@ export class PositionMetaDataEntity implements PositionMetaData {
|
||||
@Entity()
|
||||
export class PhotoMetadataEntity implements PhotoMetadata {
|
||||
|
||||
@Column("simple-array")
|
||||
@Column('simple-array')
|
||||
keywords: Array<string>;
|
||||
|
||||
@Column(type => CameraMetadataEntity)
|
||||
@ -90,10 +83,10 @@ export class PhotoMetadataEntity implements PhotoMetadata {
|
||||
@Column(type => ImageSizeEntity)
|
||||
size: ImageSizeEntity;
|
||||
|
||||
@Column("bigint")
|
||||
@Column('bigint')
|
||||
creationDate: number;
|
||||
|
||||
@Column("int")
|
||||
@Column('int')
|
||||
fileSize: number;
|
||||
}
|
||||
|
||||
@ -104,10 +97,10 @@ export class PhotoEntity implements PhotoDTO {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column("text")
|
||||
@Column('text')
|
||||
name: string;
|
||||
|
||||
@ManyToOne(type => DirectoryEntity, directory => directory.photos, {onDelete: "CASCADE"})
|
||||
@ManyToOne(type => DirectoryEntity, directory => directory.photos, {onDelete: 'CASCADE'})
|
||||
directory: DirectoryEntity;
|
||||
|
||||
@Column(type => PhotoMetadataEntity)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {SharingDTO} from "../../../../common/entities/SharingDTO";
|
||||
import {UserEntity} from "./UserEntity";
|
||||
import {UserDTO} from "../../../../common/entities/UserDTO";
|
||||
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm';
|
||||
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {UserEntity} from './UserEntity';
|
||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||
|
||||
@Entity()
|
||||
export class SharingEntity implements SharingDTO {
|
||||
@ -14,7 +14,7 @@ export class SharingEntity implements SharingDTO {
|
||||
@Column()
|
||||
path: string;
|
||||
|
||||
@Column({type: "text", nullable: true})
|
||||
@Column({type: 'text', nullable: true})
|
||||
password: string;
|
||||
|
||||
@Column()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {UserDTO, UserRoles} from "../../../../common/entities/UserDTO";
|
||||
import {Column, Entity, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {UserDTO, UserRoles} from '../../../../common/entities/UserDTO';
|
||||
import {Column, Entity, PrimaryGeneratedColumn} from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
export class UserEntity implements UserDTO {
|
||||
@ -13,10 +13,10 @@ export class UserEntity implements UserDTO {
|
||||
@Column()
|
||||
password: string;
|
||||
|
||||
@Column("smallint")
|
||||
@Column('smallint')
|
||||
role: UserRoles;
|
||||
|
||||
@Column("text", {nullable: true})
|
||||
@Column('text', {nullable: true})
|
||||
permissions: string[];
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {Column, Entity, PrimaryGeneratedColumn} from "typeorm";
|
||||
import {Column, Entity, PrimaryGeneratedColumn} from 'typeorm';
|
||||
|
||||
@Entity()
|
||||
export class VersionEntity {
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata} from "../../../common/entities/PhotoDTO";
|
||||
import {Logger} from "../../Logger";
|
||||
import {IptcParser} from "ts-node-iptc";
|
||||
import {ExifParserFactory} from "ts-exif-parser";
|
||||
import {ProjectPath} from "../../ProjectPath";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {CameraMetadata, GPSMetadata, ImageSize, PhotoDTO, PhotoMetadata} from '../../../common/entities/PhotoDTO';
|
||||
import {Logger} from '../../Logger';
|
||||
import {IptcParser} from 'ts-node-iptc';
|
||||
import {ExifParserFactory} from 'ts-exif-parser';
|
||||
import {ProjectPath} from '../../ProjectPath';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
|
||||
const LOG_TAG = "[DiskManagerTask]";
|
||||
const LOG_TAG = '[DiskManagerTask]';
|
||||
|
||||
export class DiskMangerWorker {
|
||||
private static isImage(fullPath: string) {
|
||||
@ -139,7 +139,7 @@ export class DiskMangerWorker {
|
||||
metadata.size = <ImageSize> {width: 1, height: 1};
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.debug(LOG_TAG, "Error parsing exif", fullPath, err);
|
||||
Logger.debug(LOG_TAG, 'Error parsing exif', fullPath, err);
|
||||
metadata.size = <ImageSize> {width: 1, height: 1};
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {RendererInput, ThumbnailWoker} from "./ThumbnailWoker";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {RendererInput, ThumbnailWoker} from './ThumbnailWoker';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
|
||||
|
||||
interface QueTask {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import * as cluster from "cluster";
|
||||
import {Logger} from "../../Logger";
|
||||
import {DiskManagerTask, ThumbnailTask, WorkerMessage, WorkerTask, WorkerTaskTypes} from "./Worker";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {RendererInput} from "./ThumbnailWoker";
|
||||
import {Config} from "../../../common/config/private/Config";
|
||||
import {ITaskQue} from "./TaskQue";
|
||||
import * as cluster from 'cluster';
|
||||
import {Logger} from '../../Logger';
|
||||
import {DiskManagerTask, ThumbnailTask, WorkerMessage, WorkerTask, WorkerTaskTypes} from './Worker';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {RendererInput} from './ThumbnailWoker';
|
||||
import {Config} from '../../../common/config/private/Config';
|
||||
import {ITaskQue} from './TaskQue';
|
||||
|
||||
|
||||
interface PoolTask {
|
||||
@ -24,7 +24,7 @@ export class ThreadPool {
|
||||
private tasks: PoolTask[] = [];
|
||||
|
||||
constructor(private size: number) {
|
||||
Logger.silly("Creating thread pool with", size, "workers");
|
||||
Logger.silly('Creating thread pool with', size, 'workers');
|
||||
for (let i = 0; i < size; i++) {
|
||||
this.startWorker();
|
||||
}
|
||||
@ -39,14 +39,14 @@ export class ThreadPool {
|
||||
});
|
||||
worker.worker.on('exit', (code, signal) => {
|
||||
ThreadPool.WorkerCount--;
|
||||
Logger.warn('Worker ' + worker.worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal + ", worker count:", ThreadPool.WorkerCount);
|
||||
Logger.warn('Worker ' + worker.worker.process.pid + ' died with code: ' + code + ', and signal: ' + signal + ', worker count:', ThreadPool.WorkerCount);
|
||||
Logger.debug('Starting a new worker');
|
||||
this.startWorker();
|
||||
});
|
||||
|
||||
worker.worker.on("message", (msg: WorkerMessage) => {
|
||||
worker.worker.on('message', (msg: WorkerMessage) => {
|
||||
if (worker.poolTask == null) {
|
||||
throw "No worker task after worker task is completed"
|
||||
throw 'No worker task after worker task is completed';
|
||||
}
|
||||
if (msg.error) {
|
||||
worker.poolTask.promise.reject(msg.error);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Metadata, SharpInstance} from "sharp";
|
||||
import {Dimensions, State} from "gm";
|
||||
import {Logger} from "../../Logger";
|
||||
import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig";
|
||||
import {Metadata, SharpInstance} from 'sharp';
|
||||
import {Dimensions, State} from 'gm';
|
||||
import {Logger} from '../../Logger';
|
||||
import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
||||
|
||||
export class ThumbnailWoker {
|
||||
|
||||
@ -39,14 +39,14 @@ export class RendererFactory {
|
||||
case ThumbnailProcessingLib.sharp:
|
||||
return RendererFactory.Sharp();
|
||||
}
|
||||
throw "unknown renderer"
|
||||
throw 'unknown renderer';
|
||||
}
|
||||
|
||||
public static Jimp() {
|
||||
const Jimp = require("jimp");
|
||||
const Jimp = require('jimp');
|
||||
return async (input: RendererInput): Promise<void> => {
|
||||
//generate thumbnail
|
||||
Logger.silly("[JimpThRenderer] rendering thumbnail:", input.imagePath);
|
||||
Logger.silly('[JimpThRenderer] rendering thumbnail:', input.imagePath);
|
||||
const image = await Jimp.read(input.imagePath);
|
||||
/**
|
||||
* newWidth * newHeight = size*size
|
||||
@ -83,10 +83,10 @@ export class RendererFactory {
|
||||
|
||||
|
||||
public static Sharp() {
|
||||
const sharp = require("sharp");
|
||||
const sharp = require('sharp');
|
||||
return async (input: RendererInput): Promise<void> => {
|
||||
|
||||
Logger.silly("[SharpThRenderer] rendering thumbnail:", input.imagePath);
|
||||
Logger.silly('[SharpThRenderer] rendering thumbnail:', input.imagePath);
|
||||
const image: SharpInstance = sharp(input.imagePath);
|
||||
const metadata: Metadata = await image.metadata();
|
||||
|
||||
@ -120,10 +120,10 @@ export class RendererFactory {
|
||||
|
||||
|
||||
public static Gm() {
|
||||
const gm = require("gm");
|
||||
const gm = require('gm');
|
||||
return (input: RendererInput): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Logger.silly("[GMThRenderer] rendering thumbnail:", input.imagePath);
|
||||
Logger.silly('[GMThRenderer] rendering thumbnail:', input.imagePath);
|
||||
let image: State = gm(input.imagePath);
|
||||
image.size((err, value: Dimensions) => {
|
||||
if (err) {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import {DiskMangerWorker} from "./DiskMangerWorker";
|
||||
import {Logger} from "../../Logger";
|
||||
import {RendererInput, ThumbnailWoker} from "./ThumbnailWoker";
|
||||
import {ThumbnailProcessingLib} from "../../../common/config/private/IPrivateConfig";
|
||||
import {DiskMangerWorker} from './DiskMangerWorker';
|
||||
import {Logger} from '../../Logger';
|
||||
import {RendererInput, ThumbnailWoker} from './ThumbnailWoker';
|
||||
import {ThumbnailProcessingLib} from '../../../common/config/private/IPrivateConfig';
|
||||
|
||||
export class Worker {
|
||||
|
||||
|
||||
public static process() {
|
||||
Logger.debug("Worker is waiting for tasks");
|
||||
Logger.debug('Worker is waiting for tasks');
|
||||
process.on('message', async (task: WorkerTask) => {
|
||||
try {
|
||||
let result = null;
|
||||
@ -22,8 +22,8 @@ export class Worker {
|
||||
result = await ThumbnailWoker.render((<ThumbnailTask>task).input, (<ThumbnailTask>task).renderer);
|
||||
break;
|
||||
default:
|
||||
Logger.error("Unknown worker task type");
|
||||
throw "Unknown worker task type";
|
||||
Logger.error('Unknown worker task type');
|
||||
throw 'Unknown worker task type';
|
||||
}
|
||||
process.send(<WorkerMessage>{
|
||||
error: null,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {AdminMWs} from "../middlewares/AdminMWs";
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {AdminMWs} from '../middlewares/AdminMWs';
|
||||
|
||||
export class AdminRouter {
|
||||
public static route(app: any) {
|
||||
@ -12,98 +12,97 @@ export class AdminRouter {
|
||||
|
||||
|
||||
private static addIndexGallery(app) {
|
||||
app.get("/api/admin/indexes/job/progress",
|
||||
app.get('/api/admin/indexes/job/progress',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.getIndexingProgress,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
app.put("/api/admin/indexes/job",
|
||||
app.put('/api/admin/indexes/job',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.startIndexing,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
app.delete("/api/admin/indexes/job",
|
||||
app.delete('/api/admin/indexes/job',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.cancelIndexing,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
app.delete("/api/admin/indexes",
|
||||
app.delete('/api/admin/indexes',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.resetIndexes,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addSettings(app) {
|
||||
app.get("/api/settings",
|
||||
app.get('/api/settings',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
RenderingMWs.renderConfig
|
||||
);
|
||||
|
||||
|
||||
app.put("/api/settings/database",
|
||||
app.put('/api/settings/database',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateDatabaseSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
app.put("/api/settings/map",
|
||||
app.put('/api/settings/map',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateMapSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
app.put("/api/settings/authentication",
|
||||
app.put('/api/settings/authentication',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateAuthenticationSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/thumbnail",
|
||||
app.put('/api/settings/thumbnail',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateThumbnailSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/search",
|
||||
app.put('/api/settings/search',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateSearchSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/share",
|
||||
app.put('/api/settings/share',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateShareSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/basic",
|
||||
app.put('/api/settings/basic',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateBasicSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/other",
|
||||
app.put('/api/settings/other',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateOtherSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
app.put("/api/settings/indexing",
|
||||
app.put('/api/settings/indexing',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
AdminMWs.updateIndexingSettings,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {ErrorCodes, ErrorDTO} from "../../common/entities/Error";
|
||||
import {Logger} from "../Logger";
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {ErrorCodes, ErrorDTO} from '../../common/entities/Error';
|
||||
import {Logger} from '../Logger';
|
||||
import Request = Express.Request;
|
||||
import Response = Express.Response;
|
||||
|
||||
@ -12,17 +12,17 @@ export class ErrorRouter {
|
||||
}
|
||||
|
||||
private static addApiErrorHandler(app) {
|
||||
app.use("/api/*",
|
||||
app.use('/api/*',
|
||||
RenderingMWs.renderError
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addGenericHandler(app) {
|
||||
app.use((err: any, req: Request, res: Response, next: Function) => {
|
||||
//Flush out the stack to the console
|
||||
Logger.error("Unexpected error:");
|
||||
// Flush out the stack to the console
|
||||
Logger.error('Unexpected error:');
|
||||
console.error(err);
|
||||
next(new ErrorDTO(ErrorCodes.SERVER_ERROR, "Unknown server side error", err));
|
||||
next(new ErrorDTO(ErrorCodes.SERVER_ERROR, 'Unknown server side error', err));
|
||||
},
|
||||
RenderingMWs.renderError
|
||||
);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {GalleryMWs} from "../middlewares/GalleryMWs";
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {ThumbnailGeneratorMWs} from "../middlewares/thumbnail/ThumbnailGeneratorMWs";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {GalleryMWs} from '../middlewares/GalleryMWs';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {ThumbnailGeneratorMWs} from '../middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
|
||||
export class GalleryRouter {
|
||||
public static route(app: any) {
|
||||
@ -18,7 +18,7 @@ export class GalleryRouter {
|
||||
}
|
||||
|
||||
private static addDirectoryList(app) {
|
||||
app.get(["/api/gallery/content/:directory(*)", "/api/gallery/", "/api/gallery//"],
|
||||
app.get(['/api/gallery/content/:directory(*)', '/api/gallery/', '/api/gallery//'],
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authoriseDirectory,
|
||||
GalleryMWs.listDirectory,
|
||||
@ -26,40 +26,40 @@ export class GalleryRouter {
|
||||
GalleryMWs.removeCyclicDirectoryReferences,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static addGetImage(app) {
|
||||
app.get(["/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"],
|
||||
app.get(['/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))'],
|
||||
AuthenticationMWs.authenticate,
|
||||
//TODO: authorize path
|
||||
// TODO: authorize path
|
||||
GalleryMWs.loadImage,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addGetImageThumbnail(app) {
|
||||
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?",
|
||||
app.get('/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?',
|
||||
AuthenticationMWs.authenticate,
|
||||
//TODO: authorize path
|
||||
// TODO: authorize path
|
||||
GalleryMWs.loadImage,
|
||||
ThumbnailGeneratorMWs.generateThumbnail,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addGetImageIcon(app) {
|
||||
app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon",
|
||||
app.get('/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon',
|
||||
AuthenticationMWs.authenticate,
|
||||
//TODO: authorize path
|
||||
// TODO: authorize path
|
||||
GalleryMWs.loadImage,
|
||||
ThumbnailGeneratorMWs.generateIcon,
|
||||
RenderingMWs.renderFile
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addSearch(app) {
|
||||
app.get("/api/search/:text",
|
||||
app.get('/api/search/:text',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
GalleryMWs.search,
|
||||
@ -67,10 +67,10 @@ export class GalleryRouter {
|
||||
GalleryMWs.removeCyclicDirectoryReferences,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addInstantSearch(app) {
|
||||
app.get("/api/instant-search/:text",
|
||||
app.get('/api/instant-search/:text',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
GalleryMWs.instantSearch,
|
||||
@ -78,16 +78,15 @@ export class GalleryRouter {
|
||||
GalleryMWs.removeCyclicDirectoryReferences,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addAutoComplete(app) {
|
||||
app.get("/api/autocomplete/:text",
|
||||
app.get('/api/autocomplete/:text',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
GalleryMWs.autocomplete,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Logger} from "../Logger";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import {Logger} from '../Logger';
|
||||
|
||||
/**
|
||||
* Adds logging to express
|
||||
@ -7,32 +7,32 @@ import {Logger} from "../Logger";
|
||||
export class LoggerRouter {
|
||||
public static route(app: any) {
|
||||
|
||||
app.get("/api*", (req: Request, res: Response, next: NextFunction) => {
|
||||
app.get('/api*', (req: Request, res: Response, next: NextFunction) => {
|
||||
req['_startTime'] = Date.now();
|
||||
req['logged'] = true;
|
||||
const end = res.end;
|
||||
res.end = (a?: any, b?: any, c?: any) => {
|
||||
res.end = end;
|
||||
res.end(a, b, c);
|
||||
Logger.verbose(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms");
|
||||
Logger.verbose(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms');
|
||||
};
|
||||
return next();
|
||||
});
|
||||
|
||||
app.get("/node_modules*", (req: Request, res: Response, next: NextFunction) => {
|
||||
app.get('/node_modules*', (req: Request, res: Response, next: NextFunction) => {
|
||||
req['_startTime'] = Date.now();
|
||||
req['logged'] = true;
|
||||
const end = res.end;
|
||||
res.end = (a?: any, b?: any, c?: any) => {
|
||||
res.end = end;
|
||||
res.end(a, b, c);
|
||||
Logger.silly(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms");
|
||||
Logger.silly(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms');
|
||||
};
|
||||
return next();
|
||||
});
|
||||
|
||||
app.use((req: Request, res: Response, next: NextFunction) => {
|
||||
if (req['logged'] == true) {
|
||||
if (req['logged'] === true) {
|
||||
return next();
|
||||
}
|
||||
req['_startTime'] = Date.now();
|
||||
@ -40,7 +40,7 @@ export class LoggerRouter {
|
||||
res.end = (a?: any, b?: any, c?: any) => {
|
||||
res.end = end;
|
||||
res.end(a, b, c);
|
||||
Logger.debug(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + "ms");
|
||||
Logger.debug(req.method, req.url, res.statusCode, (Date.now() - req['_startTime']) + 'ms');
|
||||
};
|
||||
return next();
|
||||
});
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {NotificationMWs} from "../middlewares/NotificationMWs";
|
||||
import Request = Express.Request;
|
||||
import Response = Express.Response;
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {NotificationMWs} from '../middlewares/NotificationMWs';
|
||||
|
||||
export class NotificationRouter {
|
||||
public static route(app: any) {
|
||||
@ -12,13 +10,12 @@ export class NotificationRouter {
|
||||
}
|
||||
|
||||
private static addGetNotifications(app) {
|
||||
app.get("/api/notifications",
|
||||
app.get('/api/notifications',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Guest),
|
||||
NotificationMWs.list,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
import {Utils} from "../../common/Utils";
|
||||
import {Config} from "../../common/config/private/Config";
|
||||
import {ProjectPath} from "../ProjectPath";
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {CookieNames} from "../../common/CookieNames";
|
||||
import {NextFunction, Request, Response} from 'express';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import {Utils} from '../../common/Utils';
|
||||
import {Config} from '../../common/config/private/Config';
|
||||
import {ProjectPath} from '../ProjectPath';
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {CookieNames} from '../../common/CookieNames';
|
||||
|
||||
|
||||
export class PublicRouter {
|
||||
|
||||
public static route(app) {
|
||||
const setLocale = (req: Request, res: Response, next: Function) => {
|
||||
let localePath = "";
|
||||
let localePath = '';
|
||||
let selectedLocale = req['locale'];
|
||||
if (req.cookies && req.cookies[CookieNames.lang]) {
|
||||
if (Config.Client.languages.indexOf(req.cookies[CookieNames.lang]) !== -1) {
|
||||
@ -37,7 +37,7 @@ export class PublicRouter {
|
||||
if (Config.Client.languages.indexOf(locale) !== -1) {
|
||||
res.cookie(CookieNames.lang, locale);
|
||||
}
|
||||
res.redirect("/?ln=" + locale);
|
||||
res.redirect('/?ln=' + locale);
|
||||
};
|
||||
};
|
||||
|
||||
@ -47,7 +47,7 @@ export class PublicRouter {
|
||||
|
||||
res.tpl.user = null;
|
||||
if (req.session.user) {
|
||||
let user = Utils.clone(req.session.user);
|
||||
const user = Utils.clone(req.session.user);
|
||||
delete user.password;
|
||||
res.tpl.user = user;
|
||||
}
|
||||
@ -60,13 +60,13 @@ export class PublicRouter {
|
||||
res.render(path.resolve(ProjectPath.FrontendFolder, 'config_inject.ejs'), res.tpl);
|
||||
});
|
||||
|
||||
app.get(['/', '/login', "/gallery*", "/share*", "/admin", "/search*"],
|
||||
app.get(['/', '/login', '/gallery*', '/share*', '/admin', '/search*'],
|
||||
AuthenticationMWs.tryAuthenticate,
|
||||
setLocale,
|
||||
renderIndex
|
||||
);
|
||||
Config.Client.languages.forEach(l => {
|
||||
app.get(['/' + l + '/', '/' + l + '/login', '/' + l + "/gallery*", '/' + l + "/share*", '/' + l + "/admin", '/' + l + "/search*"],
|
||||
app.get(['/' + l + '/', '/' + l + '/login', '/' + l + '/gallery*', '/' + l + '/share*', '/' + l + '/admin', '/' + l + '/search*'],
|
||||
redirectToBase(l)
|
||||
);
|
||||
});
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {SharingMWs} from "../middlewares/SharingMWs";
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
import {SharingMWs} from '../middlewares/SharingMWs';
|
||||
|
||||
export class SharingRouter {
|
||||
public static route(app: any) {
|
||||
@ -13,7 +13,7 @@ export class SharingRouter {
|
||||
}
|
||||
|
||||
private static addShareLogin(app) {
|
||||
app.post("/api/share/login",
|
||||
app.post('/api/share/login',
|
||||
AuthenticationMWs.inverseAuthenticate,
|
||||
AuthenticationMWs.shareLogin,
|
||||
RenderingMWs.renderSessionUser
|
||||
@ -21,7 +21,7 @@ export class SharingRouter {
|
||||
};
|
||||
|
||||
private static addGetSharing(app) {
|
||||
app.get("/api/share/:sharingKey",
|
||||
app.get('/api/share/:sharingKey',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.LimitedGuest),
|
||||
SharingMWs.getSharing,
|
||||
@ -30,7 +30,7 @@ export class SharingRouter {
|
||||
};
|
||||
|
||||
private static addCreateSharing(app) {
|
||||
app.post(["/api/share/:directory(*)", "/api/share/", "/api/share//"],
|
||||
app.post(['/api/share/:directory(*)', '/api/share/', '/api/share//'],
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.User),
|
||||
SharingMWs.createSharing,
|
||||
@ -39,7 +39,7 @@ export class SharingRouter {
|
||||
};
|
||||
|
||||
private static addUpdateSharing(app) {
|
||||
app.put(["/api/share/:directory(*)", "/api/share/", "/api/share//"],
|
||||
app.put(['/api/share/:directory(*)', '/api/share/', '/api/share//'],
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.User),
|
||||
SharingMWs.updateSharing,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {UserMWs} from "../middlewares/user/UserMWs";
|
||||
import {UserRoles} from "../../common/entities/UserDTO";
|
||||
import {AuthenticationMWs} from "../middlewares/user/AuthenticationMWs";
|
||||
import {UserRequestConstrainsMWs} from "../middlewares/user/UserRequestConstrainsMWs";
|
||||
import {RenderingMWs} from "../middlewares/RenderingMWs";
|
||||
import {UserMWs} from '../middlewares/user/UserMWs';
|
||||
import {UserRoles} from '../../common/entities/UserDTO';
|
||||
import {AuthenticationMWs} from '../middlewares/user/AuthenticationMWs';
|
||||
import {UserRequestConstrainsMWs} from '../middlewares/user/UserRequestConstrainsMWs';
|
||||
import {RenderingMWs} from '../middlewares/RenderingMWs';
|
||||
|
||||
export class UserRouter {
|
||||
public static route(app) {
|
||||
@ -19,77 +19,77 @@ export class UserRouter {
|
||||
}
|
||||
|
||||
private static addLogin(app) {
|
||||
app.post("/api/user/login",
|
||||
app.post('/api/user/login',
|
||||
AuthenticationMWs.inverseAuthenticate,
|
||||
AuthenticationMWs.login,
|
||||
RenderingMWs.renderSessionUser
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addLogout(app) {
|
||||
app.post("/api/user/logout",
|
||||
app.post('/api/user/logout',
|
||||
AuthenticationMWs.logout,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static addGetSessionUser(app) {
|
||||
app.get("/api/user/login",
|
||||
app.get('/api/user/login',
|
||||
AuthenticationMWs.authenticate,
|
||||
RenderingMWs.renderSessionUser
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static addChangePassword(app) {
|
||||
app.post("/api/user/:id/password",
|
||||
app.post('/api/user/:id/password',
|
||||
AuthenticationMWs.authenticate,
|
||||
UserRequestConstrainsMWs.forceSelfRequest,
|
||||
UserMWs.changePassword,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static addCreateUser(app) {
|
||||
app.put("/api/user",
|
||||
app.put('/api/user',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
UserMWs.createUser,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addDeleteUser(app) {
|
||||
app.delete("/api/user/:id",
|
||||
app.delete('/api/user/:id',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
UserRequestConstrainsMWs.notSelfRequest,
|
||||
UserMWs.deleteUser,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static addListUsers(app) {
|
||||
app.get("/api/user/list",
|
||||
app.get('/api/user/list',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
UserMWs.listUsers,
|
||||
RenderingMWs.renderResult
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
private static addChangeRole(app) {
|
||||
app.post("/api/user/:id/role",
|
||||
app.post('/api/user/:id/role',
|
||||
AuthenticationMWs.authenticate,
|
||||
AuthenticationMWs.authorise(UserRoles.Admin),
|
||||
UserRequestConstrainsMWs.notSelfRequestOr2Admins,
|
||||
UserMWs.changeRole,
|
||||
RenderingMWs.renderOK
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
import * as _express from "express";
|
||||
import * as _bodyParser from "body-parser";
|
||||
import * as cookieParser from "cookie-parser";
|
||||
import * as _http from "http";
|
||||
import * as locale from "locale";
|
||||
import {PublicRouter} from "./routes/PublicRouter";
|
||||
import {UserRouter} from "./routes/UserRouter";
|
||||
import {GalleryRouter} from "./routes/GalleryRouter";
|
||||
import {AdminRouter} from "./routes/AdminRouter";
|
||||
import {ErrorRouter} from "./routes/ErrorRouter";
|
||||
import {SharingRouter} from "./routes/SharingRouter";
|
||||
import {ObjectManagerRepository} from "./model/ObjectManagerRepository";
|
||||
import {Logger} from "./Logger";
|
||||
import {Config} from "../common/config/private/Config";
|
||||
import {DatabaseType} from "../common/config/private/IPrivateConfig";
|
||||
import {LoggerRouter} from "./routes/LoggerRouter";
|
||||
import {ThumbnailGeneratorMWs} from "./middlewares/thumbnail/ThumbnailGeneratorMWs";
|
||||
import {DiskManager} from "./model/DiskManger";
|
||||
import {NotificationRouter} from "./routes/NotificationRouter";
|
||||
import {ConfigDiagnostics} from "./model/ConfigDiagnostics";
|
||||
import {Localizations} from "./model/Localizations";
|
||||
import {CookieNames} from "../common/CookieNames";
|
||||
import * as _express from 'express';
|
||||
import * as _bodyParser from 'body-parser';
|
||||
import * as cookieParser from 'cookie-parser';
|
||||
import * as _http from 'http';
|
||||
import * as locale from 'locale';
|
||||
import {PublicRouter} from './routes/PublicRouter';
|
||||
import {UserRouter} from './routes/UserRouter';
|
||||
import {GalleryRouter} from './routes/GalleryRouter';
|
||||
import {AdminRouter} from './routes/AdminRouter';
|
||||
import {ErrorRouter} from './routes/ErrorRouter';
|
||||
import {SharingRouter} from './routes/SharingRouter';
|
||||
import {ObjectManagerRepository} from './model/ObjectManagerRepository';
|
||||
import {Logger} from './Logger';
|
||||
import {Config} from '../common/config/private/Config';
|
||||
import {DatabaseType} from '../common/config/private/IPrivateConfig';
|
||||
import {LoggerRouter} from './routes/LoggerRouter';
|
||||
import {ThumbnailGeneratorMWs} from './middlewares/thumbnail/ThumbnailGeneratorMWs';
|
||||
import {DiskManager} from './model/DiskManger';
|
||||
import {NotificationRouter} from './routes/NotificationRouter';
|
||||
import {ConfigDiagnostics} from './model/ConfigDiagnostics';
|
||||
import {Localizations} from './model/Localizations';
|
||||
import {CookieNames} from '../common/CookieNames';
|
||||
|
||||
const _session = require('cookie-session');
|
||||
|
||||
const LOG_TAG = "[server]";
|
||||
const LOG_TAG = '[server]';
|
||||
|
||||
export class Server {
|
||||
|
||||
@ -31,16 +31,16 @@ export class Server {
|
||||
private server: any;
|
||||
|
||||
constructor() {
|
||||
if (!(process.env.NODE_ENV == "production")) {
|
||||
Logger.debug(LOG_TAG, "Running in DEBUG mode");
|
||||
if (!(process.env.NODE_ENV == 'production')) {
|
||||
Logger.debug(LOG_TAG, 'Running in DEBUG mode');
|
||||
}
|
||||
this.init();
|
||||
}
|
||||
|
||||
async init() {
|
||||
Logger.info(LOG_TAG, "running diagnostics...");
|
||||
Logger.info(LOG_TAG, 'running diagnostics...');
|
||||
await ConfigDiagnostics.runDiagnostics();
|
||||
Logger.info(LOG_TAG, "using config:");
|
||||
Logger.info(LOG_TAG, 'using config:');
|
||||
Logger.info(LOG_TAG, JSON.stringify(Config, null, '\t'));
|
||||
|
||||
this.app = _express();
|
||||
@ -61,7 +61,7 @@ export class Server {
|
||||
|
||||
this.app.use(_session({
|
||||
name: CookieNames.session,
|
||||
keys: ["key1" + s4() + s4() + s4() + s4(), "key2" + s4() + s4() + s4() + s4(), "key3" + s4() + s4() + s4() + s4()]
|
||||
keys: ['key1' + s4() + s4() + s4() + s4(), 'key2' + s4() + s4() + s4() + s4(), 'key3' + s4() + s4() + s4() + s4()]
|
||||
}));
|
||||
|
||||
/* this.app.use((req: Request, res: Response, next: NextFunction) => {
|
||||
@ -81,7 +81,7 @@ export class Server {
|
||||
ThumbnailGeneratorMWs.init();
|
||||
Localizations.init();
|
||||
|
||||
this.app.use(locale(Config.Client.languages, "en"));
|
||||
this.app.use(locale(Config.Client.languages, 'en'));
|
||||
if (Config.Server.database.type != DatabaseType.memory) {
|
||||
await ObjectManagerRepository.InitSQLManagers();
|
||||
} else {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {Component, OnInit} 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 {I18n} from "@ngx-translate/i18n-polyfill";
|
||||
import {Component, OnInit} 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 {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
@Component({
|
||||
selector: 'admin',
|
||||
@ -15,16 +15,16 @@ export class AdminComponent implements OnInit {
|
||||
|
||||
simplifiedMode = true;
|
||||
text = {
|
||||
Advanced: "Advanced",
|
||||
Simplified: "Simplified"
|
||||
Advanced: 'Advanced',
|
||||
Simplified: 'Simplified'
|
||||
};
|
||||
|
||||
constructor(private _authService: AuthenticationService,
|
||||
private _navigation: NavigationService,
|
||||
public notificationService: NotificationService,
|
||||
public i18n: I18n) {
|
||||
this.text.Advanced = i18n("Advanced");
|
||||
this.text.Simplified = i18n("Simplified");
|
||||
this.text.Advanced = i18n('Advanced');
|
||||
this.text.Simplified = i18n('Simplified');
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
@ -38,13 +38,13 @@ export class AdminComponent implements OnInit {
|
||||
public getCss(type: NotificationType) {
|
||||
switch (type) {
|
||||
case NotificationType.error:
|
||||
return "danger";
|
||||
return 'danger';
|
||||
case NotificationType.warning:
|
||||
return "warning";
|
||||
return 'warning';
|
||||
case NotificationType.info:
|
||||
return "info";
|
||||
return 'info';
|
||||
}
|
||||
return "info";
|
||||
return 'info';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import {Component, OnDestroy, OnInit, ViewContainerRef} from "@angular/core";
|
||||
import {AuthenticationService} from "./model/network/authentication.service";
|
||||
import {UserDTO} from "../../common/entities/UserDTO";
|
||||
import {Router} from "@angular/router";
|
||||
import {Config} from "../../common/config/public/Config";
|
||||
import {Title} from "@angular/platform-browser";
|
||||
import {NotificationService} from "./model/notification.service";
|
||||
import {ShareService} from "./gallery/share.service";
|
||||
import "hammerjs";
|
||||
import {Component, OnDestroy, OnInit, ViewContainerRef} from '@angular/core';
|
||||
import {AuthenticationService} from './model/network/authentication.service';
|
||||
import {UserDTO} from '../../common/entities/UserDTO';
|
||||
import {Router} from '@angular/router';
|
||||
import {Config} from '../../common/config/public/Config';
|
||||
import {Title} from '@angular/platform-browser';
|
||||
import {NotificationService} from './model/notification.service';
|
||||
import {ShareService} from './gallery/share.service';
|
||||
import 'hammerjs';
|
||||
|
||||
@Component({
|
||||
selector: 'pi-gallery2-app',
|
||||
selector: 'app-pi-gallery2',
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
|
||||
})
|
||||
@ -55,17 +55,17 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
|
||||
private toLogin() {
|
||||
if (this._shareService.isSharing()) {
|
||||
return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
return this._router.navigate(['shareLogin'], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
} else {
|
||||
return this._router.navigate(["login"]);
|
||||
return this._router.navigate(['login']);
|
||||
}
|
||||
}
|
||||
|
||||
private toGallery() {
|
||||
if (this._shareService.isSharing()) {
|
||||
return this._router.navigate(["share", this._shareService.getSharingKey()]);
|
||||
return this._router.navigate(['share', this._shareService.getSharingKey()]);
|
||||
} else {
|
||||
return this._router.navigate(["gallery", ""]);
|
||||
return this._router.navigate(['gallery', '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,62 +1,62 @@
|
||||
import {Injectable, LOCALE_ID, NgModule, TRANSLATIONS} from "@angular/core";
|
||||
import {BrowserModule, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from "@angular/platform-browser";
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {HttpModule} from "@angular/http";
|
||||
import {AgmCoreModule} from "@agm/core";
|
||||
import {AppComponent} from "./app.component";
|
||||
import {appRoutes} from "./app.routing";
|
||||
import {UserService} from "./model/network/user.service";
|
||||
import {GalleryService} from "./gallery/gallery.service";
|
||||
import {NetworkService} from "./model/network/network.service";
|
||||
import {ThumbnailLoaderService} from "./gallery/thumnailLoader.service";
|
||||
import {GalleryCacheService} from "./gallery/cache.gallery.service";
|
||||
import {FullScreenService} from "./gallery/fullscreen.service";
|
||||
import {AuthenticationService} from "./model/network/authentication.service";
|
||||
import {UserMangerSettingsComponent} from "./settings/usermanager/usermanager.settings.component";
|
||||
import {FrameComponent} from "./frame/frame.component";
|
||||
import {GalleryLightboxPhotoComponent} from "./gallery/lightbox/photo/photo.lightbox.gallery.component";
|
||||
import {GalleryPhotoLoadingComponent} from "./gallery/grid/photo/loading/loading.photo.grid.gallery.component";
|
||||
import {GalleryNavigatorComponent} from "./gallery/navigator/navigator.gallery.component";
|
||||
import {GallerySearchComponent} from "./gallery/search/search.gallery.component";
|
||||
import {GalleryLightboxComponent} from "./gallery/lightbox/lightbox.gallery.component";
|
||||
import {GalleryDirectoryComponent} from "./gallery/directory/directory.gallery.component";
|
||||
import {GalleryGridComponent} from "./gallery/grid/grid.gallery.component";
|
||||
import {GalleryPhotoComponent} from "./gallery/grid/photo/photo.grid.gallery.component";
|
||||
import {LoginComponent} from "./login/login.component";
|
||||
import {AdminComponent} from "./admin/admin.component";
|
||||
import {GalleryComponent} from "./gallery/gallery.component";
|
||||
import {StringifyRole} from "./pipes/StringifyRolePipe";
|
||||
import {GalleryMapComponent} from "./gallery/map/map.gallery.component";
|
||||
import {GalleryMapLightboxComponent} from "./gallery/map/lightbox/lightbox.map.gallery.component";
|
||||
import {ThumbnailManagerService} from "./gallery/thumnailManager.service";
|
||||
import {OverlayService} from "./gallery/overlay.service";
|
||||
import {Config} from "../../common/config/public/Config";
|
||||
import {LAZY_MAPS_API_CONFIG} from "@agm/core/services";
|
||||
import {SlimLoadingBarModule} from "ng2-slim-loading-bar";
|
||||
import {GalleryShareComponent} from "./gallery/share/share.gallery.component";
|
||||
import {ShareLoginComponent} from "./sharelogin/share-login.component";
|
||||
import {ShareService} from "./gallery/share.service";
|
||||
import {ModalModule} from "ngx-bootstrap/modal";
|
||||
import {DatabaseSettingsComponent} from "./settings/database/database.settings.component";
|
||||
import {ToastModule} from "ng2-toastr/ng2-toastr";
|
||||
import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
|
||||
import {NotificationService} from "./model/notification.service";
|
||||
import {JWBootstrapSwitchModule} from "jw-bootstrap-switch-ng2";
|
||||
import {ClipboardModule} from "ngx-clipboard";
|
||||
import {NavigationService} from "./model/navigation.service";
|
||||
import {InfoPanelLightboxComponent} from "./gallery/lightbox/infopanel/info-panel.lightbox.gallery.component";
|
||||
import {MapSettingsComponent} from "./settings/map/map.settings.component";
|
||||
import {TooltipModule} from "ngx-bootstrap/tooltip";
|
||||
import {BsDropdownModule} from "ngx-bootstrap/dropdown";
|
||||
import {ThumbnailSettingsComponent} from "./settings/thumbnail/thumbanil.settings.component";
|
||||
import {SearchSettingsComponent} from "./settings/search/search.settings.component";
|
||||
import {SettingsService} from "./settings/settings.service";
|
||||
import {ShareSettingsComponent} from "./settings/share/share.settings.component";
|
||||
import {BasicSettingsComponent} from "./settings/basic/basic.settings.component";
|
||||
import {OtherSettingsComponent} from "./settings/other/other.settings.component";
|
||||
import {Injectable, LOCALE_ID, NgModule, TRANSLATIONS} from '@angular/core';
|
||||
import {BrowserModule, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '@angular/platform-browser';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {AgmCoreModule} from '@agm/core';
|
||||
import {AppComponent} from './app.component';
|
||||
import {appRoutes} from './app.routing';
|
||||
import {UserService} from './model/network/user.service';
|
||||
import {GalleryService} from './gallery/gallery.service';
|
||||
import {NetworkService} from './model/network/network.service';
|
||||
import {ThumbnailLoaderService} from './gallery/thumnailLoader.service';
|
||||
import {GalleryCacheService} from './gallery/cache.gallery.service';
|
||||
import {FullScreenService} from './gallery/fullscreen.service';
|
||||
import {AuthenticationService} from './model/network/authentication.service';
|
||||
import {UserMangerSettingsComponent} from './settings/usermanager/usermanager.settings.component';
|
||||
import {FrameComponent} from './frame/frame.component';
|
||||
import {GalleryLightboxPhotoComponent} from './gallery/lightbox/photo/photo.lightbox.gallery.component';
|
||||
import {GalleryPhotoLoadingComponent} from './gallery/grid/photo/loading/loading.photo.grid.gallery.component';
|
||||
import {GalleryNavigatorComponent} from './gallery/navigator/navigator.gallery.component';
|
||||
import {GallerySearchComponent} from './gallery/search/search.gallery.component';
|
||||
import {GalleryLightboxComponent} from './gallery/lightbox/lightbox.gallery.component';
|
||||
import {GalleryDirectoryComponent} from './gallery/directory/directory.gallery.component';
|
||||
import {GalleryGridComponent} from './gallery/grid/grid.gallery.component';
|
||||
import {GalleryPhotoComponent} from './gallery/grid/photo/photo.grid.gallery.component';
|
||||
import {LoginComponent} from './login/login.component';
|
||||
import {AdminComponent} from './admin/admin.component';
|
||||
import {GalleryComponent} from './gallery/gallery.component';
|
||||
import {StringifyRole} from './pipes/StringifyRolePipe';
|
||||
import {GalleryMapComponent} from './gallery/map/map.gallery.component';
|
||||
import {GalleryMapLightboxComponent} from './gallery/map/lightbox/lightbox.map.gallery.component';
|
||||
import {ThumbnailManagerService} from './gallery/thumnailManager.service';
|
||||
import {OverlayService} from './gallery/overlay.service';
|
||||
import {Config} from '../../common/config/public/Config';
|
||||
import {LAZY_MAPS_API_CONFIG} from '@agm/core/services';
|
||||
import {SlimLoadingBarModule} from 'ng2-slim-loading-bar';
|
||||
import {GalleryShareComponent} from './gallery/share/share.gallery.component';
|
||||
import {ShareLoginComponent} from './sharelogin/share-login.component';
|
||||
import {ShareService} from './gallery/share.service';
|
||||
import {ModalModule} from 'ngx-bootstrap/modal';
|
||||
import {DatabaseSettingsComponent} from './settings/database/database.settings.component';
|
||||
import {ToastModule} from 'ng2-toastr/ng2-toastr';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {NotificationService} from './model/notification.service';
|
||||
import {JWBootstrapSwitchModule} from 'jw-bootstrap-switch-ng2';
|
||||
import {ClipboardModule} from 'ngx-clipboard';
|
||||
import {NavigationService} from './model/navigation.service';
|
||||
import {InfoPanelLightboxComponent} from './gallery/lightbox/infopanel/info-panel.lightbox.gallery.component';
|
||||
import {MapSettingsComponent} from './settings/map/map.settings.component';
|
||||
import {TooltipModule} from 'ngx-bootstrap/tooltip';
|
||||
import {BsDropdownModule} from 'ngx-bootstrap/dropdown';
|
||||
import {ThumbnailSettingsComponent} from './settings/thumbnail/thumbanil.settings.component';
|
||||
import {SearchSettingsComponent} from './settings/search/search.settings.component';
|
||||
import {SettingsService} from './settings/settings.service';
|
||||
import {ShareSettingsComponent} from './settings/share/share.settings.component';
|
||||
import {BasicSettingsComponent} from './settings/basic/basic.settings.component';
|
||||
import {OtherSettingsComponent} from './settings/other/other.settings.component';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {DefaultUrlSerializer, UrlSerializer, UrlTree} from '@angular/router';
|
||||
import {IndexingSettingsComponent} from "./settings/indexing/indexing.settings.component";
|
||||
import {LanguageComponent} from "./language/language.component";
|
||||
import {IndexingSettingsComponent} from './settings/indexing/indexing.settings.component';
|
||||
import {LanguageComponent} from './language/language.component';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
@Injectable()
|
||||
@ -71,7 +71,7 @@ export class GoogleMapsConfig {
|
||||
export class MyHammerConfig extends HammerGestureConfig {
|
||||
overrides = <any>{
|
||||
'swipe': {direction: 31} // enable swipe up
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export class CustomUrlSerializer implements UrlSerializer {
|
||||
@ -81,7 +81,7 @@ export class CustomUrlSerializer implements UrlSerializer {
|
||||
// Encode parentheses
|
||||
url = url.replace(/\(/g, '%28').replace(/\)/g, '%29');
|
||||
// Use the default serializer.
|
||||
return this._defaultUrlSerializer.parse(url)
|
||||
return this._defaultUrlSerializer.parse(url);
|
||||
}
|
||||
|
||||
serialize(tree: UrlTree): string {
|
||||
@ -93,7 +93,7 @@ declare const require;
|
||||
|
||||
export function translationsFactory(locale: string) {
|
||||
locale = locale || 'en'; // default to english if no locale
|
||||
console.log("locale", locale);
|
||||
console.log('locale', locale);
|
||||
return require(`raw-loader!../translate/messages.${locale}.xlf`);
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ export function translationsFactory(locale: string) {
|
||||
imports: [
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
HttpModule,
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
appRoutes,
|
||||
ClipboardModule,
|
||||
@ -117,10 +117,10 @@ export function translationsFactory(locale: string) {
|
||||
LoginComponent,
|
||||
ShareLoginComponent,
|
||||
GalleryComponent,
|
||||
//misc
|
||||
// misc
|
||||
FrameComponent,
|
||||
LanguageComponent,
|
||||
//Gallery
|
||||
// Gallery
|
||||
GalleryLightboxPhotoComponent,
|
||||
GalleryPhotoLoadingComponent,
|
||||
GalleryGridComponent,
|
||||
@ -135,7 +135,7 @@ export function translationsFactory(locale: string) {
|
||||
GalleryPhotoComponent,
|
||||
AdminComponent,
|
||||
InfoPanelLightboxComponent,
|
||||
//Settings
|
||||
// Settings
|
||||
UserMangerSettingsComponent,
|
||||
DatabaseSettingsComponent,
|
||||
MapSettingsComponent,
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {ModuleWithProviders} from "@angular/core";
|
||||
import {RouterModule, Routes} from "@angular/router";
|
||||
import {LoginComponent} from "./login/login.component";
|
||||
import {GalleryComponent} from "./gallery/gallery.component";
|
||||
import {AdminComponent} from "./admin/admin.component";
|
||||
import {ShareLoginComponent} from "./sharelogin/share-login.component";
|
||||
import {ModuleWithProviders} from '@angular/core';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {LoginComponent} from './login/login.component';
|
||||
import {GalleryComponent} from './gallery/gallery.component';
|
||||
import {AdminComponent} from './admin/admin.component';
|
||||
import {ShareLoginComponent} from './sharelogin/share-login.component';
|
||||
|
||||
const ROUTES: Routes = [
|
||||
{
|
||||
|
||||
@ -53,7 +53,6 @@ ng2-slim-loading-bar {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.badge {
|
||||
margin-left: -5px;
|
||||
padding: 0;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {Component, ViewEncapsulation} from "@angular/core";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {AuthenticationService} from "../model/network/authentication.service";
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||
import {NotificationService} from "../model/notification.service";
|
||||
import {Component, ViewEncapsulation} from '@angular/core';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {UserDTO, UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||
import {NotificationService} from '../model/notification.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-frame',
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
|
||||
export class IconPhoto {
|
||||
|
||||
|
||||
@ -18,23 +19,23 @@ export class IconPhoto {
|
||||
}
|
||||
|
||||
getIconPath() {
|
||||
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "icon");
|
||||
return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'icon');
|
||||
}
|
||||
|
||||
getPhotoPath() {
|
||||
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name);
|
||||
return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name);
|
||||
}
|
||||
|
||||
|
||||
equals(other: PhotoDTO | IconPhoto): boolean {
|
||||
//is gridphoto
|
||||
if (other instanceof IconPhoto) {
|
||||
return this.photo.directory.path === other.photo.directory.path && this.photo.directory.name === other.photo.directory.name && this.photo.name === other.photo.name
|
||||
return this.photo.directory.path === other.photo.directory.path && this.photo.directory.name === other.photo.directory.name && this.photo.name === other.photo.name;
|
||||
}
|
||||
|
||||
//is photo
|
||||
if (other.directory) {
|
||||
return this.photo.directory.path === other.directory.path && this.photo.directory.name === other.directory.name && this.photo.name === other.name
|
||||
return this.photo.directory.path === other.directory.path && this.photo.directory.name === other.directory.name && this.photo.name === other.name;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {IconPhoto} from "./IconPhoto";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {IconPhoto} from './IconPhoto';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
|
||||
export class Photo extends IconPhoto {
|
||||
|
||||
|
||||
@ -50,13 +51,13 @@ export class Photo extends IconPhoto {
|
||||
|
||||
getReplacementThumbnailPath() {
|
||||
let size = this.getReplacementThumbnailSize();
|
||||
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "thumbnail", size.toString());
|
||||
return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'thumbnail', size.toString());
|
||||
|
||||
}
|
||||
|
||||
getThumbnailPath() {
|
||||
let size = this.getThumbnailSize();
|
||||
return Utils.concatUrls("/api/gallery/content/", this.photo.directory.path, this.photo.directory.name, this.photo.name, "thumbnail", size.toString());
|
||||
return Utils.concatUrls('/api/gallery/content/', this.photo.directory.path, this.photo.directory.name, this.photo.name, 'thumbnail', size.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {Utils} from "../../../common/Utils";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {SearchResultDTO} from "../../../common/entities/SearchResultDTO";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {Utils} from '../../../common/Utils';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
|
||||
interface CacheItem<T> {
|
||||
timestamp: number;
|
||||
@ -14,11 +14,11 @@ interface CacheItem<T> {
|
||||
@Injectable()
|
||||
export class GalleryCacheService {
|
||||
|
||||
private static CONTENT_PREFIX = "content:";
|
||||
private static AUTO_COMPLETE_PREFIX = "autocomplete:";
|
||||
private static INSTANT_SEARCH_PREFIX = "instant_search:";
|
||||
private static SEARCH_PREFIX = "search:";
|
||||
private static SEARCH_TYPE_PREFIX = ":type:";
|
||||
private static CONTENT_PREFIX = 'content:';
|
||||
private static AUTO_COMPLETE_PREFIX = 'autocomplete:';
|
||||
private static INSTANT_SEARCH_PREFIX = 'instant_search:';
|
||||
private static SEARCH_PREFIX = 'search:';
|
||||
private static SEARCH_TYPE_PREFIX = ':type:';
|
||||
|
||||
|
||||
public getAutoComplete(text: string): Array<AutoCompleteItem> {
|
||||
@ -68,7 +68,7 @@ export class GalleryCacheService {
|
||||
|
||||
public getSearch(text: string, type?: SearchTypes): SearchResultDTO {
|
||||
let key = GalleryCacheService.SEARCH_PREFIX + text;
|
||||
if (typeof type != "undefined") {
|
||||
if (typeof type != 'undefined') {
|
||||
key += GalleryCacheService.SEARCH_TYPE_PREFIX + type;
|
||||
}
|
||||
const tmp = localStorage.getItem(key);
|
||||
@ -89,7 +89,7 @@ export class GalleryCacheService {
|
||||
item: searchResult
|
||||
};
|
||||
let key = GalleryCacheService.SEARCH_PREFIX + text;
|
||||
if (typeof type != "undefined") {
|
||||
if (typeof type != 'undefined') {
|
||||
key += GalleryCacheService.SEARCH_TYPE_PREFIX + type;
|
||||
}
|
||||
localStorage.setItem(key, JSON.stringify(tmp));
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {DomSanitizer} from "@angular/platform-browser";
|
||||
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {Utils} from "../../../../common/Utils";
|
||||
import {Photo} from "../Photo";
|
||||
import {Thumbnail, ThumbnailManagerService} from "../thumnailManager.service";
|
||||
import {ShareService} from "../share.service";
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {DomSanitizer} from '@angular/platform-browser';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {Photo} from '../Photo';
|
||||
import {Thumbnail, ThumbnailManagerService} from '../thumnailManager.service';
|
||||
import {ShareService} from '../share.service';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-directory',
|
||||
@ -15,7 +15,7 @@ import {ShareService} from "../share.service";
|
||||
})
|
||||
export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
@Input() directory: DirectoryDTO;
|
||||
@ViewChild("dirContainer") container: ElementRef;
|
||||
@ViewChild('dirContainer') container: ElementRef;
|
||||
thumbnail: Thumbnail = null;
|
||||
|
||||
constructor(private thumbnailService: ThumbnailManagerService,
|
||||
@ -27,7 +27,7 @@ export class GalleryDirectoryComponent implements OnInit, OnDestroy {
|
||||
size: number = null;
|
||||
|
||||
getSanitizedThUrl() {
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' + encodeURI(this.thumbnail.Src).replace(/\(/g, "%28").replace(/\)/g, "%29") + ')');
|
||||
return this._sanitizer.bypassSecurityTrustStyle('url(' + encodeURI(this.thumbnail.Src).replace(/\(/g, '%28').replace(/\)/g, '%29') + ')');
|
||||
}
|
||||
|
||||
//TODO: implement scroll
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Event} from "../../../common/event/Event";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Event} from '../../../common/event/Event';
|
||||
|
||||
@Injectable()
|
||||
export class FullScreenService {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
gallery-map {
|
||||
margin-right: 0;
|
||||
margin-left: auto;
|
||||
display: block;
|
||||
height: 80px;
|
||||
width: 100px;
|
||||
margin-right: 0;
|
||||
margin-left: auto;
|
||||
display: block;
|
||||
height: 80px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.directories {
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {AuthenticationService} from "../model/network/authentication.service";
|
||||
import {ActivatedRoute, Params, Router} from "@angular/router";
|
||||
import {GalleryService} from "./gallery.service";
|
||||
import {GalleryGridComponent} from "./grid/grid.gallery.component";
|
||||
import {GallerySearchComponent} from "./search/search.gallery.component";
|
||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {SearchResultDTO} from "../../../common/entities/SearchResultDTO";
|
||||
import {ShareService} from "./share.service";
|
||||
import {NavigationService} from "../model/navigation.service";
|
||||
import {UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {Observable} from "rxjs/Rx";
|
||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {ActivatedRoute, Params, Router} from '@angular/router';
|
||||
import {GalleryService} from './gallery.service';
|
||||
import {GalleryGridComponent} from './grid/grid.gallery.component';
|
||||
import {GallerySearchComponent} from './search/search.gallery.component';
|
||||
import {SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {SearchResultDTO} from '../../../common/entities/SearchResultDTO';
|
||||
import {ShareService} from './share.service';
|
||||
import {NavigationService} from '../model/navigation.service';
|
||||
import {UserRoles} from '../../../common/entities/UserDTO';
|
||||
import {Observable} from 'rxjs/Rx';
|
||||
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery',
|
||||
@ -62,26 +62,33 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
this.countDown.second = t % 60;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
await this.shareService.wait();
|
||||
if (!this._authService.isAuthenticated() &&
|
||||
(!this.shareService.isSharing() ||
|
||||
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))) {
|
||||
private onRoute = async (params: Params) => {
|
||||
const searchText = params['searchText'];
|
||||
if (searchText && searchText != '') {
|
||||
let typeString = params['type'];
|
||||
|
||||
return this._navigation.toLogin();
|
||||
}
|
||||
this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest);
|
||||
this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User);
|
||||
if (typeString && typeString != '') {
|
||||
let type: SearchTypes = <any>SearchTypes[typeString];
|
||||
this._galleryService.search(searchText, type);
|
||||
return;
|
||||
}
|
||||
|
||||
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
|
||||
this.subscription.route = this._route.params.subscribe(this.onRoute);
|
||||
|
||||
if (this.shareService.isSharing()) {
|
||||
this.$counter = Observable.interval(1000);
|
||||
this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x));
|
||||
this._galleryService.search(searchText);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
if (params['sharingKey'] && params['sharingKey'] != '') {
|
||||
const sharing = await this.shareService.getSharing();
|
||||
this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}});
|
||||
return;
|
||||
}
|
||||
|
||||
let directoryName = params['directory'];
|
||||
directoryName = directoryName || '';
|
||||
|
||||
this._galleryService.getDirectory(directoryName);
|
||||
|
||||
};
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.subscription.content !== null) {
|
||||
@ -118,33 +125,26 @@ export class GalleryComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
};
|
||||
|
||||
private onRoute = async (params: Params) => {
|
||||
const searchText = params['searchText'];
|
||||
if (searchText && searchText != "") {
|
||||
let typeString = params['type'];
|
||||
async ngOnInit() {
|
||||
await this.shareService.wait();
|
||||
if (!this._authService.isAuthenticated() &&
|
||||
(!this.shareService.isSharing() ||
|
||||
(this.shareService.isSharing() && Config.Client.Sharing.passwordProtected == true))) {
|
||||
|
||||
if (typeString && typeString != "") {
|
||||
let type: SearchTypes = <any>SearchTypes[typeString];
|
||||
this._galleryService.search(searchText, type);
|
||||
return;
|
||||
}
|
||||
return this._navigation.toLogin();
|
||||
}
|
||||
this.showSearchBar = Config.Client.Search.enabled && this._authService.isAuthorized(UserRoles.Guest);
|
||||
this.showShare = Config.Client.Sharing.enabled && this._authService.isAuthorized(UserRoles.User);
|
||||
|
||||
this._galleryService.search(searchText);
|
||||
return;
|
||||
this.subscription.content = this._galleryService.content.subscribe(this.onContentChange);
|
||||
this.subscription.route = this._route.params.subscribe(this.onRoute);
|
||||
|
||||
if (this.shareService.isSharing()) {
|
||||
this.$counter = Observable.interval(1000);
|
||||
this.subscription.timer = this.$counter.subscribe((x) => this.updateTimer(x));
|
||||
}
|
||||
|
||||
if (params['sharingKey'] && params['sharingKey'] != "") {
|
||||
const sharing = await this.shareService.getSharing();
|
||||
this._router.navigate(['/gallery', sharing.path], {queryParams: {sk: this.shareService.getSharingKey()}});
|
||||
return;
|
||||
}
|
||||
|
||||
let directoryName = params['directory'];
|
||||
directoryName = directoryName || "";
|
||||
|
||||
this._galleryService.getDirectory(directoryName);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
onLightboxLastElement() {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {NetworkService} from "../model/network/network.service";
|
||||
import {ContentWrapper} from "../../../common/entities/ConentWrapper";
|
||||
import {DirectoryDTO} from "../../../common/entities/DirectoryDTO";
|
||||
import {SearchTypes} from "../../../common/entities/AutoCompleteItem";
|
||||
import {GalleryCacheService} from "./cache.gallery.service";
|
||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||
import {SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {ShareService} from "./share.service";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {ContentWrapper} from '../../../common/entities/ConentWrapper';
|
||||
import {DirectoryDTO} from '../../../common/entities/DirectoryDTO';
|
||||
import {SearchTypes} from '../../../common/entities/AutoCompleteItem';
|
||||
import {GalleryCacheService} from './cache.gallery.service';
|
||||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||
import {SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {ShareService} from './share.service';
|
||||
|
||||
@Injectable()
|
||||
export class GalleryService {
|
||||
@ -49,7 +49,7 @@ export class GalleryService {
|
||||
}
|
||||
|
||||
|
||||
const cw = await this.networkService.getJson<ContentWrapper>("/gallery/content/" + directoryName, params);
|
||||
const cw = await this.networkService.getJson<ContentWrapper>('/gallery/content/' + directoryName, params);
|
||||
|
||||
|
||||
if (!cw || cw.notModified == true) {
|
||||
@ -78,8 +78,8 @@ export class GalleryService {
|
||||
if (this.searchId != null) {
|
||||
clearTimeout(this.searchId);
|
||||
}
|
||||
if (text === null || text === '' || text.trim() == ".") {
|
||||
return null
|
||||
if (text === null || text === '' || text.trim() == '.') {
|
||||
return null;
|
||||
}
|
||||
|
||||
this.content.next(new ContentWrapper());
|
||||
@ -87,10 +87,10 @@ export class GalleryService {
|
||||
cw.searchResult = this.galleryCacheService.getSearch(text, type);
|
||||
if (cw.searchResult == null) {
|
||||
const params = {};
|
||||
if (typeof type != "undefined") {
|
||||
if (typeof type != 'undefined') {
|
||||
params['type'] = type;
|
||||
}
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>("/search/" + text, params)).searchResult;
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/search/' + text, params)).searchResult;
|
||||
this.galleryCacheService.setSearch(text, type, cw.searchResult);
|
||||
}
|
||||
this.content.next(cw);
|
||||
@ -98,16 +98,16 @@ export class GalleryService {
|
||||
}
|
||||
|
||||
public async instantSearch(text: string): Promise<ContentWrapper> {
|
||||
if (text === null || text === '' || text.trim() == ".") {
|
||||
if (text === null || text === '' || text.trim() == '.') {
|
||||
const content = new ContentWrapper(this.lastDirectory);
|
||||
this.content.next(content);
|
||||
if (this.searchId != null) {
|
||||
clearTimeout(this.searchId);
|
||||
}
|
||||
if (!this.lastDirectory) {
|
||||
this.getDirectory("/");
|
||||
this.getDirectory('/');
|
||||
}
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.searchId != null) {
|
||||
@ -128,7 +128,7 @@ export class GalleryService {
|
||||
cw.searchResult = this.galleryCacheService.getInstantSearch(text);
|
||||
|
||||
if (cw.searchResult == null) {
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>("/instant-search/" + text)).searchResult;
|
||||
cw.searchResult = (await this.networkService.getJson<ContentWrapper>('/instant-search/' + text)).searchResult;
|
||||
this.galleryCacheService.setInstantSearch(text, cw.searchResult);
|
||||
}
|
||||
}
|
||||
@ -145,7 +145,7 @@ export class GalleryService {
|
||||
}
|
||||
|
||||
public async getSharing(sharingKey: string): Promise<SharingDTO> {
|
||||
return this.networkService.getJson<SharingDTO>("/share/" + sharingKey);
|
||||
return this.networkService.getJson<SharingDTO>('/share/' + sharingKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {Photo} from "../Photo";
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {Photo} from '../Photo';
|
||||
|
||||
export class GridPhoto extends Photo {
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
|
||||
export class GridRowBuilder {
|
||||
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
div {
|
||||
/*display: block;*/
|
||||
line-height: normal;
|
||||
font-size: 0;
|
||||
/*display: block;*/
|
||||
line-height: normal;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
gallery-grid-photo {
|
||||
display: inline-block;
|
||||
display: inline-block;
|
||||
|
||||
cursor: pointer;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<div #gridContainer>
|
||||
<gallery-grid-photo
|
||||
*ngFor="let gridPhoto of photosToRender"
|
||||
(click)="lightbox.show(gridPhoto.photo)"
|
||||
[gridPhoto]="gridPhoto"
|
||||
[style.width.px]="gridPhoto.renderWidth"
|
||||
[style.height.px]="gridPhoto.renderHeight"
|
||||
[style.marginLeft.px]="IMAGE_MARGIN"
|
||||
[style.marginRight.px]="IMAGE_MARGIN">
|
||||
<gallery-grid-photo
|
||||
*ngFor="let gridPhoto of photosToRender"
|
||||
(click)="lightbox.show(gridPhoto.photo)"
|
||||
[gridPhoto]="gridPhoto"
|
||||
[style.width.px]="gridPhoto.renderWidth"
|
||||
[style.height.px]="gridPhoto.renderHeight"
|
||||
[style.marginLeft.px]="IMAGE_MARGIN"
|
||||
[style.marginRight.px]="IMAGE_MARGIN">
|
||||
|
||||
</gallery-grid-photo>
|
||||
</div>
|
||||
</gallery-grid-photo>
|
||||
</div>
|
||||
|
||||
@ -10,14 +10,14 @@ import {
|
||||
QueryList,
|
||||
ViewChild,
|
||||
ViewChildren
|
||||
} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {GridRowBuilder} from "./GridRowBuilder";
|
||||
import {GalleryLightboxComponent} from "../lightbox/lightbox.gallery.component";
|
||||
import {GridPhoto} from "./GridPhoto";
|
||||
import {GalleryPhotoComponent} from "./photo/photo.grid.gallery.component";
|
||||
import {OverlayService} from "../overlay.service";
|
||||
import {Config} from "../../../../common/config/public/Config";
|
||||
} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {GridRowBuilder} from './GridRowBuilder';
|
||||
import {GalleryLightboxComponent} from '../lightbox/lightbox.gallery.component';
|
||||
import {GridPhoto} from './GridPhoto';
|
||||
import {GalleryPhotoComponent} from './photo/photo.grid.gallery.component';
|
||||
import {OverlayService} from '../overlay.service';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-grid',
|
||||
@ -154,7 +154,7 @@ export class GalleryGridComponent implements OnChanges, AfterViewInit, OnDestroy
|
||||
this.renderedPhotoIndex < numberOfPhotos)) {
|
||||
let ret = this.renderARow();
|
||||
if (ret === null) {
|
||||
throw new Error("Grid photos rendering failed");
|
||||
throw new Error('Grid photos rendering failed');
|
||||
}
|
||||
renderedContentHeight += ret;
|
||||
}
|
||||
|
||||
@ -1,97 +1,97 @@
|
||||
.static {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #bbbbbb;
|
||||
color: #7f7f7f;
|
||||
font-size: 50px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #bbbbbb;
|
||||
color: #7f7f7f;
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.static span {
|
||||
top: calc(50% - 25px);
|
||||
left: calc(50% - 25px);
|
||||
top: calc(50% - 25px);
|
||||
left: calc(50% - 25px);
|
||||
}
|
||||
|
||||
.sk-cube-grid {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.sk-cube-grid .sk-cube {
|
||||
width: calc(100% / 3);
|
||||
height: calc(100% / 3);
|
||||
background-color: #bbbbbb;
|
||||
float: left;
|
||||
width: calc(100% / 3);
|
||||
height: calc(100% / 3);
|
||||
background-color: #bbbbbb;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube {
|
||||
-webkit-animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out;
|
||||
animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out;
|
||||
-webkit-animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out;
|
||||
animation: sk-cubeGridScaleDelay 4.6s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube1 {
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube2 {
|
||||
-webkit-animation-delay: 0.6s;
|
||||
animation-delay: 0.6s;
|
||||
-webkit-animation-delay: 0.6s;
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube3 {
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
-webkit-animation-delay: 0.8s;
|
||||
animation-delay: 0.8s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube4 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s;
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube5 {
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube6 {
|
||||
-webkit-animation-delay: 0.6s;
|
||||
animation-delay: 0.6s;
|
||||
-webkit-animation-delay: 0.6s;
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube7 {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s;
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube8 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s;
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.sk-cube-grid.animate .sk-cube9 {
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
}
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
}
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
}
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
}
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="sk-cube-grid animate" *ngIf="animate == true">
|
||||
<div class="sk-cube sk-cube1"></div>
|
||||
<div class="sk-cube sk-cube2"></div>
|
||||
<div class="sk-cube sk-cube3"></div>
|
||||
<div class="sk-cube sk-cube4"></div>
|
||||
<div class="sk-cube sk-cube5"></div>
|
||||
<div class="sk-cube sk-cube6"></div>
|
||||
<div class="sk-cube sk-cube7"></div>
|
||||
<div class="sk-cube sk-cube8"></div>
|
||||
<div class="sk-cube sk-cube9"></div>
|
||||
<div class="sk-cube sk-cube1"></div>
|
||||
<div class="sk-cube sk-cube2"></div>
|
||||
<div class="sk-cube sk-cube3"></div>
|
||||
<div class="sk-cube sk-cube4"></div>
|
||||
<div class="sk-cube sk-cube5"></div>
|
||||
<div class="sk-cube sk-cube6"></div>
|
||||
<div class="sk-cube sk-cube7"></div>
|
||||
<div class="sk-cube sk-cube8"></div>
|
||||
<div class="sk-cube sk-cube9"></div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {Component, Input} from "@angular/core";
|
||||
import {Component, Input} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-grid-photo-loading',
|
||||
|
||||
@ -49,11 +49,11 @@ img {
|
||||
}
|
||||
|
||||
.info {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
font-size: medium;
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
font-size: medium;
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
margin-top: 0;
|
||||
|
||||
transition: margin .3s ease-out, background-color .3s ease-out;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {Dimension, IRenderable} from "../../../model/IRenderable";
|
||||
import {GridPhoto} from "../GridPhoto";
|
||||
import {SearchTypes} from "../../../../../common/entities/AutoCompleteItem";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {Thumbnail, ThumbnailManagerService} from "../../thumnailManager.service";
|
||||
import {Config} from "../../../../../common/config/public/Config";
|
||||
import {AnimationBuilder} from "@angular/animations";
|
||||
import {Component, ElementRef, Input, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {Dimension, IRenderable} from '../../../model/IRenderable';
|
||||
import {GridPhoto} from '../GridPhoto';
|
||||
import {SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {Thumbnail, ThumbnailManagerService} from '../../thumnailManager.service';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
import {AnimationBuilder} from '@angular/animations';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-grid-photo',
|
||||
@ -15,9 +15,9 @@ import {AnimationBuilder} from "@angular/animations";
|
||||
})
|
||||
export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
@Input() gridPhoto: GridPhoto;
|
||||
@ViewChild("img") imageRef: ElementRef;
|
||||
@ViewChild("info") infoDiv: ElementRef;
|
||||
@ViewChild("photoContainer") container: ElementRef;
|
||||
@ViewChild('img') imageRef: ElementRef;
|
||||
@ViewChild('info') infoDiv: ElementRef;
|
||||
@ViewChild('photoContainer') container: ElementRef;
|
||||
|
||||
thumbnail: Thumbnail;
|
||||
/*
|
||||
@ -35,7 +35,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
infoBar = {
|
||||
marginTop: 0,
|
||||
visible: false,
|
||||
background: "rgba(0,0,0,0.0)"
|
||||
background: 'rgba(0,0,0,0.0)'
|
||||
};
|
||||
animationTimer = null;
|
||||
|
||||
@ -83,7 +83,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
|
||||
getPositionText(): string {
|
||||
if (!this.gridPhoto) {
|
||||
return ""
|
||||
return '';
|
||||
}
|
||||
return this.gridPhoto.photo.metadata.positionData.city ||
|
||||
this.gridPhoto.photo.metadata.positionData.state ||
|
||||
@ -97,7 +97,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
clearTimeout(this.animationTimer);
|
||||
}
|
||||
this.animationTimer = setTimeout(() => {
|
||||
this.infoBar.background = "rgba(0,0,0,0.8)";
|
||||
this.infoBar.background = 'rgba(0,0,0,0.8)';
|
||||
if (!this.infoDiv) {
|
||||
this.animationTimer = setTimeout(() => {
|
||||
if (!this.infoDiv) {
|
||||
@ -115,7 +115,7 @@ export class GalleryPhotoComponent implements IRenderable, OnInit, OnDestroy {
|
||||
|
||||
mouseOut() {
|
||||
this.infoBar.marginTop = 0;
|
||||
this.infoBar.background = "rgba(0,0,0,0.0)";
|
||||
this.infoBar.background = 'rgba(0,0,0,0.0)';
|
||||
if (this.animationTimer != null) {
|
||||
clearTimeout(this.animationTimer);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {Component, ElementRef, EventEmitter, Input, Output} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../../common/entities/PhotoDTO";
|
||||
import {Config} from "../../../../../common/config/public/Config";
|
||||
import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../../../common/config/public/Config';
|
||||
|
||||
@Component({
|
||||
selector: 'info-panel',
|
||||
@ -21,7 +21,7 @@ export class InfoPanelLightboxComponent {
|
||||
}
|
||||
|
||||
calcFileSize() {
|
||||
let postFixes = ["B", "KB", "MB", "GB", "TB"];
|
||||
let postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
let index = 0;
|
||||
let size = this.photo.metadata.fileSize;
|
||||
while (size > 1000 && index < postFixes.length - 1) {
|
||||
@ -42,8 +42,8 @@ export class InfoPanelLightboxComponent {
|
||||
|
||||
getDate() {
|
||||
const date = new Date(this.photo.metadata.creationDate);
|
||||
let locale = "en-us";
|
||||
return date.toLocaleString(locale, {month: "long"}) + " " + date.getDate();
|
||||
let locale = 'en-us';
|
||||
return date.toLocaleString(locale, {month: 'long'}) + ' ' + date.getDate();
|
||||
}
|
||||
|
||||
getTime() {
|
||||
@ -53,31 +53,31 @@ export class InfoPanelLightboxComponent {
|
||||
|
||||
getDay() {
|
||||
const date = new Date(this.photo.metadata.creationDate);
|
||||
let locale = "en-us";
|
||||
return date.toLocaleString(locale, {weekday: "long"});
|
||||
let locale = 'en-us';
|
||||
return date.toLocaleString(locale, {weekday: 'long'});
|
||||
}
|
||||
|
||||
toFraction(f) {
|
||||
if (f > 1) {
|
||||
return f;
|
||||
}
|
||||
return "1/" + (1 / f);
|
||||
return '1/' + (1 / f);
|
||||
}
|
||||
|
||||
hasGPS() {
|
||||
return this.photo.metadata.positionData && this.photo.metadata.positionData.GPSData &&
|
||||
this.photo.metadata.positionData.GPSData.latitude && this.photo.metadata.positionData.GPSData.longitude
|
||||
this.photo.metadata.positionData.GPSData.latitude && this.photo.metadata.positionData.GPSData.longitude;
|
||||
}
|
||||
|
||||
getPositionText(): string {
|
||||
if (!this.photo.metadata.positionData) {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
let str = this.photo.metadata.positionData.city ||
|
||||
this.photo.metadata.positionData.state;
|
||||
|
||||
if (str.length != 0) {
|
||||
str += ", ";
|
||||
str += ', ';
|
||||
}
|
||||
str += this.photo.metadata.positionData.country;
|
||||
|
||||
|
||||
@ -1,23 +1,13 @@
|
||||
import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
OnDestroy,
|
||||
Output,
|
||||
QueryList,
|
||||
ViewChild
|
||||
} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {GalleryPhotoComponent} from "../grid/photo/photo.grid.gallery.component";
|
||||
import {Dimension} from "../../model/IRenderable";
|
||||
import {FullScreenService} from "../fullscreen.service";
|
||||
import {OverlayService} from "../overlay.service";
|
||||
import {Subscription} from "rxjs";
|
||||
import {animate, AnimationBuilder, AnimationPlayer, style} from "@angular/animations";
|
||||
import {GalleryLightboxPhotoComponent} from "./photo/photo.lightbox.gallery.component";
|
||||
import {Observable} from "rxjs/Observable";
|
||||
import {ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, OnDestroy, Output, QueryList, ViewChild} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {GalleryPhotoComponent} from '../grid/photo/photo.grid.gallery.component';
|
||||
import {Dimension} from '../../model/IRenderable';
|
||||
import {FullScreenService} from '../fullscreen.service';
|
||||
import {OverlayService} from '../overlay.service';
|
||||
import {Subscription} from 'rxjs';
|
||||
import {animate, AnimationBuilder, AnimationPlayer, style} from '@angular/animations';
|
||||
import {GalleryLightboxPhotoComponent} from './photo/photo.lightbox.gallery.component';
|
||||
import {Observable} from 'rxjs/Observable';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-lightbox',
|
||||
@ -28,8 +18,8 @@ export class GalleryLightboxComponent implements OnDestroy {
|
||||
|
||||
|
||||
@Output('onLastElement') onLastElement = new EventEmitter();
|
||||
@ViewChild("photo") photoElement: GalleryLightboxPhotoComponent;
|
||||
@ViewChild("lightbox") lightboxElement: ElementRef;
|
||||
@ViewChild('photo') photoElement: GalleryLightboxPhotoComponent;
|
||||
@ViewChild('lightbox') lightboxElement: ElementRef;
|
||||
|
||||
public navigation = {hasPrev: true, hasNext: true};
|
||||
public blackCanvasOpacity: any = 0;
|
||||
@ -108,40 +98,13 @@ export class GalleryLightboxComponent implements OnDestroy {
|
||||
this.updateActivePhoto(photoIndex, resize);
|
||||
}
|
||||
|
||||
private updateActivePhoto(photoIndex: number, resize: boolean = true) {
|
||||
let pcList = this.gridPhotoQL.toArray();
|
||||
|
||||
|
||||
if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) {
|
||||
throw new Error("Can't find the photo");
|
||||
}
|
||||
this.activePhotoId = photoIndex;
|
||||
this.activePhoto = pcList[photoIndex];
|
||||
|
||||
if (resize) {
|
||||
this.animatePhoto(this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo));
|
||||
}
|
||||
this.navigation.hasPrev = photoIndex > 0;
|
||||
this.navigation.hasNext = photoIndex + 1 < pcList.length;
|
||||
|
||||
let to = this.activePhoto.getDimension();
|
||||
|
||||
//if target image out of screen -> scroll to there
|
||||
if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getPhotoFrameHeight() < to.top) {
|
||||
this.setBodyScrollTop(to.top);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
startPhotoDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
||||
|
||||
public show(photo: PhotoDTO) {
|
||||
this.controllersVisible = true;
|
||||
this.showControls();
|
||||
this.visible = true;
|
||||
let selectedPhoto = this.findPhotoComponent(photo);
|
||||
if (selectedPhoto === null) {
|
||||
throw new Error("Can't find Photo");
|
||||
throw new Error('Can\'t find Photo');
|
||||
}
|
||||
|
||||
const lightboxDimension = selectedPhoto.getDimension();
|
||||
@ -168,6 +131,33 @@ export class GalleryLightboxComponent implements OnDestroy {
|
||||
this.showPhoto(this.gridPhotoQL.toArray().indexOf(selectedPhoto), false);
|
||||
}
|
||||
|
||||
startPhotoDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
|
||||
|
||||
private updateActivePhoto(photoIndex: number, resize: boolean = true) {
|
||||
let pcList = this.gridPhotoQL.toArray();
|
||||
|
||||
|
||||
if (photoIndex < 0 || photoIndex > this.gridPhotoQL.length) {
|
||||
throw new Error('Can\'t find the photo');
|
||||
}
|
||||
this.activePhotoId = photoIndex;
|
||||
this.activePhoto = pcList[photoIndex];
|
||||
|
||||
if (resize) {
|
||||
this.animatePhoto(this.calcLightBoxPhotoDimension(this.activePhoto.gridPhoto.photo));
|
||||
}
|
||||
this.navigation.hasPrev = photoIndex > 0;
|
||||
this.navigation.hasNext = photoIndex + 1 < pcList.length;
|
||||
|
||||
let to = this.activePhoto.getDimension();
|
||||
|
||||
//if target image out of screen -> scroll to there
|
||||
if (this.getBodyScrollTop() > to.top || this.getBodyScrollTop() + this.getPhotoFrameHeight() < to.top) {
|
||||
this.setBodyScrollTop(to.top);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.controllersVisible = false;
|
||||
this.fullScreenService.exitFullScreen();
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
.imgContainer img {
|
||||
position: absolute;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.imgContainer {
|
||||
justify-content: center; /* add to align horizontal */
|
||||
align-items: center; /* add to align vertical */
|
||||
justify-content: center; /* add to align horizontal */
|
||||
align-items: center; /* add to align vertical */
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<div class="imgContainer" #imgContainer>
|
||||
<img *ngIf="showThumbnail()"
|
||||
[style.width.%]="imageSize.width"
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="thumbnailPath()"/>
|
||||
<img *ngIf="showThumbnail()"
|
||||
[style.width.%]="imageSize.width"
|
||||
[style.height.%]="imageSize.height"
|
||||
[src]="thumbnailPath()"/>
|
||||
|
||||
<img *ngIf="gridPhoto !== null && loadImage"
|
||||
[style.width.%]="imageSize.width"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Component, ElementRef, Input, OnChanges} from "@angular/core";
|
||||
import {GridPhoto} from "../../grid/GridPhoto";
|
||||
import {Component, ElementRef, Input, OnChanges} from '@angular/core';
|
||||
import {GridPhoto} from '../../grid/GridPhoto';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-lightbox-photo',
|
||||
@ -12,7 +12,7 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
@Input() loadImage: boolean = false;
|
||||
@Input() windowAspect: number = 1;
|
||||
|
||||
public imageSize = {width: "auto", height: "100"};
|
||||
public imageSize = {width: 'auto', height: '100'};
|
||||
|
||||
imageLoaded: boolean = false;
|
||||
public imageLoadFinished: boolean = false;
|
||||
@ -27,6 +27,32 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
this.setImageSize();
|
||||
}
|
||||
|
||||
onImageError() {
|
||||
//TODO:handle error
|
||||
this.imageLoadFinished = true;
|
||||
console.error('cant load image');
|
||||
}
|
||||
|
||||
|
||||
onImageLoad() {
|
||||
this.imageLoadFinished = true;
|
||||
this.imageLoaded = true;
|
||||
}
|
||||
|
||||
public thumbnailPath(): string {
|
||||
if (this.gridPhoto.isThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getThumbnailPath();
|
||||
|
||||
if (this.gridPhoto.isReplacementThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getReplacementThumbnailPath();
|
||||
return null;
|
||||
}
|
||||
|
||||
public showThumbnail(): boolean {
|
||||
return this.gridPhoto && !this.imageLoaded &&
|
||||
(this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable());
|
||||
}
|
||||
|
||||
private setImageSize() {
|
||||
if (!this.gridPhoto) {
|
||||
return;
|
||||
@ -36,39 +62,13 @@ export class GalleryLightboxPhotoComponent implements OnChanges {
|
||||
const photoAspect = this.gridPhoto.photo.metadata.size.width / this.gridPhoto.photo.metadata.size.height;
|
||||
|
||||
if (photoAspect < this.windowAspect) {
|
||||
this.imageSize.height = "100";
|
||||
this.imageSize.height = '100';
|
||||
this.imageSize.width = null;
|
||||
} else {
|
||||
this.imageSize.height = null;
|
||||
this.imageSize.width = "100";
|
||||
this.imageSize.width = '100';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onImageLoad() {
|
||||
this.imageLoadFinished = true;
|
||||
this.imageLoaded = true;
|
||||
}
|
||||
|
||||
onImageError() {
|
||||
//TODO:handle error
|
||||
this.imageLoadFinished = true;
|
||||
console.error("cant load image");
|
||||
}
|
||||
|
||||
public showThumbnail(): boolean {
|
||||
return this.gridPhoto && !this.imageLoaded &&
|
||||
(this.gridPhoto.isThumbnailAvailable() || this.gridPhoto.isReplacementThumbnailAvailable());
|
||||
}
|
||||
|
||||
public thumbnailPath(): string {
|
||||
if (this.gridPhoto.isThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getThumbnailPath();
|
||||
|
||||
if (this.gridPhoto.isReplacementThumbnailAvailable() === true)
|
||||
return this.gridPhoto.getReplacementThumbnailPath();
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1,67 +1,67 @@
|
||||
.lightbox {
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1100; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: hidden;
|
||||
display: flex; /* add */
|
||||
justify-content: center; /* add to align horizontal */
|
||||
align-items: center; /* add to align vertical */
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1100; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: hidden;
|
||||
display: flex; /* add */
|
||||
justify-content: center; /* add to align horizontal */
|
||||
align-items: center; /* add to align vertical */
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.sebm-google-map-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.blackCanvas {
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1099; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
background-color: black;
|
||||
transition: all 0.3s ease-in-out;
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1099; /* Sit on top */
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
background-color: black;
|
||||
transition: all 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
#controllers-container {
|
||||
z-index: 1100;
|
||||
right: 0;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
z-index: 1100;
|
||||
right: 0;
|
||||
top: 0;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
#controls {
|
||||
top: 0;
|
||||
height: initial;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
font-size: large;
|
||||
top: 0;
|
||||
height: initial;
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
#controls span {
|
||||
margin-left: 6px;
|
||||
margin-right: 6px;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
margin-left: 6px;
|
||||
margin-right: 6px;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
opacity: 0.4;
|
||||
transition: opacity .2s ease-out;
|
||||
-moz-transition: opacity .2s ease-out;
|
||||
-webkit-transition: opacity .2s ease-out;
|
||||
-o-transition: opacity .2s ease-out;
|
||||
opacity: 0.4;
|
||||
transition: opacity .2s ease-out;
|
||||
-moz-transition: opacity .2s ease-out;
|
||||
-webkit-transition: opacity .2s ease-out;
|
||||
-o-transition: opacity .2s ease-out;
|
||||
}
|
||||
|
||||
.highlight:hover {
|
||||
opacity: 1.0;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.preview-loading {
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../../common/entities/PhotoDTO";
|
||||
import {Dimension} from "../../../model/IRenderable";
|
||||
import {FullScreenService} from "../../fullscreen.service";
|
||||
import {AgmMap} from "@agm/core";
|
||||
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from "../../thumnailManager.service";
|
||||
import {IconPhoto} from "../../IconPhoto";
|
||||
import {Photo} from "../../Photo";
|
||||
import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
|
||||
import {Dimension} from '../../../model/IRenderable';
|
||||
import {FullScreenService} from '../../fullscreen.service';
|
||||
import {AgmMap} from '@agm/core';
|
||||
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../thumnailManager.service';
|
||||
import {IconPhoto} from '../../IconPhoto';
|
||||
import {Photo} from '../../Photo';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-map-lightbox',
|
||||
@ -23,7 +23,7 @@ export class GalleryMapLightboxComponent implements OnChanges {
|
||||
mapPhotos: MapPhoto[] = [];
|
||||
mapCenter = {latitude: 0, longitude: 0};
|
||||
|
||||
@ViewChild("root") elementRef: ElementRef;
|
||||
@ViewChild('root') elementRef: ElementRef;
|
||||
|
||||
@ViewChild(AgmMap) map: AgmMap;
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
.sebm-google-map-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#map {
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import {Component, ElementRef, Input, OnChanges, ViewChild} from "@angular/core";
|
||||
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||
import {Dimension, IRenderable} from "../../model/IRenderable";
|
||||
import {GalleryMapLightboxComponent} from "./lightbox/lightbox.map.gallery.component";
|
||||
import {Component, ElementRef, Input, OnChanges, ViewChild} from '@angular/core';
|
||||
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
|
||||
import {Dimension, IRenderable} from '../../model/IRenderable';
|
||||
import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.component';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-map',
|
||||
templateUrl: './map.gallery.component.html',
|
||||
@ -14,7 +15,7 @@ export class GalleryMapComponent implements OnChanges, IRenderable {
|
||||
|
||||
mapPhotos: Array<{ latitude: number, longitude: number }> = [];
|
||||
mapCenter = {latitude: 0, longitude: 0};
|
||||
@ViewChild("map") map: ElementRef;
|
||||
@ViewChild('map') map: ElementRef;
|
||||
|
||||
//TODO: fix zooming
|
||||
ngOnChanges() {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import {Component, Input, OnChanges} from "@angular/core";
|
||||
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {UserDTO} from "../../../../common/entities/UserDTO";
|
||||
import {AuthenticationService} from "../../model/network/authentication.service";
|
||||
import {ShareService} from "../share.service";
|
||||
import {I18n} from "@ngx-translate/i18n-polyfill";
|
||||
import {Component, Input, OnChanges} from '@angular/core';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {RouterLink} from '@angular/router';
|
||||
import {UserDTO} from '../../../../common/entities/UserDTO';
|
||||
import {AuthenticationService} from '../../model/network/authentication.service';
|
||||
import {ShareService} from '../share.service';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-navbar',
|
||||
@ -31,14 +31,14 @@ export class GalleryNavigatorComponent implements OnChanges {
|
||||
return [];
|
||||
}
|
||||
|
||||
let path = this.directory.path.replace(new RegExp("\\\\", 'g'), "/");
|
||||
let path = this.directory.path.replace(new RegExp('\\\\', 'g'), '/');
|
||||
|
||||
let dirs = path.split("/");
|
||||
let dirs = path.split('/');
|
||||
dirs.push(this.directory.name);
|
||||
|
||||
//removing empty strings
|
||||
for (let i = 0; i < dirs.length; i++) {
|
||||
if (!dirs[i] || 0 === dirs[i].length || "." === dirs[i]) {
|
||||
if (!dirs[i] || 0 === dirs[i].length || '.' === dirs[i]) {
|
||||
dirs.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
@ -49,14 +49,14 @@ export class GalleryNavigatorComponent implements OnChanges {
|
||||
|
||||
//create root link
|
||||
if (dirs.length == 0) {
|
||||
arr.push({name: this.i18n("Images"), route: null});
|
||||
arr.push({name: this.i18n('Images'), route: null});
|
||||
} else {
|
||||
arr.push({name: this.i18n("Images"), route: UserDTO.isPathAvailable("/", user.permissions) ? "/" : null});
|
||||
arr.push({name: this.i18n('Images'), route: UserDTO.isPathAvailable('/', user.permissions) ? '/' : null});
|
||||
}
|
||||
|
||||
//create rest navigation
|
||||
dirs.forEach((name, index) => {
|
||||
const route = dirs.slice(0, dirs.indexOf(name) + 1).join("/");
|
||||
const route = dirs.slice(0, dirs.indexOf(name) + 1).join('/');
|
||||
if (dirs.length - 1 == index) {
|
||||
arr.push({name: name, route: null});
|
||||
} else {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Event} from "../../../common/event/Event";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {Event} from '../../../common/event/Event';
|
||||
|
||||
@Injectable()
|
||||
export class OverlayService {
|
||||
@ -24,20 +24,20 @@ export class OverlayService {
|
||||
if (this.scrollWidth == null) {
|
||||
|
||||
|
||||
let outer = document.createElement("div");
|
||||
outer.style.visibility = "hidden";
|
||||
outer.style.width = "100px";
|
||||
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
|
||||
let outer = document.createElement('div');
|
||||
outer.style.visibility = 'hidden';
|
||||
outer.style.width = '100px';
|
||||
outer.style.msOverflowStyle = 'scrollbar'; // needed for WinJS apps
|
||||
|
||||
document.body.appendChild(outer);
|
||||
|
||||
let widthNoScroll = outer.offsetWidth;
|
||||
// force scrollbars
|
||||
outer.style.overflowY = "scroll";
|
||||
outer.style.overflowY = 'scroll';
|
||||
|
||||
// add innerdiv
|
||||
let inner = document.createElement("div");
|
||||
inner.style.width = "100%";
|
||||
let inner = document.createElement('div');
|
||||
inner.style.width = '100%';
|
||||
outer.appendChild(inner);
|
||||
|
||||
let widthWithScroll = inner.offsetWidth;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {NetworkService} from "../../model/network/network.service";
|
||||
import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem";
|
||||
import {GalleryCacheService} from "../cache.gallery.service";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../../model/network/network.service';
|
||||
import {AutoCompleteItem} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {GalleryCacheService} from '../cache.gallery.service';
|
||||
|
||||
@Injectable()
|
||||
export class AutoCompleteService {
|
||||
@ -14,7 +14,7 @@ export class AutoCompleteService {
|
||||
public async autoComplete(text: string): Promise<Array<AutoCompleteItem>> {
|
||||
let items: Array<AutoCompleteItem> = this.galleryCacheService.getAutoComplete(text);
|
||||
if (items == null) {
|
||||
items = await this._networkService.getJson<Array<AutoCompleteItem>>("/autocomplete/" + text);
|
||||
items = await this._networkService.getJson<Array<AutoCompleteItem>>('/autocomplete/' + text);
|
||||
this.galleryCacheService.setAutoComplete(text, items);
|
||||
}
|
||||
return items;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Component} from "@angular/core";
|
||||
import {AutoCompleteService} from "./autocomplete.service";
|
||||
import {AutoCompleteItem, SearchTypes} from "../../../../common/entities/AutoCompleteItem";
|
||||
import {ActivatedRoute, Params, RouterLink} from "@angular/router";
|
||||
import {GalleryService} from "../gallery.service";
|
||||
import {Config} from "../../../../common/config/public/Config";
|
||||
import {Component} from '@angular/core';
|
||||
import {AutoCompleteService} from './autocomplete.service';
|
||||
import {AutoCompleteItem, SearchTypes} from '../../../../common/entities/AutoCompleteItem';
|
||||
import {ActivatedRoute, Params, RouterLink} from '@angular/router';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery-search',
|
||||
@ -14,10 +14,10 @@ import {Config} from "../../../../common/config/public/Config";
|
||||
export class GallerySearchComponent {
|
||||
|
||||
autoCompleteItems: Array<AutoCompleteRenderItem> = [];
|
||||
public searchText: string = "";
|
||||
public searchText: string = '';
|
||||
private cache = {
|
||||
lastAutocomplete: "",
|
||||
lastInstantSearch: ""
|
||||
lastAutocomplete: '',
|
||||
lastInstantSearch: ''
|
||||
};
|
||||
|
||||
SearchTypes: any = [];
|
||||
@ -32,7 +32,7 @@ export class GallerySearchComponent {
|
||||
|
||||
this.subscription = this._route.params.subscribe((params: Params) => {
|
||||
let searchText = params['searchText'];
|
||||
if (searchText && searchText != "") {
|
||||
if (searchText && searchText != '') {
|
||||
this.searchText = searchText;
|
||||
}
|
||||
});
|
||||
@ -41,7 +41,7 @@ export class GallerySearchComponent {
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.subscription !== null) {
|
||||
this.subscription.unsubscribe()
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,9 +94,9 @@ export class GallerySearchComponent {
|
||||
|
||||
private async autocomplete(searchText: string) {
|
||||
if (!Config.Client.Search.autocompleteEnabled) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (searchText.trim() == ".") {
|
||||
if (searchText.trim() == '.') {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -129,9 +129,9 @@ export class GallerySearchComponent {
|
||||
}
|
||||
|
||||
class AutoCompleteRenderItem {
|
||||
public preText: string = "";
|
||||
public highLightText: string = "";
|
||||
public postText: string = "";
|
||||
public preText: string = '';
|
||||
public highLightText: string = '';
|
||||
public postText: string = '';
|
||||
public type: SearchTypes;
|
||||
|
||||
constructor(public text: string, searchText: string, type: SearchTypes) {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {NetworkService} from "../model/network/network.service";
|
||||
import {CreateSharingDTO, SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
import {Router, RoutesRecognized} from "@angular/router";
|
||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {NetworkService} from '../model/network/network.service';
|
||||
import {CreateSharingDTO, SharingDTO} from '../../../common/entities/SharingDTO';
|
||||
import {Router, RoutesRecognized} from '@angular/router';
|
||||
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class ShareService {
|
||||
@ -27,8 +27,8 @@ export class ShareService {
|
||||
|
||||
this.router.events.subscribe(val => {
|
||||
if (val instanceof RoutesRecognized) {
|
||||
this.param = val.state.root.firstChild.params["sharingKey"] || null;
|
||||
this.queryParam = val.state.root.firstChild.queryParams["sk"] || null;
|
||||
this.param = val.state.root.firstChild.params['sharingKey'] || null;
|
||||
this.queryParam = val.state.root.firstChild.queryParams['sk'] || null;
|
||||
const changed = this.sharingKey != this.param || this.queryParam;
|
||||
if (changed) {
|
||||
this.sharingKey = this.param || this.queryParam;
|
||||
@ -50,7 +50,7 @@ export class ShareService {
|
||||
}
|
||||
|
||||
public createSharing(dir: string, includeSubfolders: boolean, valid: number): Promise<SharingDTO> {
|
||||
return this._networkService.postJson("/share/" + dir, {
|
||||
return this._networkService.postJson('/share/' + dir, {
|
||||
createSharing: <CreateSharingDTO>{
|
||||
includeSubfolders: includeSubfolders,
|
||||
valid: valid
|
||||
@ -59,7 +59,7 @@ export class ShareService {
|
||||
}
|
||||
|
||||
public updateSharing(dir: string, sharingId: number, includeSubfolders: boolean, password: string, valid: number): Promise<SharingDTO> {
|
||||
return this._networkService.putJson("/share/" + dir, {
|
||||
return this._networkService.putJson('/share/' + dir, {
|
||||
updateSharing: <CreateSharingDTO>{
|
||||
id: sharingId,
|
||||
includeSubfolders: includeSubfolders,
|
||||
@ -79,7 +79,7 @@ export class ShareService {
|
||||
}
|
||||
|
||||
public async getSharing(): Promise<SharingDTO> {
|
||||
const sharing = await this._networkService.getJson<SharingDTO>("/share/" + this.getSharingKey());
|
||||
const sharing = await this._networkService.getJson<SharingDTO>('/share/' + this.getSharingKey());
|
||||
this.sharing.next(sharing);
|
||||
return sharing;
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
|
||||
import {Utils} from "../../../../common/Utils";
|
||||
import {ShareService} from "../share.service";
|
||||
import {GalleryService} from "../gallery.service";
|
||||
import {ContentWrapper} from "../../../../common/entities/ConentWrapper";
|
||||
import {SharingDTO} from "../../../../common/entities/SharingDTO";
|
||||
import {ModalDirective} from "ngx-bootstrap/modal";
|
||||
import {Config} from "../../../../common/config/public/Config";
|
||||
import {NotificationService} from "../../model/notification.service";
|
||||
import {DirectoryDTO} from "../../../../common/entities/DirectoryDTO";
|
||||
import {I18n} from "@ngx-translate/i18n-polyfill";
|
||||
import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
|
||||
import {Utils} from '../../../../common/Utils';
|
||||
import {ShareService} from '../share.service';
|
||||
import {GalleryService} from '../gallery.service';
|
||||
import {ContentWrapper} from '../../../../common/entities/ConentWrapper';
|
||||
import {SharingDTO} from '../../../../common/entities/SharingDTO';
|
||||
import {ModalDirective} from 'ngx-bootstrap/modal';
|
||||
import {Config} from '../../../../common/config/public/Config';
|
||||
import {NotificationService} from '../../model/notification.service';
|
||||
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
|
||||
import {I18n} from '@ngx-translate/i18n-polyfill';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -20,7 +20,7 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||
@ViewChild('shareModal') public childModal: ModalDirective;
|
||||
|
||||
enabled: boolean = true;
|
||||
url: string = "";
|
||||
url: string = '';
|
||||
|
||||
input = {
|
||||
includeSubfolders: true,
|
||||
@ -28,9 +28,9 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||
amount: 30,
|
||||
type: ValidityTypes.Days
|
||||
},
|
||||
password: ""
|
||||
password: ''
|
||||
};
|
||||
currentDir: string = "";
|
||||
currentDir: string = '';
|
||||
sharing: SharingDTO = null;
|
||||
contentSubscription = null;
|
||||
passwordProtection = false;
|
||||
@ -72,33 +72,33 @@ export class GalleryShareComponent implements OnInit, OnDestroy {
|
||||
case ValidityTypes.Months:
|
||||
return this.input.valid.amount * 1000 * 60 * 60 * 24 * 30;
|
||||
}
|
||||
throw new Error("unknown type: " + this.input.valid.type);
|
||||
throw new Error('unknown type: ' + this.input.valid.type);
|
||||
}
|
||||
|
||||
async update() {
|
||||
if (this.sharing == null) {
|
||||
return;
|
||||
}
|
||||
this.url = "loading..";
|
||||
this.url = 'loading..';
|
||||
this.sharing = await this._sharingService.updateSharing(this.currentDir, this.sharing.id, this.input.includeSubfolders, this.input.password, this.calcValidity());
|
||||
this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey
|
||||
this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey;
|
||||
}
|
||||
|
||||
async get() {
|
||||
this.url = "loading..";
|
||||
this.url = 'loading..';
|
||||
this.sharing = await this._sharingService.createSharing(this.currentDir, this.input.includeSubfolders, this.calcValidity());
|
||||
this.url = Config.Client.publicUrl + "/share/" + this.sharing.sharingKey
|
||||
this.url = Config.Client.publicUrl + '/share/' + this.sharing.sharingKey;
|
||||
}
|
||||
|
||||
async showModal() {
|
||||
await this.get();
|
||||
this.input.password = "";
|
||||
this.input.password = '';
|
||||
this.childModal.show();
|
||||
document.body.style.paddingRight = "0px";
|
||||
document.body.style.paddingRight = '0px';
|
||||
}
|
||||
|
||||
onCopy() {
|
||||
this._notification.success(this.i18n("Url has been copied to clipboard"));
|
||||
this._notification.success(this.i18n('Url has been copied to clipboard'));
|
||||
}
|
||||
|
||||
public hideModal() {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {GalleryCacheService} from "./cache.gallery.service";
|
||||
import {Photo} from "./Photo";
|
||||
import {IconPhoto} from "./IconPhoto";
|
||||
import {PhotoDTO} from "../../../common/entities/PhotoDTO";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {GalleryCacheService} from './cache.gallery.service';
|
||||
import {Photo} from './Photo';
|
||||
import {IconPhoto} from './IconPhoto';
|
||||
import {PhotoDTO} from '../../../common/entities/PhotoDTO';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
|
||||
export enum ThumbnailLoadingPriority {
|
||||
extraHigh = 4, high = 3, medium = 2, low = 1
|
||||
@ -23,7 +23,7 @@ export class ThumbnailLoaderService {
|
||||
|
||||
let index = taskEntry.parentTask.taskEntities.indexOf(taskEntry);
|
||||
if (index == -1) {
|
||||
throw new Error("ThumbnailTaskEntity not exist on Task");
|
||||
throw new Error('ThumbnailTaskEntity not exist on Task');
|
||||
}
|
||||
taskEntry.parentTask.taskEntities.splice(index, 1);
|
||||
|
||||
@ -31,7 +31,7 @@ export class ThumbnailLoaderService {
|
||||
&& taskEntry.parentTask.inProgress == false) {
|
||||
let i = this.que.indexOf(taskEntry.parentTask);
|
||||
if (i == -1) {
|
||||
throw new Error("ThumbnailTask not exist");
|
||||
throw new Error('ThumbnailTask not exist');
|
||||
}
|
||||
this.que.splice(i, 1);
|
||||
}
|
||||
@ -136,7 +136,7 @@ export class ThumbnailLoaderService {
|
||||
let i = this.que.indexOf(task);
|
||||
if (i == -1) {
|
||||
if (task.taskEntities.length !== 0) {
|
||||
console.error("ThumbnailLoader: can't find poolTask to remove");
|
||||
console.error('ThumbnailLoader: can\'t find poolTask to remove');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {
|
||||
ThumbnailLoaderService,
|
||||
ThumbnailLoadingListener,
|
||||
ThumbnailLoadingPriority,
|
||||
ThumbnailTaskEntity
|
||||
} from "./thumnailLoader.service";
|
||||
import {Photo} from "./Photo";
|
||||
import {IconPhoto} from "./IconPhoto";
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ThumbnailLoaderService, ThumbnailLoadingListener, ThumbnailLoadingPriority, ThumbnailTaskEntity} from './thumnailLoader.service';
|
||||
import {Photo} from './Photo';
|
||||
import {IconPhoto} from './IconPhoto';
|
||||
|
||||
|
||||
@Injectable()
|
||||
@ -80,7 +75,7 @@ export class IconThumbnail extends ThumbnailBase {
|
||||
|
||||
constructor(private photo: IconPhoto, thumbnailService: ThumbnailLoaderService) {
|
||||
super(thumbnailService);
|
||||
this.src = "";
|
||||
this.src = '';
|
||||
this.error = false;
|
||||
if (this.photo.isIconAvailable()) {
|
||||
this.src = this.photo.getIconPath();
|
||||
@ -166,28 +161,28 @@ export class Thumbnail extends ThumbnailBase {
|
||||
public load() {
|
||||
if (!this.photo.isThumbnailAvailable() && this.thumbnailTask == null) {
|
||||
// setTimeout(() => {
|
||||
let listener: ThumbnailLoadingListener = {
|
||||
onStartedLoading: () => { //onLoadStarted
|
||||
this.loading = true;
|
||||
},
|
||||
onLoad: () => {//onLoaded
|
||||
this.src = this.photo.getThumbnailPath();
|
||||
if (this.onLoad) this.onLoad();
|
||||
this.available = true;
|
||||
this.loading = false;
|
||||
this.thumbnailTask = null;
|
||||
},
|
||||
onError: (error) => {//onError
|
||||
this.thumbnailTask = null;
|
||||
this.loading = false;
|
||||
this.error = true;
|
||||
}
|
||||
};
|
||||
if (this.photo.isReplacementThumbnailAvailable()) {
|
||||
this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.medium, listener);
|
||||
} else {
|
||||
this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener);
|
||||
let listener: ThumbnailLoadingListener = {
|
||||
onStartedLoading: () => { //onLoadStarted
|
||||
this.loading = true;
|
||||
},
|
||||
onLoad: () => {//onLoaded
|
||||
this.src = this.photo.getThumbnailPath();
|
||||
if (this.onLoad) this.onLoad();
|
||||
this.available = true;
|
||||
this.loading = false;
|
||||
this.thumbnailTask = null;
|
||||
},
|
||||
onError: (error) => {//onError
|
||||
this.thumbnailTask = null;
|
||||
this.loading = false;
|
||||
this.error = true;
|
||||
}
|
||||
};
|
||||
if (this.photo.isReplacementThumbnailAvailable()) {
|
||||
this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.medium, listener);
|
||||
} else {
|
||||
this.thumbnailTask = this.thumbnailService.loadImage(this.photo, ThumbnailLoadingPriority.high, listener);
|
||||
}
|
||||
// }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Component, Input} from "@angular/core";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {Cookie} from "ng2-cookies";
|
||||
import {CookieNames} from "../../../common/CookieNames";
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {Cookie} from 'ng2-cookies';
|
||||
import {CookieNames} from '../../../common/CookieNames';
|
||||
|
||||
@Component({
|
||||
selector: 'language',
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Component, OnInit} from "@angular/core";
|
||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
||||
import {AuthenticationService} from "../model/network/authentication.service";
|
||||
import {ErrorCodes} from "../../../common/entities/Error";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {NavigationService} from "../model/navigation.service";
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {LoginCredential} from '../../../common/entities/LoginCredential';
|
||||
import {AuthenticationService} from '../model/network/authentication.service';
|
||||
import {ErrorCodes} from '../../../common/entities/Error';
|
||||
import {Config} from '../../../common/config/public/Config';
|
||||
import {NavigationService} from '../model/navigation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'login',
|
||||
|
||||
@ -11,6 +11,6 @@ export interface Dimension {
|
||||
|
||||
export module Dimension {
|
||||
export const toString = (dim: Dimension) => {
|
||||
return {top: dim.top + "px", left: dim.left + "px", width: dim.width + "px", height: dim.height + "px"};
|
||||
}
|
||||
return {top: dim.top + 'px', left: dim.left + 'px', width: dim.width + 'px', height: dim.height + 'px'};
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
import {Router} from "@angular/router";
|
||||
import {ShareService} from "../gallery/share.service";
|
||||
import {Router} from '@angular/router';
|
||||
import {ShareService} from '../gallery/share.service';
|
||||
|
||||
@Injectable()
|
||||
export class NavigationService {
|
||||
@ -17,22 +17,22 @@ export class NavigationService {
|
||||
}
|
||||
|
||||
public async toLogin() {
|
||||
console.log("toLogin");
|
||||
console.log('toLogin');
|
||||
await this._shareService.wait();
|
||||
if (this._shareService.isSharing()) {
|
||||
return this._router.navigate(["shareLogin"], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
return this._router.navigate(['shareLogin'], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
} else {
|
||||
return this._router.navigate(["login"]);
|
||||
return this._router.navigate(['login']);
|
||||
}
|
||||
}
|
||||
|
||||
public async toGallery() {
|
||||
console.log("toGallery");
|
||||
console.log('toGallery');
|
||||
await this._shareService.wait();
|
||||
if (this._shareService.isSharing()) {
|
||||
return this._router.navigate(["gallery", ""], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
return this._router.navigate(['gallery', ''], {queryParams: {sk: this._shareService.getSharingKey()}});
|
||||
} else {
|
||||
return this._router.navigate(["gallery", ""]);
|
||||
return this._router.navigate(['gallery', '']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user