diff --git a/backend/config/Config.ts b/backend/config/Config.ts index 25f16e8..d154e55 100644 --- a/backend/config/Config.ts +++ b/backend/config/Config.ts @@ -1,23 +1,18 @@ -import {ConfigLoader} from "./ConfigLoader"; +/// + +import {ConfigLoader} from "./../../backend/config/ConfigLoader"; import * as path from "path"; +import {ConfigClass, DatabaseType} from "../../common/config/Config"; -export enum DatabaseType{ - memory, mongoDB -} +export var Config = new ConfigClass(); -export class ConfigClass { +Config.Server = { + port: 80, + thumbnailSizes: [200], + imagesFolder: "/demo/images", + thumbnailFolder: "/demo/TEMP", + databaseType: DatabaseType.mongoDB +}; - constructor() { - ConfigLoader.init(this, path.join(__dirname, './../../config.json')); - } - - public PORT:number = 80; - - public thumbnailSizes:Array = [200]; - public imagesFolder:string = "/demo/images"; - public thumbnailFolder:string = "/demo/TEMP"; - public databaseType:DatabaseType = DatabaseType.mongoDB; -} - - -export var Config = new ConfigClass(); \ No newline at end of file +ConfigLoader.init(Config, path.join(__dirname, './../../config.json'), [["PORT", "Server-port"]]); + \ No newline at end of file diff --git a/backend/config/ConfigLoader.ts b/backend/config/ConfigLoader.ts index 09ac243..82542d5 100644 --- a/backend/config/ConfigLoader.ts +++ b/backend/config/ConfigLoader.ts @@ -3,14 +3,21 @@ import * as optimist from "optimist"; export class ConfigLoader { - static init(configObject:any, configFilePath?:string) { + static init(configObject:any, configFilePath?:string, envAlias:Array> = []) { this.processConfigFile(configFilePath, configObject); this.processArguments(configObject); - this.processEnvVariables(configObject); + this.processEnvVariables(configObject, envAlias); } - private static processEnvVariables(configObject:any) { + private static processEnvVariables(configObject:any, envAlias:Array>) { + let varAliases = {}; + envAlias.forEach((alias)=> { + if (process.env[alias[0]]) { + varAliases[alias[1]] = process.env[alias[0]]; + } + }); + this.processHierarchyVar(configObject, varAliases); this.loadObject(configObject, process.env); }; @@ -18,11 +25,15 @@ export class ConfigLoader { let argv = optimist.argv; delete(argv._); delete(argv.$0); + this.processHierarchyVar(configObject, argv); + }; + + private static processHierarchyVar(configObject:any, vars:any) { let config = {}; - Object.keys(argv).forEach((key)=> { + Object.keys(vars).forEach((key)=> { let keyArray = key.split("-"); - let value = argv[key]; + let value = vars[key]; let setObject = (object, keyArray, value) => { let key = keyArray.shift(); @@ -37,7 +48,7 @@ export class ConfigLoader { }); this.loadObject(configObject, config); - }; + } private static processConfigFile(configFilePath:string, configObject:any) { if (typeof configFilePath !== 'undefined') { diff --git a/backend/middlewares/GalleryMWs.ts b/backend/middlewares/GalleryMWs.ts index 0c4857c..be47291 100644 --- a/backend/middlewares/GalleryMWs.ts +++ b/backend/middlewares/GalleryMWs.ts @@ -3,18 +3,18 @@ import * as fs from "fs"; import {NextFunction, Request, Response} from "express"; import {Error, ErrorCodes} from "../../common/entities/Error"; import {Directory} from "../../common/entities/Directory"; -import {Config} from "../config/Config"; import {ObjectManagerRepository} from "../model/ObjectManagerRepository"; import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem"; import {ContentWrapper} from "../../common/entities/ConentWrapper"; import {SearchResult} from "../../common/entities/SearchResult"; import {Photo} from "../../common/entities/Photo"; +import {Config} from "../config/Config"; export class GalleryMWs { private static getImageFolder() { - return path.join(__dirname, "/../../", Config.imagesFolder); + return path.join(__dirname, "/../../", Config.Server.imagesFolder); } public static listDirectory(req:Request, res:Response, next:NextFunction) { @@ -58,7 +58,14 @@ export class GalleryMWs { public static search(req:Request, res:Response, next:NextFunction) { + if (Config.Client.Search.searchEnabled === false) { + return next(); + } + if (!(req.params.text)) { + return next(); + } + ObjectManagerRepository.getInstance().getSearchManager().search(req.params.text, (err, result:SearchResult) => { if (err || !result) { return next(new Error(ErrorCodes.GENERAL_ERROR, err)); @@ -70,6 +77,10 @@ export class GalleryMWs { public static instantSearch(req:Request, res:Response, next:NextFunction) { + if (Config.Client.Search.instantSearchEnabled === false) { + return next(); + } + if (!(req.params.text)) { return next(); } @@ -84,6 +95,9 @@ export class GalleryMWs { } public static autocomplete(req:Request, res:Response, next:NextFunction) { + if (Config.Client.Search.autocompleteEnabled === false) { + return next(); + } if (!(req.params.text)) { return next(); } diff --git a/backend/middlewares/ThumbnailGeneratorMWs.ts b/backend/middlewares/ThumbnailGeneratorMWs.ts index 6538a71..ea4dc53 100644 --- a/backend/middlewares/ThumbnailGeneratorMWs.ts +++ b/backend/middlewares/ThumbnailGeneratorMWs.ts @@ -13,7 +13,7 @@ import {Config} from "../config/Config"; export class ThumbnailGeneratorMWs { private static getThumbnailFolder() { - return path.join(__dirname, "/../../", Config.thumbnailFolder); + return path.join(__dirname, "/../../", Config.Server.thumbnailFolder); } public static generateThumbnail(req:Request, res:Response, next:NextFunction) { @@ -21,11 +21,11 @@ export class ThumbnailGeneratorMWs { return next(); let imagePath = req.resultPipe; - let size:number = parseInt(req.params.size) || Config.thumbnailSizes[0]; + let size:number = parseInt(req.params.size) || Config.Server.thumbnailSizes[0]; let thumbnailFolder = ThumbnailGeneratorMWs.getThumbnailFolder(); - if (Config.thumbnailSizes.indexOf(size) === -1) { - size = Config.thumbnailSizes[0]; + if (Config.Server.thumbnailSizes.indexOf(size) === -1) { + size = Config.Server.thumbnailSizes[0]; } let thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size)); diff --git a/backend/routes/PublicRouter.ts b/backend/routes/PublicRouter.ts index 16a21ef..aeb5cb2 100644 --- a/backend/routes/PublicRouter.ts +++ b/backend/routes/PublicRouter.ts @@ -4,6 +4,7 @@ import * as _express from "express"; import {NextFunction, Request, Response} from "express"; import * as _path from "path"; import {Utils} from "../../common/Utils"; +import {Config} from "../config/Config"; export class PublicRouter { constructor(private app) { @@ -16,6 +17,7 @@ export class PublicRouter { delete user.password; res.tpl.user = user; } + res.tpl.clientConfig = Config.Client; return next(); }); diff --git a/backend/server.ts b/backend/server.ts index 626f2b4..b2a7c42 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -11,9 +11,10 @@ import {GalleryRouter} from "./routes/GalleryRouter"; import {AdminRouter} from "./routes/AdminRouter"; import {ErrorRouter} from "./routes/ErrorRouter"; import {SharingRouter} from "./routes/SharingRouter"; -import {Config, DatabaseType} from "./config/Config"; +import {DatabaseType} from "./../common/config/Config"; import {ObjectManagerRepository} from "./model/ObjectManagerRepository"; import {DatabaseManager} from "./model/mongoose/DatabaseManager"; +import {Config} from "./config/Config"; export class Server { @@ -21,7 +22,6 @@ export class Server { private debug:any; private app:any; private server:any; - private port:number; constructor() { @@ -56,7 +56,7 @@ export class Server { this.app.use(_bodyParser.json()); - if (Config.databaseType === DatabaseType.memory) { + if (Config.Server.databaseType === DatabaseType.memory) { ObjectManagerRepository.MemoryMongoManagers(); } else { ObjectManagerRepository.InitMongoManagers(); @@ -64,8 +64,8 @@ export class Server { ()=> { console.error("MongoDB connection error. Falling back to memory Object Managers"); ObjectManagerRepository.MemoryMongoManagers(); + Config.setDatabaseType(DatabaseType.memory); }); - } new PublicRouter(this.app); @@ -79,13 +79,13 @@ export class Server { // Get PORT from environment and store in Express. - this.app.set('port', Config.PORT); + this.app.set('port', Config.Server.port); // Create HTTP server. this.server = _http.createServer(this.app); //Listen on provided PORT, on all network interfaces. - this.server.listen(Config.PORT); + this.server.listen(Config.Server.port); this.server.on('error', this.onError); this.server.on('listening', this.onListening); @@ -101,9 +101,9 @@ export class Server { throw error; } - var bind = typeof Config.PORT === 'string' - ? 'Pipe ' + Config.PORT - : 'Port ' + Config.PORT; + var bind = typeof Config.Server.port === 'string' + ? 'Pipe ' + Config.Server.port + : 'Port ' + Config.Server.port; // handle specific listen error with friendly messages switch (error.code) { diff --git a/common/config/Config.ts b/common/config/Config.ts new file mode 100644 index 0000000..8645d56 --- /dev/null +++ b/common/config/Config.ts @@ -0,0 +1,44 @@ +export enum DatabaseType{ + memory, mongoDB +} + +interface ServerConfig { + port:number; + thumbnailSizes:Array; + imagesFolder:string; + thumbnailFolder:string; + databaseType:DatabaseType; +} + +interface SearchConfig { + searchEnabled:boolean + instantSearchEnabled:boolean + autocompleteEnabled:boolean +} + +interface ClientConfig { + Search:SearchConfig; +} +export class ConfigClass { + + public Server:ServerConfig = null; + + public Client:ClientConfig = { + Search: { + searchEnabled: true, + instantSearchEnabled: true, + autocompleteEnabled: true + } + }; + + public setDatabaseType(type:DatabaseType) { + this.Server.databaseType = type; + if (type === DatabaseType.memory) { + this.Client.Search.searchEnabled = false; + this.Client.Search.instantSearchEnabled = false; + this.Client.Search.autocompleteEnabled = false; + } + } +} + + \ No newline at end of file diff --git a/frontend/app/config/Config.ts b/frontend/app/config/Config.ts new file mode 100644 index 0000000..9930701 --- /dev/null +++ b/frontend/app/config/Config.ts @@ -0,0 +1,12 @@ +import {ConfigClass} from "../../../common/config/Config"; +import {Utils} from "../../../common/Utils"; + +declare module ServerInject { + export var ConfigInject; +} + +export var Config = new ConfigClass(); + +if (typeof ServerInject !== "undefined" && typeof ServerInject.ConfigInject !== "undefined") { + Utils.updateKeys(Config.Client, ServerInject.ConfigInject); +} \ No newline at end of file diff --git a/frontend/app/gallery/gallery.component.html b/frontend/app/gallery/gallery.component.html index 9a1e985..8d6cb59 100644 --- a/frontend/app/gallery/gallery.component.html +++ b/frontend/app/gallery/gallery.component.html @@ -1,7 +1,7 @@
- +
diff --git a/frontend/app/gallery/gallery.component.ts b/frontend/app/gallery/gallery.component.ts index 891d13c..0f5e9e5 100644 --- a/frontend/app/gallery/gallery.component.ts +++ b/frontend/app/gallery/gallery.component.ts @@ -9,6 +9,7 @@ import {GalleryGridComponent} from "./grid/grid.gallery.component"; import {FrameComponent} from "../frame/frame.component"; import {GalleryLightboxComponent} from "./lightbox/lightbox.gallery.component"; import {GallerySearchComponent} from "./search/search.gallery.component"; +import {Config} from "../config/Config"; @Component({ selector: 'gallery', @@ -23,10 +24,14 @@ import {GallerySearchComponent} from "./search/search.gallery.component"; export class GalleryComponent implements OnInit { + public showSearchBar:boolean = true; + constructor(private _galleryService:GalleryService, private _params:RouteParams, private _authService:AuthenticationService, private _router:Router) { + + this.showSearchBar = Config.Client.Search.searchEnabled; } ngOnInit() { diff --git a/frontend/app/gallery/search/search.gallery.component.ts b/frontend/app/gallery/search/search.gallery.component.ts index a554896..67dded0 100644 --- a/frontend/app/gallery/search/search.gallery.component.ts +++ b/frontend/app/gallery/search/search.gallery.component.ts @@ -6,6 +6,7 @@ import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem"; import {Message} from "../../../../common/entities/Message"; import {GalleryService} from "../gallery.service"; import {FORM_DIRECTIVES} from "@angular/common"; +import {Config} from "../../config/Config"; @Component({ selector: 'gallery-search', @@ -25,13 +26,20 @@ export class GallerySearchComponent { onSearchChange(event:KeyboardEvent) { let searchText = (event.target).value; - this.autocomplete(searchText); - this._galleryService.instantSearch(searchText); + if (Config.Client.Search.autocompleteEnabled) { + this.autocomplete(searchText); + } + + if (Config.Client.Search.instantSearchEnabled) { + this._galleryService.instantSearch(searchText); + } } public onSearch() { - this._galleryService.search(this.searchText); + if (Config.Client.Search.searchEnabled) { + this._galleryService.search(this.searchText); + } } public search(item:AutoCompleteItem) { @@ -40,13 +48,7 @@ export class GallerySearchComponent { this.onSearch(); } - private showSuggestions(suggestions:Array, searchText:string) { - this.emptyAutoComplete(); - suggestions.forEach((item)=> { - let renderItem = new AutoCompleteRenderItem(item.text, searchText); - this.autoCompleteItems.push(renderItem); - }); - } + public onFocusLost(event) { this.autoCompleteItems = []; @@ -61,6 +63,9 @@ export class GallerySearchComponent { } private autocomplete(searchText:string) { + if (!Config.Client.Search.autocompleteEnabled) { + return + } if (searchText.trim().length > 0) { this._autoCompleteService.autoComplete(searchText).then((message:Message>) => { if (message.error) { @@ -75,6 +80,14 @@ export class GallerySearchComponent { } } + private showSuggestions(suggestions:Array, searchText:string) { + this.emptyAutoComplete(); + suggestions.forEach((item)=> { + let renderItem = new AutoCompleteRenderItem(item.text, searchText); + this.autoCompleteItems.push(renderItem); + }); + } + } class AutoCompleteRenderItem { diff --git a/frontend/index.ejs b/frontend/index.ejs index 5ca8c6d..86b3ca0 100644 --- a/frontend/index.ejs +++ b/frontend/index.ejs @@ -1,7 +1,7 @@ - + PiGallery2 @@ -15,7 +15,10 @@ Loading...