1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2024-11-28 08:58:49 +02:00

source style cleanup

This commit is contained in:
Braun Patrik 2016-05-09 17:04:56 +02:00
parent 0f92ad983b
commit ef5758f3c7
60 changed files with 549 additions and 601 deletions

View File

@ -1,4 +1,3 @@
import {ConfigLoader} from "./ConfigLoader";
import * as path from "path";
@ -6,10 +5,10 @@ export enum DatabaseType{
memory, mongoDB
}
export class ConfigClass{
export class ConfigClass {
constructor(){
ConfigLoader.init(this,path.join(__dirname,'./../../config.json'));
constructor() {
ConfigLoader.init(this, path.join(__dirname, './../../config.json'));
}
public PORT:number = 80;

View File

@ -1,42 +1,41 @@
import * as fs from 'fs';
import * as optimist from 'optimist';
import * as fs from "fs";
import * as optimist from "optimist";
export class ConfigLoader {
static init(configObject:any, configFilePath?:string){
static init(configObject:any, configFilePath?:string) {
this.processConfigFile(configFilePath, configObject);
this.processArguments(configObject);
this.processEnvVariables(configObject);
}
private static processEnvVariables(configObject:any) {
private static processEnvVariables(configObject:any) {
this.loadObject(configObject, process.env);
};
private static processArguments(configObject:any) {
let argv = optimist.argv;
delete(argv._);
delete(argv.$0);
delete(argv.$0);
let config = {};
Object.keys(argv).forEach((key)=> {
let keyArray = key.split("-");
let value = argv[key];
let value = argv[key];
let setObject = (object,keyArray,value) => {
let setObject = (object, keyArray, value) => {
let key = keyArray.shift();
object[key] = {};
if(keyArray.length == 0){
if (keyArray.length == 0) {
object[key] = value;
return;
}
return setObject(object[key],keyArray,value);
return setObject(object[key], keyArray, value);
};
setObject(config,keyArray,value);
setObject(config, keyArray, value);
});
});
this.loadObject(configObject, config);
};
@ -48,39 +47,38 @@ export class ConfigLoader {
}
};
private static loadConfigFile(configFilePath,configObject):boolean{
if(fs.existsSync(configFilePath) === false){
private static loadConfigFile(configFilePath, configObject):boolean {
if (fs.existsSync(configFilePath) === false) {
return false;
}
try {
let config = JSON.parse(fs.readFileSync(configFilePath, 'utf8'));
this.loadObject(configObject,config);
this.loadObject(configObject, config);
return true;
}catch(err){
} catch (err) {
}
return false;
}
private static saveConfigFile(configFilePath,configObject){
private static saveConfigFile(configFilePath, configObject) {
try {
fs.writeFileSync(configFilePath, JSON.stringify(configObject, null, 4));
}catch(err){
} catch (err) {
}
}
private static loadObject(targetObject,sourceObject){
private static loadObject(targetObject, sourceObject) {
Object.keys(sourceObject).forEach((key)=> {
if(typeof targetObject[key] === "undefined"){
if (typeof targetObject[key] === "undefined") {
return;
}
if(typeof targetObject[key] === "object"){
this.loadObject(targetObject[key],sourceObject[key] );
}else {
}
if (typeof targetObject[key] === "object") {
this.loadObject(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});

View File

@ -1,7 +1,6 @@
///<reference path="ExtendedRequest.d.ts"/>
///<reference path="../../typings/main.d.ts"/>
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {UserRoles} from "../../common/entities/User";
@ -9,16 +8,15 @@ import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
export class AuthenticationMWs {
public static authenticate(req:Request, res:Response, next:NextFunction){
/* if (typeof req.session.user === 'undefined') {
return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
}*/
public static authenticate(req:Request, res:Response, next:NextFunction) {
/* if (typeof req.session.user === 'undefined') {
return next(new Error(ErrorCodes.NOT_AUTHENTICATED));
}*/
//TODO: uncomment
return next();
}
public static authorise(role:UserRoles){
public static authorise(role:UserRoles) {
return (req:Request, res:Response, next:NextFunction) => {
if (req.session.user.role < role) {
return next(new Error(ErrorCodes.NOT_AUTHORISED));
@ -26,24 +24,24 @@ export class AuthenticationMWs {
return next();
};
}
public static inverseAuthenticate(req:Request, res:Response, next:NextFunction){
public static inverseAuthenticate(req:Request, res:Response, next:NextFunction) {
if (typeof req.session.user !== 'undefined') {
return next(new Error(ErrorCodes.ALREADY_AUTHENTICATED));
}
return next();
}
public static login(req:Request, res:Response, next:NextFunction){
public static login(req:Request, res:Response, next:NextFunction) {
//not enough parameter
if ((typeof req.body === 'undefined') || (typeof req.body.loginCredential === 'undefined') || (typeof req.body.loginCredential.username === 'undefined') ||
if ((typeof req.body === 'undefined') || (typeof req.body.loginCredential === 'undefined') || (typeof req.body.loginCredential.username === 'undefined') ||
(typeof req.body.loginCredential.password === 'undefined')) {
return next();
}
//lets find the user
ObjectManagerRepository.getInstance().getUserManager().findOne({
name: req.body.loginCredential.username,
password: req.body.loginCredential.password
name: req.body.loginCredential.username,
password: req.body.loginCredential.password
}, (err, result) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.CREDENTIAL_NOT_FOUND));
@ -57,7 +55,4 @@ export class AuthenticationMWs {
}
}

View File

@ -1,17 +1,16 @@
declare module Express {
export interface Request{
export interface Request {
resultPipe?:any
body?:{
loginCredential
}
}
export interface Response{
export interface Response {
tpl?:any
}
export interface Session {
export interface Session {
user?;
}
}

View File

@ -1,9 +1,7 @@
import * as path from 'path';
import * as fs from 'fs';
import * as path from "path";
import * as fs from "fs";
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {GalleryManager} from "../model/memory/GalleryManager";
import {Directory} from "../../common/entities/Directory";
import {Config} from "../config/Config";
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
@ -12,58 +10,56 @@ import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
export class GalleryMWs {
private static getImageFolder(){
return path.join(__dirname,"/../../",Config.imagesFolder);
private static getImageFolder() {
return path.join(__dirname, "/../../", Config.imagesFolder);
}
public static listDirectory(req:Request, res:Response, next:NextFunction){
public static listDirectory(req:Request, res:Response, next:NextFunction) {
let directoryName = req.params.directory || "/";
let absoluteDirectoryName = path.join(GalleryMWs.getImageFolder(), directoryName);
if(!fs.statSync(absoluteDirectoryName).isDirectory()){
if (!fs.statSync(absoluteDirectoryName).isDirectory()) {
return next();
}
ObjectManagerRepository.getInstance().getGalleryManager().listDirectory(directoryName,(err,directory:Directory) => {
if(err || !directory){
return next(new Error(ErrorCodes.GENERAL_ERROR,err));
}
ObjectManagerRepository.getInstance().getGalleryManager().listDirectory(directoryName, (err, directory:Directory) => {
if (err || !directory) {
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
}
req.resultPipe = directory;
return next();
});
}
public static loadImage(req:Request, res:Response, next:NextFunction){
if(!(req.params.imagePath)){
public static loadImage(req:Request, res:Response, next:NextFunction) {
if (!(req.params.imagePath)) {
return next();
}
let fullImagePath = path.join(GalleryMWs.getImageFolder(), req.params.imagePath);
if(fs.statSync(fullImagePath).isDirectory()){
let fullImagePath = path.join(GalleryMWs.getImageFolder(), req.params.imagePath);
if (fs.statSync(fullImagePath).isDirectory()) {
return next();
}
req.resultPipe = fullImagePath;
return next();
}
public static search(req:Request, res:Response, next:NextFunction){
public static search(req:Request, res:Response, next:NextFunction) {
//TODO: implement
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
public static autocomplete(req:Request, res:Response, next:NextFunction){
if(!(req.params.text)){
public static autocomplete(req:Request, res:Response, next:NextFunction) {
if (!(req.params.text)) {
return next();
}
ObjectManagerRepository.getInstance().getSearchManager().autocomplete(req.params.text,(err,items:Array<AutoCompleteItem>) => {
if(err || !items){
return next(new Error(ErrorCodes.GENERAL_ERROR,err));
ObjectManagerRepository.getInstance().getSearchManager().autocomplete(req.params.text, (err, items:Array<AutoCompleteItem>) => {
if (err || !items) {
return next(new Error(ErrorCodes.GENERAL_ERROR, err));
}
req.resultPipe = items;
return next();
@ -71,5 +67,4 @@ export class GalleryMWs {
}
}

View File

@ -1,4 +1,3 @@
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {Utils} from "../../common/Utils";
@ -6,47 +5,47 @@ import {Message} from "../../common/entities/Message";
export class RenderingMWs {
public static renderResult(req:Request, res:Response, next:NextFunction){
if(!req.resultPipe)
public static renderResult(req:Request, res:Response, next:NextFunction) {
if (!req.resultPipe)
return next();
return RenderingMWs.renderMessage(res,req.resultPipe);
return RenderingMWs.renderMessage(res, req.resultPipe);
}
public static renderSessionUser(req:Request, res:Response, next:NextFunction){
if(!(req.session.user)){
public static renderSessionUser(req:Request, res:Response, next:NextFunction) {
if (!(req.session.user)) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
let user = Utils.clone(req.session.user);
delete user.password;
RenderingMWs.renderMessage(res,user);
RenderingMWs.renderMessage(res, user);
}
public static renderFile(req:Request, res:Response, next:NextFunction){
if(!req.resultPipe)
return next();
public static renderFile(req:Request, res:Response, next:NextFunction) {
if (!req.resultPipe)
return next();
return res.sendFile(req.resultPipe);
}
public static renderOK(req:Request, res:Response, next:NextFunction){
let message = new Message<string> (null,"ok");
public static renderOK(req:Request, res:Response, next:NextFunction) {
let message = new Message<string>(null, "ok");
res.json(message);
}
public static renderError(err:any, req:Request, res:Response, next:NextFunction):any{
if(err instanceof Error) {
let message = new Message<any> (err,null);
public static renderError(err:any, req:Request, res:Response, next:NextFunction):any {
if (err instanceof Error) {
let message = new Message<any>(err, null);
return res.json(message);
}
return next(err);
}
protected static renderMessage<T>(res:Response, content:T){
let message = new Message<T> (null,content);
protected static renderMessage<T>(res:Response, content:T) {
let message = new Message<T>(null, content);
res.json(message);
}

View File

@ -1,64 +1,63 @@
///<reference path="jimp.d.ts"/>
import * as path from 'path';
import * as Jimp from 'jimp';
import * as crypto from 'crypto';
import * as fs from 'fs';
import * as path from "path";
import * as Jimp from "jimp";
import * as crypto from "crypto";
import * as fs from "fs";
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {Config} from "../config/Config";
import {Config} from "../config/Config";
export class ThumbnailGeneratorMWs {
private static getThumbnailFolder(){
return path.join(__dirname,"/../../",Config.thumbnailFolder);
private static getThumbnailFolder() {
return path.join(__dirname, "/../../", Config.thumbnailFolder);
}
public static generateThumbnail(req:Request, res:Response, next:NextFunction){
if(!req.resultPipe)
public static generateThumbnail(req:Request, res:Response, next:NextFunction) {
if (!req.resultPipe)
return next();
let imagePath = req.resultPipe;
let size:number = parseInt(req.params.size) || Config.thumbnailSizes[0];
let size:number = parseInt(req.params.size) || Config.thumbnailSizes[0];
let thumbnailFolder = ThumbnailGeneratorMWs.getThumbnailFolder();
if(Config.thumbnailSizes.indexOf(size) === -1){
if (Config.thumbnailSizes.indexOf(size) === -1) {
size = Config.thumbnailSizes[0];
}
let thPath = path.join(thumbnailFolder,ThumbnailGeneratorMWs.generateThumbnailName(imagePath,size));
let thPath = path.join(thumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
req.resultPipe = thPath;
if(fs.existsSync(thPath) === true){
if (fs.existsSync(thPath) === true) {
return next();
}
if (!fs.existsSync(thumbnailFolder)){
if (!fs.existsSync(thumbnailFolder)) {
fs.mkdirSync(thumbnailFolder);
}
Jimp.read(imagePath).then( (image) => {
Jimp.read(imagePath).then((image) => {
if (image.bitmap.with < image.bitmap.height) {
image.resize(size, Jimp.AUTO); // resize
}else{
} else {
image.resize(Jimp.AUTO, size); // resize
}
image.quality(60); // set JPEG quality
image.write(thPath, () =>{ // save
image.write(thPath, () => { // save
return next();
});
});
}).catch(function (err) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
return next(new Error(ErrorCodes.GENERAL_ERROR));
});
}
private static generateThumbnailName(imagePath:string,size:number):string{
return crypto.createHash('md5').update(imagePath).digest('hex')+"_"+size+".jpg";
private static generateThumbnailName(imagePath:string, size:number):string {
return crypto.createHash('md5').update(imagePath).digest('hex') + "_" + size + ".jpg";
}
}

View File

@ -1,5 +1,3 @@
import {UserManager} from "../model/memory/UserManager";
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
@ -7,7 +5,7 @@ import {User} from "../../common/entities/User";
export class UserMWs {
public static changePassword(req:Request, res:Response, next:NextFunction){
public static changePassword(req:Request, res:Response, next:NextFunction) {
if ((typeof req.body === 'undefined') || (typeof req.body.userModReq === 'undefined')
|| (typeof req.body.userModReq.id === 'undefined')
|| (typeof req.body.userModReq.oldPassword === 'undefined')
@ -15,7 +13,7 @@ export class UserMWs {
return next();
}
ObjectManagerRepository.getInstance().getUserManager().changePassword(req.body.userModReq, (err, result) =>{
ObjectManagerRepository.getInstance().getUserManager().changePassword(req.body.userModReq, (err, result) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
@ -23,14 +21,14 @@ export class UserMWs {
return next();
});
}
public static createUser(req:Request, res:Response, next:NextFunction){
public static createUser(req:Request, res:Response, next:NextFunction) {
if ((typeof req.body === 'undefined') || (typeof req.body.newUser === 'undefined')) {
return next();
}
ObjectManagerRepository.getInstance().getUserManager().createUser(req.body.newUser, (err, result) =>{
ObjectManagerRepository.getInstance().getUserManager().createUser(req.body.newUser, (err, result) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.USER_CREATION_ERROR));
}
@ -40,12 +38,12 @@ export class UserMWs {
}
public static deleteUser(req:Request, res:Response, next:NextFunction){
public static deleteUser(req:Request, res:Response, next:NextFunction) {
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
return next();
}
ObjectManagerRepository.getInstance().getUserManager().deleteUser(req.params.id, (err, result) =>{
ObjectManagerRepository.getInstance().getUserManager().deleteUser(req.params.id, (err, result) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
@ -56,13 +54,13 @@ export class UserMWs {
}
public static changeRole(req:Request, res:Response, next:NextFunction){
public static changeRole(req:Request, res:Response, next:NextFunction) {
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')
|| (typeof req.body === 'undefined') || (typeof req.body.newRole === 'undefined')) {
return next();
}
ObjectManagerRepository.getInstance().getUserManager().changeRole(req.params.id,req.body.newRole, (err) =>{
ObjectManagerRepository.getInstance().getUserManager().changeRole(req.params.id, req.body.newRole, (err) => {
if (err) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
@ -72,21 +70,19 @@ export class UserMWs {
}
public static listUsers(req:Request, res:Response, next:NextFunction){
ObjectManagerRepository.getInstance().getUserManager().find({}, (err, result:Array<User>) =>{
public static listUsers(req:Request, res:Response, next:NextFunction) {
ObjectManagerRepository.getInstance().getUserManager().find({}, (err, result:Array<User>) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
for(let i = 0; i < result.length; i++){
for (let i = 0; i < result.length; i++) {
result[i].password = "";
}
req.resultPipe = result;
return next();
});
}
}

View File

@ -1,5 +1,3 @@
import {UserManager} from "../model/memory/UserManager";
import {NextFunction, Request, Response} from "express";
import {Error, ErrorCodes} from "../../common/entities/Error";
import {UserRoles} from "../../common/entities/User";
@ -7,53 +5,51 @@ import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
export class UserRequestConstrainsMWs {
public static forceSelfRequest(req:Request, res:Response, next:NextFunction){
public static forceSelfRequest(req:Request, res:Response, next:NextFunction) {
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
return next();
}
if(req.session.user.id !== req.params.id){
return next(new Error(ErrorCodes.NOT_AUTHORISED));
}
return next();
}
public static notSelfRequest(req:Request, res:Response, next:NextFunction){
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
return next();
}
if(req.session.user.id === req.params.id){
if (req.session.user.id !== req.params.id) {
return next(new Error(ErrorCodes.NOT_AUTHORISED));
}
return next();
}
public static notSelfRequestOr2Admins(req:Request, res:Response, next:NextFunction){
public static notSelfRequest(req:Request, res:Response, next:NextFunction) {
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
return next();
}
if(req.session.user.id !== req.params.id){
if (req.session.user.id === req.params.id) {
return next(new Error(ErrorCodes.NOT_AUTHORISED));
}
return next();
}
public static notSelfRequestOr2Admins(req:Request, res:Response, next:NextFunction) {
if ((typeof req.params === 'undefined') || (typeof req.params.id === 'undefined')) {
return next();
}
if (req.session.user.id !== req.params.id) {
return next();
}
//TODO: fix it!
ObjectManagerRepository.getInstance().getUserManager().find({minRole:UserRoles.Admin}, (err, result) =>{
ObjectManagerRepository.getInstance().getUserManager().find({minRole: UserRoles.Admin}, (err, result) => {
if ((err) || (!result)) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
if(result.length <= 1) {
if (result.length <= 1) {
return next(new Error(ErrorCodes.GENERAL_ERROR));
}
});
return next();
}
}

View File

@ -1,4 +1,5 @@
declare module "jimp"{
declare module "jimp" {
function read(filaname);
var AUTO:any;
}

View File

@ -1,37 +1,36 @@
import * as fs from 'fs';
import * as path from 'path';
import * as mime from 'mime';
import * as sizeOf from 'image-size';
import * as fs from "fs";
import * as path from "path";
import * as mime from "mime";
import * as sizeOf from "image-size";
import {Directory} from "../../common/entities/Directory";
import {Photo} from "../../common/entities/Photo";
export class DiskManager{
public static scanDirectory(relativeDirectoryName, cb:(error: any, result:Directory) => void){
export class DiskManager {
public static scanDirectory(relativeDirectoryName, cb:(error:any, result:Directory) => void) {
console.log("DiskManager: scanDirectory");
let directoryName = path.basename(relativeDirectoryName);
let directoryParent = path.join( path.dirname(relativeDirectoryName),"/");
let absoluteDirectoryName = path.join(__dirname,"/../../demo/images", relativeDirectoryName);
let directoryParent = path.join(path.dirname(relativeDirectoryName), "/");
let absoluteDirectoryName = path.join(__dirname, "/../../demo/images", relativeDirectoryName);
let directory = new Directory(1,directoryName,directoryParent,new Date(),[],[]);
let directory = new Directory(1, directoryName, directoryParent, new Date(), [], []);
fs.readdir(absoluteDirectoryName, function (err, list) {
if(err){
return cb(err,null);
if (err) {
return cb(err, null);
}
for (let i = 0; i < list.length; i++) {
let file = list[i];
let fullFilePath = path.resolve(absoluteDirectoryName, file);
if(fs.statSync(fullFilePath).isDirectory()){
directory.directories.push(new Directory(2,file,relativeDirectoryName,new Date(),[],[]));
if (fs.statSync(fullFilePath).isDirectory()) {
directory.directories.push(new Directory(2, file, relativeDirectoryName, new Date(), [], []));
}
if(DiskManager.isImage(fullFilePath)){
if (DiskManager.isImage(fullFilePath)) {
let dimensions = sizeOf(fullFilePath);
directory.photos.push(new Photo(1,file,dimensions.width,dimensions.height));
directory.photos.push(new Photo(1, file, dimensions.width, dimensions.height));
}
}
@ -40,7 +39,7 @@ export class DiskManager{
});
}
private static isImage(fullPath){
private static isImage(fullPath) {
let imageMimeTypes = [
'image/bmp',
'image/gif',

View File

@ -1,4 +1,4 @@
import {Directory} from "../../common/entities/Directory";
export interface IGalleryManager {
listDirectory(relativeDirectoryName, cb:(error: any,result:Directory) => void);
listDirectory(relativeDirectoryName, cb:(error:any, result:Directory) => void);
}

View File

@ -1,4 +1,4 @@
import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
export interface ISearchManager {
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void);
autocomplete(text, cb:(error:any, result:Array<AutoCompleteItem>) => void);
}

View File

@ -1,9 +1,9 @@
import {User, UserRoles} from "../../common/entities/User";
export interface IUserManager {
findOne(filter,cb:(error: any,result:User) => void);
find(filter,cb:(error: any,result:Array<User>) => void);
createUser(user,cb:(error: any,result:User) => void);
deleteUser(id:number,cb:(error: any,result:string) => void);
changeRole(id:number, newRole:UserRoles,cb:(error: any) => void);
changePassword(request:any,cb:(error: any,result:string) => void);
findOne(filter, cb:(error:any, result:User) => void);
find(filter, cb:(error:any, result:Array<User>) => void);
createUser(user, cb:(error:any, result:User) => void);
deleteUser(id:number, cb:(error:any, result:string) => void);
changeRole(id:number, newRole:UserRoles, cb:(error:any) => void);
changePassword(request:any, cb:(error:any, result:string) => void);
}

View File

@ -8,27 +8,27 @@ import {ISearchManager} from "./ISearchManager";
import {MongoSearchManager} from "./mongoose/MongoSearchManager";
import {SearchManager} from "./memory/SearchManager";
export class ObjectManagerRepository{
export class ObjectManagerRepository {
private _galleryManager:IGalleryManager;
private _userManager:IUserManager;
private _searchManager:ISearchManager;
private static _instance:ObjectManagerRepository = null;
public static InitMongoManagers(){
public static InitMongoManagers() {
ObjectManagerRepository.getInstance().setGalleryManager(new MongoGalleryManager());
ObjectManagerRepository.getInstance().setUserManager(new MongoUserManager());
ObjectManagerRepository.getInstance().setSearchManager(new MongoSearchManager());
}
public static MemoryMongoManagers(){
public static MemoryMongoManagers() {
ObjectManagerRepository.getInstance().setGalleryManager(new GalleryManager());
ObjectManagerRepository.getInstance().setUserManager(new UserManager());
ObjectManagerRepository.getInstance().setSearchManager(new SearchManager());
}
public static getInstance(){
if(this._instance === null){
public static getInstance() {
if (this._instance === null) {
this._instance = new ObjectManagerRepository();
}
return this._instance;

View File

@ -2,13 +2,12 @@ import {Directory} from "../../../common/entities/Directory";
import {IGalleryManager} from "../IGalleryManager";
import {DiskManager} from "../DiskManger";
export class GalleryManager implements IGalleryManager{
export class GalleryManager implements IGalleryManager {
public listDirectory(relativeDirectoryName, cb:(error: any,result:Directory) => void){
return DiskManager.scanDirectory(relativeDirectoryName,cb);
public listDirectory(relativeDirectoryName, cb:(error:any, result:Directory) => void) {
return DiskManager.scanDirectory(relativeDirectoryName, cb);
}
}

View File

@ -1,13 +1,12 @@
import {AutoCompleteItem} from "../../../common/entities/AutoCompleteItem";
import {ISearchManager} from "../ISearchManager";
export class SearchManager implements ISearchManager{
export class SearchManager implements ISearchManager {
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void){
autocomplete(text, cb:(error:any, result:Array<AutoCompleteItem>) => void) {
throw new Error("not implemented");
}
}

View File

@ -1,40 +1,41 @@
import {User, UserRoles} from "../../../common/entities/User";
import {IUserManager} from "../IUserManager";
export class UserManager implements IUserManager{
export class UserManager implements IUserManager {
private users = [new User(1,"developer", "developer", UserRoles.Developer),
new User(2,"admin", "admin", UserRoles.Admin),
new User(3,"user", "user", UserRoles.User),
new User(4,"guest", "guest", UserRoles.Guest)];
private users = [new User(1, "developer", "developer", UserRoles.Developer),
new User(2, "admin", "admin", UserRoles.Admin),
new User(3, "user", "user", UserRoles.User),
new User(4, "guest", "guest", UserRoles.Guest)];
public findOne(filter,cb:(error: any,result:User) => void){
public findOne(filter, cb:(error:any, result:User) => void) {
return cb(null, this.users[1]);
}
public find(filter,cb:(error: any,result:Array<User>) => void){
public find(filter, cb:(error:any, result:Array<User>) => void) {
return cb(null, this.users);
}
public createUser(user,cb:(error: any,result:User) => void){
public createUser(user, cb:(error:any, result:User) => void) {
this.users.push(user);
return cb(null, user);
}
public deleteUser(id:number,cb:(error: any) => void){
public deleteUser(id:number, cb:(error:any) => void) {
this.users = this.users.filter(u => u.id != id);
return cb(null);
}
public changeRole(id:number, newRole:UserRoles, cb:(error: any,result:string) => void){
for(let i = 0; i < this.users.length; i++){
if (this.users[i].id === id){
public changeRole(id:number, newRole:UserRoles, cb:(error:any, result:string) => void) {
for (let i = 0; i < this.users.length; i++) {
if (this.users[i].id === id) {
this.users[i].role = newRole;
return cb(null,"ok");
return cb(null, "ok");
}
}
}
public changePassword(request:any,cb:(error: any,result:string) => void){
public changePassword(request:any, cb:(error:any, result:string) => void) {
throw new Error("not implemented"); //TODO: implement
}

View File

@ -1,5 +1,4 @@
import * as path from 'path';
import * as path from "path";
import {Directory} from "../../../common/entities/Directory";
import {IGalleryManager} from "../IGalleryManager";
import {DiskManager} from "../DiskManger";
@ -7,30 +6,33 @@ import {Utils} from "../../../common/Utils";
import {DirectoryModel} from "./entities/DirectoryModel";
import {PhotoModel} from "./entities/PhotoModel";
export class MongoGalleryManager implements IGalleryManager{
export class MongoGalleryManager implements IGalleryManager {
constructor(){
constructor() {
}
public listDirectory(relativeDirectoryName, cb:(error: any,result:Directory) => void){
public listDirectory(relativeDirectoryName, cb:(error:any, result:Directory) => void) {
let directoryName = path.basename(relativeDirectoryName);
let directoryParent = path.join( path.dirname(relativeDirectoryName),"/");
let directoryParent = path.join(path.dirname(relativeDirectoryName), "/");
DirectoryModel.findOne({name:directoryName, path: directoryParent}).populate('photos').populate('directories').exec( (err,res:any) =>{
if(err || !res){
return this.indexDirectory(relativeDirectoryName,cb);
DirectoryModel.findOne({
name: directoryName,
path: directoryParent
}).populate('photos').populate('directories').exec((err, res:any) => {
if (err || !res) {
return this.indexDirectory(relativeDirectoryName, cb);
}
return cb(err, res);
});
}
public indexDirectory(relativeDirectoryName, cb:(error: any,result:Directory) => void){
DiskManager.scanDirectory(relativeDirectoryName,(err,scannedDirectory)=>{
public indexDirectory(relativeDirectoryName, cb:(error:any, result:Directory) => void) {
DiskManager.scanDirectory(relativeDirectoryName, (err, scannedDirectory)=> {
let arr = [];
scannedDirectory.directories.forEach((value) => {
let dir = new DirectoryModel(value);
Utils.setKeys(dir,value);
Utils.setKeys(dir, value);
dir.save();
arr.push(dir);
});
@ -38,19 +40,18 @@ export class MongoGalleryManager implements IGalleryManager{
arr = [];
scannedDirectory.photos.forEach((value) => {
let p = new PhotoModel(value);
Utils.setKeys(p,value);
Utils.setKeys(p, value);
p.save();
arr.push(p);
});
scannedDirectory.photos = arr;
DirectoryModel.create(scannedDirectory,(err)=>{
return cb(err,scannedDirectory);
DirectoryModel.create(scannedDirectory, (err)=> {
return cb(err, scannedDirectory);
});
});
}
}

View File

@ -3,43 +3,45 @@ import {ISearchManager} from "../ISearchManager";
import {DirectoryModel} from "./entities/DirectoryModel";
import {PhotoModel} from "./entities/PhotoModel";
export class MongoSearchManager implements ISearchManager{
export class MongoSearchManager implements ISearchManager {
constructor(){
constructor() {
}
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void){
autocomplete(text, cb:(error:any, result:Array<AutoCompleteItem>) => void) {
console.log("autocomplete: " + text);
let items:Array<AutoCompleteItem> = [];
PhotoModel.find({name: { $regex: text, $options: "i" } }).limit(10).select('name').exec( (err,res:Array<any>) =>{
if(err || !res){
return cb(err,null);
PhotoModel.find({name: {$regex: text, $options: "i"}}).limit(10).select('name').exec((err, res:Array<any>) => {
if (err || !res) {
return cb(err, null);
}
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name),AutoCompeleteTypes.image));
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.image));
DirectoryModel.find({name: { $regex: text, $options: "i" } }).limit(10).select('name').exec( (err,res:Array<any>) =>{
if(err || !res){
return cb(err,null);
DirectoryModel.find({
name: {
$regex: text,
$options: "i"
}
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name),AutoCompeleteTypes.directory));
return cb(null,items);
}).limit(10).select('name').exec((err, res:Array<any>) => {
if (err || !res) {
return cb(err, null);
}
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name), AutoCompeleteTypes.directory));
return cb(null, items);
});
});
}
private encapsulateAutoComplete(values:Array<string>,type: AutoCompeleteTypes){
private encapsulateAutoComplete(values:Array<string>, type:AutoCompeleteTypes) {
let res = [];
values.forEach((value)=>{
res.push(new AutoCompleteItem(value,type));
values.forEach((value)=> {
res.push(new AutoCompleteItem(value, type));
});
return res;
}
}

View File

@ -4,7 +4,6 @@ import {UserModel} from "./entities/UserModel";
export class MongoUserManager implements IUserManager {
constructor() {
}
@ -27,7 +26,7 @@ export class MongoUserManager implements IUserManager {
public deleteUser(id:number, cb:(error:any) => void) {
UserModel.remove({id: id}, cb);
}
public changeRole(id:number, newRole:UserRoles, cb:(error:any, result:string) => void) {
return UserModel.update({id: id}, {role: newRole}, function (err) {

View File

@ -1,10 +1,10 @@
import {DatabaseManager} from "../DatabaseManager";
import {Schema} from "mongoose";
export var DirectoryModel = DatabaseManager.getInstance().getModel('directory',{
name:String,
path:String,
lastUpdate:Date,
export var DirectoryModel = DatabaseManager.getInstance().getModel('directory', {
name: String,
path: String,
lastUpdate: Date,
directories: [{
type: Schema.Types.ObjectId,
ref: 'directory'

View File

@ -3,7 +3,7 @@
import {AuthenticationMWs} from "../middlewares/AuthenticationMWs";
import {UserRoles} from "../../common/entities/User";
export class AdminRouter{
export class AdminRouter {
constructor(private app) {
this.addResetDB();
@ -27,7 +27,4 @@ export class AdminRouter{
};
}

View File

@ -3,7 +3,7 @@
import {RenderingMWs} from "../middlewares/RenderingMWs";
import {Error, ErrorCodes} from "../../common/entities/Error";
export class ErrorRouter{
export class ErrorRouter {
constructor(private app) {
this.addApiErrorHandler();
@ -17,13 +17,13 @@ export class ErrorRouter{
};
private addGenericHandler() {
this.app.use((err, req, res, next) => {
this.app.use((err, req, res, next) => {
//Flush out the stack to the console
console.error(err.stack);
next(new Error(ErrorCodes.SERVER_ERROR,"Unknown server side error"));
},
RenderingMWs.renderError
//Flush out the stack to the console
console.error(err.stack);
next(new Error(ErrorCodes.SERVER_ERROR, "Unknown server side error"));
},
RenderingMWs.renderError
);
}

View File

@ -5,8 +5,8 @@ import {GalleryMWs} from "../middlewares/GalleryMWs";
import {RenderingMWs} from "../middlewares/RenderingMWs";
import {ThumbnailGeneratorMWs} from "../middlewares/ThumbnailGeneratorMWs";
export class GalleryRouter{
constructor(private app){
export class GalleryRouter {
constructor(private app) {
this.addGetImageThumbnail();
this.addGetImage();
@ -17,7 +17,7 @@ export class GalleryRouter{
}
private addDirectoryList() {
this.app.get(["/api/gallery/content/:directory(*)","/api/gallery/","/api/gallery//"],
this.app.get(["/api/gallery/content/:directory(*)", "/api/gallery/", "/api/gallery//"],
AuthenticationMWs.authenticate,
GalleryMWs.listDirectory,
RenderingMWs.renderResult
@ -59,5 +59,4 @@ export class GalleryRouter{
};
}

View File

@ -1,21 +1,17 @@
///<reference path="../../typings/main.d.ts"/>
import * as _express from 'express';
import * as _path from 'path';
import * as _express from "express";
import {NextFunction, Request, Response} from "express";
import * as _path from "path";
import {Utils} from "../../common/Utils";
import {NextFunction, Request, Response} from "express";
export class PublicRouter{
constructor(private app){
export class PublicRouter {
constructor(private app) {
this.app.use((req:Request, res:Response, next:NextFunction) => {
res.tpl = {};
res.tpl.user = null;
if(req.session.user) {
if (req.session.user) {
let user = Utils.clone(req.session.user);
delete user.password;
res.tpl.user = user;
@ -23,17 +19,17 @@ export class PublicRouter{
return next();
});
this.app.use(_express.static(_path.resolve(__dirname, './../../frontend')));
this.app.use('/node_modules',_express.static(_path.resolve(__dirname, './../../node_modules')));
var renderIndex = (req: Request, res: Response) => {
res.render(_path.resolve(__dirname, './../../frontend/index.ejs'),res.tpl);
this.app.use(_express.static(_path.resolve(__dirname, './../../frontend')));
this.app.use('/node_modules', _express.static(_path.resolve(__dirname, './../../node_modules')));
var renderIndex = (req:Request, res:Response) => {
res.render(_path.resolve(__dirname, './../../frontend/index.ejs'), res.tpl);
};
this.app.get(['/','/login',"/gallery*","/admin"], renderIndex);
this.app.get(['/', '/login', "/gallery*", "/admin"], renderIndex);
}
}

View File

@ -3,7 +3,7 @@
import {AuthenticationMWs} from "../middlewares/AuthenticationMWs";
import {UserRoles} from "../../common/entities/User";
export class SharingRouter{
export class SharingRouter {
constructor(private app) {
this.addGetSharing();
@ -27,7 +27,4 @@ export class SharingRouter{
};
}

View File

@ -4,15 +4,15 @@ import {UserMWs} from "../middlewares/UserMWs";
import {UserRoles} from "../../common/entities/User";
import {AuthenticationMWs} from "../middlewares/AuthenticationMWs";
import {UserRequestConstrainsMWs} from "../middlewares/UserRequestConstrainsMWs";
import {RenderingMWs} from "../middlewares/RenderingMWs";
import {RenderingMWs} from "../middlewares/RenderingMWs";
export class UserRouter{
constructor(private app){
export class UserRouter {
constructor(private app) {
this.addLogin();
this.addGetSessionUser();
this.addChangePassword();
this.addCreateUser();
this.addDeleteUser();
this.addListUsers();

View File

@ -55,7 +55,7 @@ export class Server {
// for parsing application/json
this.app.use(_bodyParser.json());
if (Config.databaseType === DatabaseType.memory) {
ObjectManagerRepository.MemoryMongoManagers();
} else {

View File

@ -1,13 +1,13 @@
export var MessageTypes = {
Client:{
Login:{
Authenticate:"Authenticate"
Client: {
Login: {
Authenticate: "Authenticate"
}
},
Server:{
Login:{
Authenticated:"Authenticated"
Server: {
Login: {
Authenticated: "Authenticated"
}
}

View File

@ -5,47 +5,47 @@ export class Utils {
}
static concatUrls(...args:Array<string>){
static concatUrls(...args:Array<string>) {
let url = "";
for(let i = 0 ; i < args.length; i++){
if(args[i] === "" || typeof args[i] === "undefined") continue;
for (let i = 0; i < args.length; i++) {
if (args[i] === "" || typeof args[i] === "undefined") continue;
let part = args[i].replace("\\", "/");
if (part === "/" || part === "./") continue;
let part = args[i].replace("\\","/");
if(part === "/" || part === "./") continue;
url += part + "/";
}
return url.substring(0, url.length - 1);
}
public static updateKeys(targetObject,sourceObject){
public static updateKeys(targetObject, sourceObject) {
Object.keys(sourceObject).forEach((key)=> {
if(typeof targetObject[key] === "undefined"){
if (typeof targetObject[key] === "undefined") {
return;
}
if(typeof targetObject[key] === "object"){
Utils.updateKeys(targetObject[key],sourceObject[key] );
}else {
if (typeof targetObject[key] === "object") {
Utils.updateKeys(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});
}
public static setKeys(targetObject,sourceObject){
public static setKeys(targetObject, sourceObject) {
Object.keys(sourceObject).forEach((key)=> {
if(typeof targetObject[key] === "object"){
Utils.updateKeys(targetObject[key],sourceObject[key] );
}else {
if (typeof targetObject[key] === "object") {
Utils.updateKeys(targetObject[key], sourceObject[key]);
} else {
targetObject[key] = sourceObject[key];
}
});
}
public static enumToArray(EnumType):Array<{key:number;value:string;}>{
public static enumToArray(EnumType):Array<{key:number;value:string;}> {
let arr:Array<{key:number;value:string;}> = [];
for(let enumMember in EnumType){
if(!EnumType.hasOwnProperty(enumMember)){
for (let enumMember in EnumType) {
if (!EnumType.hasOwnProperty(enumMember)) {
continue;
}
let key = parseInt(enumMember, 10);

View File

@ -4,7 +4,8 @@ export enum AutoCompeleteTypes {
imageTag
}
export class AutoCompleteItem{
constructor(public text:string,public type:AutoCompeleteTypes){}
export class AutoCompleteItem {
constructor(public text:string, public type:AutoCompeleteTypes) {
}
}

View File

@ -1,10 +1,11 @@
import {Photo} from "./Photo";
export class Directory{
export class Directory {
constructor(public id?:number,
public name?:string,
public path?:string,
public lastUpdate?:Date,
public directories:Array<Directory> =[],
public photos:Array<Photo> = []){}
public directories:Array<Directory> = [],
public photos:Array<Photo> = []) {
}
}

View File

@ -1,4 +1,3 @@
export enum ErrorCodes{
NOT_AUTHENTICATED,
ALREADY_AUTHENTICATED,
@ -11,9 +10,10 @@ export enum ErrorCodes{
GENERAL_ERROR,
SERVER_ERROR
}
export class Error{
constructor(public code:ErrorCodes, public message?:String) {}
export class Error {
constructor(public code:ErrorCodes, public message?:String) {
}
}

View File

@ -1,5 +1,5 @@
export class LoginCredential{
constructor(public username:string = "", public password:string = ""){
export class LoginCredential {
constructor(public username:string = "", public password:string = "") {
}
}

View File

@ -1,9 +1,10 @@
import {Error} from "./Error";
export class Message<T>{
export class Message<T> {
public error:Error = null;
public result:T = null;
constructor(error:Error, result:T){
constructor(error:Error, result:T) {
this.error = error;
this.result = result;
}

View File

@ -4,10 +4,11 @@ export class Photo {
constructor(public id:number, public name:string, public width:number, public height:number) {
}
public static getThumbnailPath(directory:Directory,photo:Photo){
return Utils.concatUrls("/api/gallery/content/",directory.path,directory.name,photo.name,"thumbnail");
public static getThumbnailPath(directory:Directory, photo:Photo) {
return Utils.concatUrls("/api/gallery/content/", directory.path, directory.name, photo.name, "thumbnail");
}
public static getPhotoPath(directory:Directory,photo:Photo){
return Utils.concatUrls("/api/gallery/content/",directory.path,directory.name,photo.name);
public static getPhotoPath(directory:Directory, photo:Photo) {
return Utils.concatUrls("/api/gallery/content/", directory.path, directory.name, photo.name);
}
}

View File

@ -1,12 +1,12 @@
export enum UserRoles{
Guest = 1,
User = 2,
Admin = 3,
Developer = 4,
}
export class User {
constructor(public id?:number,public name?:string, public password?:string, public role:UserRoles = UserRoles.User){}
export class User {
constructor(public id?:number, public name?:string, public password?:string, public role:UserRoles = UserRoles.User) {
}
}

View File

@ -1,3 +1,4 @@
export class UserModificationRequest{
constructor(public id:number){}
export class UserModificationRequest {
constructor(public id:number) {
}
}

View File

@ -9,7 +9,7 @@ import {FORM_DIRECTIVES} from "@angular/common";
import {Utils} from "../../../common/Utils";
import {AdminService} from "./admin.service";
import {Message} from "../../../common/entities/Message";
import {StringifyRole} from "./StringifyRolePipe";
import {StringifyRole} from "./../pipes/StringifyRolePipe";
@Component({
selector: 'admin',

View File

@ -1,33 +1,32 @@
///<reference path="../../browser.d.ts"/>
import {Injectable} from '@angular/core';
import {Injectable} from "@angular/core";
import {NetworkService} from "../model/network/network.service.ts";
import {Http} from "@angular/http";
import {Message} from "../../../common/entities/Message";
import {User} from "../../../common/entities/User";
import {Message} from "../../../common/entities/Message";
import {User} from "../../../common/entities/User";
@Injectable()
export class AdminService {
constructor(private _networkService:NetworkService){
constructor(private _networkService:NetworkService) {
}
public createUser(user:User): Promise<Message<string>>{
return this._networkService.putJson("/user",{newUser:user});
public createUser(user:User):Promise<Message<string>> {
return this._networkService.putJson("/user", {newUser: user});
}
public getUsers():Promise<Message<Array<User>>>{
public getUsers():Promise<Message<Array<User>>> {
return this._networkService.getJson("/user/list");
}
public deleteUser(user:User) {
return this._networkService.deleteJson("/user/"+user.id);
return this._networkService.deleteJson("/user/" + user.id);
}
public updateRole(user:User) {
return this._networkService.postJson("/user/"+user.id+"/role",{newRole:user.role});
return this._networkService.postJson("/user/" + user.id + "/role", {newRole: user.role});
}
}

View File

@ -1,18 +1,18 @@
///<reference path="../browser.d.ts"/>
import { Component,OnInit } from '@angular/core';
import {Component, OnInit} from "@angular/core";
import {LoginComponent} from "./login/login.component";
import {AuthenticationService} from "./model/network/authentication.service.ts";
import {GalleryComponent} from "./gallery/gallery.component";
import {GalleryComponent} from "./gallery/gallery.component";
import {User} from "../../common/entities/User";
import {Router, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from "@angular/router-deprecated";
import {Router, RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS} from "@angular/router-deprecated";
import {HTTP_PROVIDERS} from "@angular/http";
import {UserService} from "./model/network/user.service.ts";
import {GalleryService} from "./gallery/gallery.service";
import {GalleryService} from "./gallery/gallery.service";
import {AdminComponent} from "./admin/admin.component";
import {NetworkService} from "./model/network/network.service";
import {NetworkService} from "./model/network/network.service";
@Component({
selector: 'pi-gallery2-app',
template: `<router-outlet></router-outlet>`,
@ -43,27 +43,27 @@ import {NetworkService} from "./model/network/network.service";
},
{
path: '/gallery',
redirectTo: ["Gallery",{directory:""}]
},
{
redirectTo: ["Gallery", {directory: ""}]
},
{
path: '/gallery/:directory',
name: 'Gallery',
component: GalleryComponent
},
])
export class AppComponent implements OnInit{
export class AppComponent implements OnInit {
constructor(private _router: Router, private _authenticationService: AuthenticationService){
constructor(private _router:Router, private _authenticationService:AuthenticationService) {
}
ngOnInit() {
this._authenticationService.OnAuthenticated.on((user:User) => {
if (this._router.isRouteActive(this._router.generate(['Login']))) {
console.log("routing");
this._router.navigate(["Gallery",{directory:""}]);
this._router.navigate(["Gallery", {directory: ""}]);
}
});
}
}

View File

@ -1,18 +1,18 @@
///<reference path="../../browser.d.ts"/>
import {Component, ViewEncapsulation} from '@angular/core';
import {Component, ViewEncapsulation} from "@angular/core";
import {RouterLink} from "@angular/router-deprecated";
@Component({
selector: 'app-frame',
templateUrl: 'app/frame/frame.component.html',
directives:[RouterLink],
templateUrl: 'app/frame/frame.component.html',
directives: [RouterLink],
encapsulation: ViewEncapsulation.Emulated
})
export class FrameComponent {
constructor() {
export class FrameComponent {
constructor() {
}
}

View File

@ -1,6 +1,6 @@
///<reference path="../../../browser.d.ts"/>
import {Component, Input} from '@angular/core';
import {Component, Input} from "@angular/core";
import {Directory} from "../../../../common/entities/Directory";
import {RouterLink} from "@angular/router-deprecated";
import {Utils} from "../../../../common/Utils";
@ -8,19 +8,18 @@ import {Utils} from "../../../../common/Utils";
@Component({
selector: 'gallery-directory',
templateUrl: 'app/gallery/directory/directory.gallery.component.html',
directives:[RouterLink],
directives: [RouterLink],
})
export class GalleryDirectoryComponent{
@Input() directory: Directory;
export class GalleryDirectoryComponent {
@Input() directory:Directory;
constructor() {
}
getDirectoryPath(){
return Utils.concatUrls(this.directory.path,this.directory.name);
getDirectoryPath() {
return Utils.concatUrls(this.directory.path, this.directory.name);
}
}

View File

@ -1,8 +1,8 @@
///<reference path="../../browser.d.ts"/>
import {Component, OnInit} from '@angular/core';
import {Component, OnInit} from "@angular/core";
import {AuthenticationService} from "../model/network/authentication.service.ts";
import {Router, RouteParams} from "@angular/router-deprecated";
import {Router, RouteParams} from "@angular/router-deprecated";
import {GalleryService} from "./gallery.service";
import {Directory} from "../../../common/entities/Directory";
import {Message} from "../../../common/entities/Message";
@ -16,35 +16,35 @@ import {GallerySearchComponent} from "./search/search.gallery.component";
selector: 'gallery',
templateUrl: 'app/gallery/gallery.component.html',
styleUrls: ['app/gallery/gallery.component.css'],
directives:[GalleryGridComponent,
GalleryDirectoryComponent,
GalleryLightboxComponent,
FrameComponent,
GallerySearchComponent]
directives: [GalleryGridComponent,
GalleryDirectoryComponent,
GalleryLightboxComponent,
FrameComponent,
GallerySearchComponent]
})
export class GalleryComponent implements OnInit{
export class GalleryComponent implements OnInit {
currentDirectory:Directory = new Directory();
constructor(private _galleryService:GalleryService,
private _params: RouteParams,
private _authService: AuthenticationService,
private _router: Router) {
private _params:RouteParams,
private _authService:AuthenticationService,
private _router:Router) {
}
ngOnInit(){
ngOnInit() {
if (!this._authService.isAuthenticated()) {
this._router.navigate(['Login']);
return;
}
let directoryName = this._params.get('directory');
console.log(this._params);
console.log(directoryName);
directoryName = directoryName ? directoryName : "";
this._galleryService.getDirectory(directoryName).then(( message:Message<Directory>) => {
if(message.error){
this._galleryService.getDirectory(directoryName).then((message:Message<Directory>) => {
if (message.error) {
//TODO: implement
return;
}
@ -52,9 +52,7 @@ export class GalleryComponent implements OnInit{
this.currentDirectory = message.result;
});
}
}

View File

@ -1,19 +1,18 @@
///<reference path="../../browser.d.ts"/>
import {Injectable} from '@angular/core';
import {Injectable} from "@angular/core";
import {NetworkService} from "../model/network/network.service.ts";
import {Http} from "@angular/http";
import {Message} from "../../../common/entities/Message";
import {Directory} from "../../../common/entities/Directory";
import {Directory} from "../../../common/entities/Directory";
@Injectable()
export class GalleryService{
export class GalleryService {
constructor(private _networkService:NetworkService){
constructor(private _networkService:NetworkService) {
}
public getDirectory(directoryName:string): Promise<Message<Directory>>{
return this._networkService.getJson("/gallery/content/"+directoryName);
public getDirectory(directoryName:string):Promise<Message<Directory>> {
return this._networkService.getJson("/gallery/content/" + directoryName);
}
}

View File

@ -1,25 +1,24 @@
import {Photo} from "../../../../common/entities/Photo";
export class GridRowBuilder{
export class GridRowBuilder {
private photoRow:Array<Photo> = [];
private photoIndex:number = 0; //index of the last pushed photo to the photoRow
constructor(private photos:Array<Photo>, private startIndex:number, private photoMargin:number, private containerWidth:number){
constructor(private photos:Array<Photo>, private startIndex:number, private photoMargin:number, private containerWidth:number) {
this.photoIndex = startIndex;
}
public addPhotos(number:number){
for(let i = 0; i < number; i++){
public addPhotos(number:number) {
for (let i = 0; i < number; i++) {
this.addPhoto();
}
}
public addPhoto():boolean{
if(this.photoIndex + 1 > this.photos.length){
public addPhoto():boolean {
if (this.photoIndex + 1 > this.photos.length) {
return false;
}
this.photoRow.push(this.photos[this.photoIndex]);
@ -27,8 +26,8 @@ export class GridRowBuilder{
return true;
}
public removePhoto():boolean{
if(this.photoIndex - 1 < this.startIndex){
public removePhoto():boolean {
if (this.photoIndex - 1 < this.startIndex) {
return false;
}
this.photoIndex--;
@ -36,11 +35,11 @@ export class GridRowBuilder{
return true;
}
public getPhotoRow():Array<Photo>{
public getPhotoRow():Array<Photo> {
return this.photoRow;
}
public adjustRowHeightBetween(minHeight:number,maxHeight:number){
public adjustRowHeightBetween(minHeight:number, maxHeight:number) {
while (this.calcRowHeight() > maxHeight && this.addPhoto() === true) { //row too high -> add more images
}
@ -48,18 +47,18 @@ export class GridRowBuilder{
}
//keep at least one photo int thr row
if(this.photoRow.length <= 0){
if (this.photoRow.length <= 0) {
this.addPhoto();
}
}
public calcRowHeight():number {
let width = 0;
for(let i = 0; i < this.photoRow.length; i++){
for (let i = 0; i < this.photoRow.length; i++) {
width += ((this.photoRow[i].width) / (this.photoRow[i].height)); //summing up aspect ratios
}
let height = (this.containerWidth - this.photoRow.length * (this.photoMargin * 2) - 1) / width; //cant be equal -> width-1
return height +(this.photoMargin * 2);
return height + (this.photoMargin * 2);
};
}

View File

@ -45,8 +45,7 @@ export class GalleryLightboxComponent {
from.top -= this.getBodyScrollTop();
let fromImage = {width: from.width + "px", height: from.height + "px", top: "0px", left:"0px"};
let fromImage = {width: from.width + "px", height: from.height + "px", top: "0px", left: "0px"};
let toImage = this.calcLightBoxPhotoDimension(this.activePhoto.photo).toStyle();
this.forceAnimateFrom(fromImage,
@ -91,7 +90,7 @@ export class GalleryLightboxComponent {
let fromImage = this.calcLightBoxPhotoDimension(this.activePhoto.photo).toStyle();
let toImage = {width: to.width + "px", height: to.height + "px", top: "0px", left:"0px"};
let toImage = {width: to.width + "px", height: to.height + "px", top: "0px", left: "0px"};
this.forceAnimateTo(fromImage,
toImage,
@ -103,7 +102,7 @@ export class GalleryLightboxComponent {
}
private findPhotoComponenet(photo){
private findPhotoComponenet(photo) {
let galleryPhotoComponents = this.gridPhotoQL.toArray();
let selectedPhoto:GalleryPhotoComponent = null;
for (let i = 0; i < galleryPhotoComponents.length; i++) {
@ -173,21 +172,21 @@ export class GalleryLightboxComponent {
return window.innerHeight;
}
private calcLightBoxPhotoDimension(photo:Photo):Dimension{
private calcLightBoxPhotoDimension(photo:Photo):Dimension {
let width = 0;
let height = 0;
if (photo.height > photo.width) {
width= Math.round(photo.width * (this.getScreenHeight() / photo.height));
height= this.getScreenHeight();
width = Math.round(photo.width * (this.getScreenHeight() / photo.height));
height = this.getScreenHeight();
} else {
width= this.getScreenWidth();
height= Math.round(photo.height * (this.getScreenWidth() / photo.width));
width = this.getScreenWidth();
height = Math.round(photo.height * (this.getScreenWidth() / photo.width));
}
let top = (this.getScreenHeight() / 2 - height / 2);
let left = (this.getScreenWidth() / 2 - width / 2);
return new Dimension(top,left,width,height);
return new Dimension(top, left, width, height);
}
}

View File

@ -1,34 +1,34 @@
///<reference path="../../../browser.d.ts"/>
import {Component, Input, ElementRef, ViewChild} from '@angular/core';
import {Component, Input, ElementRef, ViewChild} from "@angular/core";
import {Photo} from "../../../../common/entities/Photo";
import {Directory} from "../../../../common/entities/Directory";
import {IRenderable, Dimension} from "../../model/IRenderable";
import {Directory} from "../../../../common/entities/Directory";
import {IRenderable, Dimension} from "../../model/IRenderable";
@Component({
selector: 'gallery-photo',
templateUrl: 'app/gallery/photo/photo.gallery.component.html',
styleUrls: ['app/gallery/photo/photo.gallery.component.css'],
})
export class GalleryPhotoComponent implements IRenderable{
@Input() photo: Photo;
@Input() directory: Directory;
export class GalleryPhotoComponent implements IRenderable {
@Input() photo:Photo;
@Input() directory:Directory;
@ViewChild("image") imageRef:ElementRef;
constructor() {
}
getPhotoPath(){
return Photo.getThumbnailPath(this.directory,this.photo);
getPhotoPath() {
return Photo.getThumbnailPath(this.directory, this.photo);
}
public getDimension():Dimension{
public getDimension():Dimension {
return new Dimension(this.imageRef.nativeElement.offsetTop,
this.imageRef.nativeElement.offsetLeft,
this.imageRef.nativeElement.width,
this.imageRef.nativeElement.height);
this.imageRef.nativeElement.offsetLeft,
this.imageRef.nativeElement.width,
this.imageRef.nativeElement.height);
}
}

View File

@ -1,7 +1,6 @@
///<reference path="../../../browser.d.ts"/>
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";
import {NetworkService} from "../../model/network/network.service";
import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem";
import {Message} from "../../../../common/entities/Message";
@ -10,11 +9,11 @@ import {Message} from "../../../../common/entities/Message";
export class AutoCompleteService {
constructor(private _networkService:NetworkService){
constructor(private _networkService:NetworkService) {
}
public autoComplete(text:string): Promise<Message<Array<AutoCompleteItem> >> {
return this._networkService.getJson("/gallery/autocomplete/"+text);
public autoComplete(text:string):Promise<Message<Array<AutoCompleteItem> >> {
return this._networkService.getJson("/gallery/autocomplete/" + text);
}

View File

@ -12,59 +12,58 @@ import {Message} from "../../../../common/entities/Message";
providers: [AutoCompleteService]
})
export class GallerySearchComponent {
autoCompleteItems:Array<AutoCompleteRenderItem> = [];
constructor(private _autoCompleteService:AutoCompleteService) {
}
getSuggestions(event:KeyboardEvent){
let searchText = (<HTMLInputElement>event.target).value;
if(searchText.trim().length > 0) {
this._autoCompleteService.autoComplete(searchText).then((message:Message<Array<AutoCompleteItem>>) =>{
if(message.error){
getSuggestions(event:KeyboardEvent) {
let searchText = (<HTMLInputElement>event.target).value;
if (searchText.trim().length > 0) {
this._autoCompleteService.autoComplete(searchText).then((message:Message<Array<AutoCompleteItem>>) => {
if (message.error) {
//TODO: implement
console.error(message.error);
return;
}
this.showSuggestions(message.result,searchText);
this.showSuggestions(message.result, searchText);
});
}else{
this.emptyAutoComplete();
} else {
this.emptyAutoComplete();
}
}
private showSuggestions(suggestions:Array<AutoCompleteItem>,searchText:string){
private showSuggestions(suggestions:Array<AutoCompleteItem>, searchText:string) {
this.emptyAutoComplete();
suggestions.forEach((item)=>{
suggestions.forEach((item)=> {
let preIndex = item.text.toLowerCase().indexOf(searchText.toLowerCase());
let renderItem = new AutoCompleteRenderItem();
if(preIndex > -1){
renderItem.preText = item.text.substring(0,preIndex);
if (preIndex > -1) {
renderItem.preText = item.text.substring(0, preIndex);
renderItem.highLightText = item.text.substring(preIndex, preIndex + searchText.length);
renderItem.postText = item.text.substring(preIndex + searchText.length);
}else{
renderItem.postText = item.text.substring(preIndex + searchText.length);
} else {
renderItem.postText = item.text;
}
this.autoCompleteItems.push(renderItem);
});
}
public onFocusLost(event){
public onFocusLost(event) {
this.autoCompleteItems = [];
}
private emptyAutoComplete(){
this.autoCompleteItems = [];
private emptyAutoComplete() {
this.autoCompleteItems = [];
}
}
class AutoCompleteRenderItem{
constructor(public preText:string = "",public highLightText:string = "", public postText:string = ""){
class AutoCompleteRenderItem {
constructor(public preText:string = "", public highLightText:string = "", public postText:string = "") {
}
}

View File

@ -1,30 +1,31 @@
///<reference path="../../browser.d.ts"/>
import {Component, OnInit} from '@angular/core';
import {LoginCredential} from '../../../common/entities/LoginCredential';
import {Component, OnInit} from "@angular/core";
import {LoginCredential} from "../../../common/entities/LoginCredential";
import {AuthenticationService} from "../model/network/authentication.service.ts";
import {Router} from "@angular/router-deprecated";
import {FORM_DIRECTIVES} from "@angular/common";
import {Router} from "@angular/router-deprecated";
import {FORM_DIRECTIVES} from "@angular/common";
@Component({
selector: 'login',
templateUrl: 'app/login/login.component.html',
styleUrls:['app/login/login.component.css'],
directives:[FORM_DIRECTIVES]
styleUrls: ['app/login/login.component.css'],
directives: [FORM_DIRECTIVES]
})
export class LoginComponent implements OnInit{
loginCredential: LoginCredential;
constructor(private _authService: AuthenticationService, private _router: Router) {
export class LoginComponent implements OnInit {
loginCredential:LoginCredential;
constructor(private _authService:AuthenticationService, private _router:Router) {
this.loginCredential = new LoginCredential();
}
ngOnInit(){
ngOnInit() {
if (this._authService.isAuthenticated()) {
this._router.navigate(['Gallery',{directory:"/"}]);
this._router.navigate(['Gallery', {directory: "/"}]);
}
}
onLogin(){
onLogin() {
this._authService.login(this.loginCredential);
}
}

View File

@ -1,13 +1,7 @@
///<reference path="../../../browser.d.ts"/>
import {
it,
inject,
beforeEachProviders
} from '@angular/core/testing';
import {provide} from '@angular/core';
import {it, inject, beforeEachProviders} from "@angular/core/testing";
import {provide} from "@angular/core";
import {UserService} from "./user.service.ts";
import {User} from "../../../../common/entities/User";
import {Message} from "../../../../common/entities/Message";
@ -16,8 +10,8 @@ import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {AuthenticationService} from "./authentication.service";
class MockUserService {
public login(credential:LoginCredential){
return Promise.resolve(new Message<User>(null,new User(0,"testUserName")))
public login(credential:LoginCredential) {
return Promise.resolve(new Message<User>(null, new User(0, "testUserName")))
}
}
@ -28,24 +22,24 @@ describe('AuthenticationService', () => {
]);
it('should call User service login', inject([ AuthenticationService,UserService ], (authService, userService) => {
spyOn(userService,"login").and.callThrough();
it('should call User service login', inject([AuthenticationService, UserService], (authService, userService) => {
spyOn(userService, "login").and.callThrough();
expect(userService.login).not.toHaveBeenCalled();
authService.login();
expect(userService.login).toHaveBeenCalled();
}));
it('should have NO Authenticated use', inject([ AuthenticationService ], (authService) => {
it('should have NO Authenticated use', inject([AuthenticationService], (authService) => {
expect(authService.getUser()).toBe(null);
expect(authService.isAuthenticated()).toBe(false);
}));
it('should have Authenticated use', inject([ AuthenticationService ], (authService) => {
spyOn(authService.OnAuthenticated,"trigger").and.callThrough();
it('should have Authenticated use', inject([AuthenticationService], (authService) => {
spyOn(authService.OnAuthenticated, "trigger").and.callThrough();
authService.login();
authService.OnAuthenticated.on(() =>{
authService.OnAuthenticated.on(() => {
expect(authService.OnAuthenticated.trigger).toHaveBeenCalled();
expect(authService.getUser()).not.toBe(null);
expect(authService.isAuthenticated()).toBe(true);

View File

@ -1,70 +1,70 @@
///<reference path="../../../browser.d.ts"/>
import {Injectable} from '@angular/core';
import {Injectable} from "@angular/core";
import {User} from "../../../../common/entities/User";
import {Event} from "../../../../common/event/Event";
import {UserService} from "./user.service.ts";
import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {Message} from "../../../../common/entities/Message";
import { Cookie } from 'ng2-cookies/ng2-cookies';
import {Cookie} from "ng2-cookies/ng2-cookies";
import {ErrorCodes} from "../../../../common/entities/Error";
declare module ServerInject{
export var user;
declare module ServerInject {
export var user;
}
@Injectable()
export class AuthenticationService{
export class AuthenticationService {
private _user:User = null;
public OnAuthenticated:Event<User>;
constructor(private _userService: UserService){
constructor(private _userService:UserService) {
this.OnAuthenticated = new Event();
//picking up session..
if(this.isAuthenticated() == false && Cookie.getCookie('pigallery2-session') != null){
if(typeof ServerInject !== "undefined" && typeof ServerInject.user !== "undefined"){
if (this.isAuthenticated() == false && Cookie.getCookie('pigallery2-session') != null) {
if (typeof ServerInject !== "undefined" && typeof ServerInject.user !== "undefined") {
console.log("user found");
this.setUser(ServerInject.user);
}
this.getSessionUser();
this.getSessionUser();
}
}
private getSessionUser(){
this._userService.getSessionUser().then( (message:Message<User>) =>{
if(message.error){
private getSessionUser() {
this._userService.getSessionUser().then((message:Message<User>) => {
if (message.error) {
console.log(message.error);
}else{
} else {
this._user = message.result;
this.OnAuthenticated.trigger(this._user);
}
});
}
private setUser(user:User){
private setUser(user:User) {
this._user = user;
this.OnAuthenticated.trigger(this._user);
}
public login(credential:LoginCredential) {
this._userService.login(credential).then( (message:Message<User>) =>{
if(message.error){
console.log(ErrorCodes[message.error.code] + "message: "+ message.error.message);
}else{
this._userService.login(credential).then((message:Message<User>) => {
if (message.error) {
console.log(ErrorCodes[message.error.code] + "message: " + message.error.message);
} else {
this.setUser(message.result);
}
});
}
public isAuthenticated():boolean{
public isAuthenticated():boolean {
return (this._user && this._user != null) ? true : false;
}
public getUser(){
public getUser() {
return this._user;
}

View File

@ -1,7 +1,7 @@
///<reference path="../../../browser.d.ts"/>
import {it, inject, beforeEachProviders, beforeEach, afterEach} from "@angular/core/testing";
import {BaseRequestOptions, Http, Response, ResponseOptions, ResponseType, BaseResponseOptions} from "@angular/http";
import {BaseRequestOptions, Http, Response, ResponseOptions} from "@angular/http";
import {MockBackend, MockConnection} from "@angular/http/testing";
import {provide} from "@angular/core";
import "rxjs/Rx";
@ -114,9 +114,9 @@ describe('NetworkService Fail tests', () => {
beforeEach(inject([MockBackend], (backend) => {
backend.connections.subscribe((c) => {
connection = c;
connection.mockError({name :"errorName",message:testError});
connection = c;
connection.mockError({name: "errorName", message: testError});
});
}));
@ -161,7 +161,7 @@ describe('NetworkService Fail tests', () => {
networkService.deleteJson(testUrl).then((res:Message<any>) => {
expect(res).toBe(null);
}).catch((err) => {
}).catch((err) => {
expect(err).toBe(testError);
});
}));

View File

@ -1,54 +1,54 @@
///<reference path="../../../browser.d.ts"/>
import {Injectable} from '@angular/core';
import {Injectable} from "@angular/core";
import {Http, Headers, RequestOptions} from "@angular/http";
import {Message} from "../../../../common/entities/Message";
import "rxjs/Rx";
@Injectable()
export class NetworkService{
export class NetworkService {
_baseUrl = "/api";
constructor(protected _http:Http){
constructor(protected _http:Http) {
}
private callJson<T>(method:string, url:string, data:any = {}): Promise<T>{
let body = JSON.stringify( data );
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
private callJson<T>(method:string, url:string, data:any = {}):Promise<T> {
let body = JSON.stringify(data);
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
if(method == "get" || method == "delete"){
return this._http[method](this._baseUrl+url, options)
if (method == "get" || method == "delete") {
return this._http[method](this._baseUrl + url, options)
.toPromise()
.then(res => <Message<any>> res.json())
.catch(NetworkService.handleError);
}
return this._http[method](this._baseUrl+url, body, options)
return this._http[method](this._baseUrl + url, body, options)
.toPromise()
.then(res => <Message<any>> res.json())
.catch(NetworkService.handleError);
}
public postJson<T>(url:string, data:any = {}): Promise<T>{
return this.callJson("post",url,data);
public postJson<T>(url:string, data:any = {}):Promise<T> {
return this.callJson("post", url, data);
}
public putJson<T>(url:string, data:any = {}): Promise<T>{
return this.callJson("put",url,data);
public putJson<T>(url:string, data:any = {}):Promise<T> {
return this.callJson("put", url, data);
}
public getJson<T>(url:string): Promise<T>{
return this.callJson("get",url);
public getJson<T>(url:string):Promise<T> {
return this.callJson("get", url);
}
public deleteJson<T>(url:string): Promise<T>{
return this.callJson("delete",url);
public deleteJson<T>(url:string):Promise<T> {
return this.callJson("delete", url);
}
private static handleError (error: any) {
private static handleError(error:any) {
// TODO: in a real world app, we may send the error to some remote logging infrastructure
// instead of just logging it to the console
console.error(error);

View File

@ -1,14 +1,12 @@
///<reference path="../../../browser.d.ts"/>
import {it, inject, beforeEachProviders, beforeEach, afterEach} from "@angular/core/testing";
import {BaseRequestOptions, Http, Response, ResponseOptions} from "@angular/http";
import {MockBackend, MockConnection} from "@angular/http/testing";
import {it, inject, beforeEachProviders} from "@angular/core/testing";
import {BaseRequestOptions, Http} from "@angular/http";
import {MockBackend} from "@angular/http/testing";
import {provide} from "@angular/core";
import "rxjs/Rx";
import {NetworkService} from "./network.service";
import {Message} from "../../../../common/entities/Message";
import {UserService} from "./user.service";
import {LoginComponent} from "../../login/login.component";
import {LoginCredential} from "../../../../common/entities/LoginCredential";
@ -28,25 +26,20 @@ describe('UserService', () => {
]);
it('should call postJson at login', inject([UserService,NetworkService], (userService,networkService) => {
spyOn(networkService,"postJson");
let credential = new LoginCredential("name","pass");
it('should call postJson at login', inject([UserService, NetworkService], (userService, networkService) => {
spyOn(networkService, "postJson");
let credential = new LoginCredential("name", "pass");
userService.login(credential);
expect(networkService.postJson).toHaveBeenCalled();
expect(networkService.postJson.calls.argsFor(0)).toEqual(["/user/login",{"loginCredential": credential}]);
expect(networkService.postJson.calls.argsFor(0)).toEqual(["/user/login", {"loginCredential": credential}]);
}));
it('should call getJson at getSessionUser', inject([UserService,NetworkService], (userService,networkService) => {
spyOn(networkService,"getJson");
it('should call getJson at getSessionUser', inject([UserService, NetworkService], (userService, networkService) => {
spyOn(networkService, "getJson");
userService.getSessionUser();
expect(networkService.getJson).toHaveBeenCalled();
expect(networkService.getJson.calls.argsFor(0)).toEqual(["/user/login"]);
}));
});

View File

@ -1,27 +1,25 @@
///<reference path="../../../browser.d.ts"/>
import {Injectable} from '@angular/core';
import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {Http} from "@angular/http";
import {Injectable} from "@angular/core";
import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {NetworkService} from "./network.service.ts";
import {User} from "../../../../common/entities/User";
import {Message} from "../../../../common/entities/Message";
@Injectable()
export class UserService{
export class UserService {
constructor(private _networkService:NetworkService){
constructor(private _networkService:NetworkService) {
}
public login(credential:LoginCredential): Promise<Message<User>>{
return this._networkService.postJson("/user/login",{"loginCredential": credential});
public login(credential:LoginCredential):Promise<Message<User>> {
return this._networkService.postJson("/user/login", {"loginCredential": credential});
}
public getSessionUser(): Promise<Message<User>>{
public getSessionUser():Promise<Message<User>> {
return this._networkService.getJson("/user/login");
}
}

View File

@ -4,7 +4,7 @@ import {UserRoles} from "../../../common/entities/User";
@Pipe({name: 'stringifyRole'})
export class StringifyRole implements PipeTransform {
transform(role: string): number {
transform(role:string):number {
return UserRoles[role];
}
}

View File

@ -1,6 +1,6 @@
///<reference path="../typings/browser.d.ts"/>
import { bootstrap } from '@angular/platform-browser-dynamic';
import {bootstrap} from "@angular/platform-browser-dynamic";
import {AppComponent} from "./app/app.component.ts";
bootstrap(AppComponent)