Browse Source

Первый коммит

Alec 4 years ago
commit
c5903c93ae

BIN
.DS_Store


BIN
assets/.DS_Store


+ 4 - 0
assets/css/admin.css

@@ -0,0 +1,4 @@
+.admin {
+    background-color: rgb(212, 190, 233);
+    margin: 20px 0;
+}

+ 49 - 0
assets/css/authorization.css

@@ -0,0 +1,49 @@
+* {
+    box-sizing: border-box;
+    margin: 0;
+    padding: 0;
+}
+
+body {
+    font-family: sans-serif;
+    font-size: 14px;
+    display: flex;
+    height: 100vh;
+    justify-content: center;
+    align-items: center;
+    flex-direction: column;
+}
+.form {
+    width: 200px;
+    display: flex;
+    flex-wrap: wrap;
+    padding: 10px 20px;
+    background-color: white;
+    border-radius: 10px;
+    box-shadow: 0 0 16px black;
+}
+.form > * {
+    margin: 10px 0;
+    width: 100%;
+    display: block;
+    height: 25px;
+    border-radius: 5px;
+    border: 1px solid gray;
+    font-family: sans-serif;
+    outline: none;
+}
+.form > input {
+    padding-inline-start: 10px;
+}
+button:hover,
+input:focus {
+    background-color: rgb(242, 228, 255);
+    border-color: blueviolet;
+    color: blueviolet;
+}
+button:hover {
+    cursor: pointer;
+}
+a {
+    margin-top: 20px;
+}

+ 92 - 0
assets/css/message.css

@@ -0,0 +1,92 @@
+.messenger {
+  left: 10px;
+  width: 350px;
+  position: fixed;
+  z-index: 250;
+  bottom: 10px;
+  pointer-events: none;
+  overflow: hidden;
+  text-align: center;
+}
+.messenger > div {
+  padding: 6px 14px;
+  margin-top: 2px;
+  min-height: 60px;
+  -webkit-border-radius: 4px;
+          border-radius: 4px;
+  /* border: 1px solid rgba(0, 0, 0, 0.85); */
+  background-color: rgba(0, 0, 0, 0.5);
+  color: #f0f0f0;
+  pointer-events: auto;
+  cursor: pointer;
+  position: relative;
+}
+.messenger > div:hover {
+  background-color: rgba(0, 0, 0, 0.55);
+  color: #ffffff;
+}
+.messenger > div.removing {
+  opacity: 0;
+  -webkit-transition: opacity;
+  -o-transition: opacity;
+  transition: opacity;
+  -webkit-transition-timing-function: ease-out;
+       -o-transition-timing-function: ease-out;
+          transition-timing-function: ease-out;
+}
+.messenger > div.removing.short {
+  -webkit-transition-duration: 0.1s;
+       -o-transition-duration: 0.1s;
+          transition-duration: 0.1s;
+}
+.messenger > div.removing.long {
+  -webkit-transition-duration: 2s;
+       -o-transition-duration: 2s;
+          transition-duration: 2s;
+}
+.messenger > div > .close {
+  position: absolute;
+  right: 5px;
+  top: 5px;
+  width: 16px;
+  height: 16px;
+  z-index: 300;
+}
+.messenger > div > .close::before,
+.messenger > div > .close::after {
+  content: "";
+  position: absolute;
+  width: 3px;
+  left: 50%;
+  top: 0;
+  bottom: 0;
+  transform: translateX(-50%) rotateZ(-45deg);
+  background-color: rgb(207, 207, 207);
+}
+.messenger > div > .close::after {
+  transform: translateX(-50%) rotateZ(45deg);
+}
+.messenger > div > .close:hover::before,
+.messenger > div > .close:hover::after {
+  background-color: white;
+}
+@media (max-width: 586px) {
+  .messenger {
+    left: 0;
+    bottom: 0;
+    width: 100%;
+  }
+  .messenger > div {
+    margin: 5px 10px;
+  }
+}
+@media (min-width: 587px) and (max-width: 1151px) {
+  .messenger {
+    left: 0;
+    bottom: 0;
+    width: 450px;
+  }
+  .messenger > div {
+    margin: 5px 10px;
+  }
+}

+ 123 - 0
assets/css/style.css

@@ -0,0 +1,123 @@
+@font-face {
+    font-family: Scada;
+    font-weight: normal;
+    font-style: normal;
+    src: url(/assets/fonts/Scada-Regular.ttf);
+}
+@font-face {
+    font-family: Scada;
+    font-weight: normal;
+    font-style: italic;
+    src: url(/assets/fonts/Scada-Italic.ttf);
+}
+@font-face {
+    font-family: Scada;
+    font-weight: bold;
+    font-style: normal;
+    src: url(/assets/fonts/Scada-Bold.ttf);
+}
+@font-face {
+    font-family: Scada;
+    font-weight: bold;
+    font-style: italic;
+    src: url(/assets/fonts/Scada-BoldItalic.ttf);
+}
+
+* {
+    margin: 0;
+    box-sizing: border-box;
+}
+body {
+    font-family: Scada;
+    font-size: 16px;
+    line-height: 1.4;
+    width: 1100px;
+    height: 100vh;
+    margin-left: auto;
+    margin-right: auto;
+    background-color: #f5f5f5;
+    display: flex;
+    flex-direction: column;
+}
+
+.logo {
+    width: 80px;
+    height: 80px;
+
+    /* Удалить, если будет установлена картинка */
+    background-color: #00bcd4;
+}
+
+.org-name {
+    font-size: 24px;
+    color: rgb(80, 80, 80);
+}
+
+.header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 20px 40px;
+    background-color: white;
+}
+header {
+    flex-shrink: 0;
+}
+main {
+    background-color: white;
+    height: 100%;
+    padding: 20px;
+    overflow: auto;
+    position: relative;
+}
+footer {
+    background-color: rgb(70, 70, 70);
+    height: 40px;
+    flex-shrink: 0;
+    color: rgb(230, 230, 230);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+nav {
+	display: flex;
+    justify-content: space-evenly;
+    background-color: #B2EBF2;
+    padding-top: 2px;
+}
+nav > .item > a {
+	text-decoration: none;
+	color: #00838F;
+    font-size: 16px;
+    font-weight: bold;
+    text-transform: uppercase;
+	padding: 10px;
+    display: block;
+    border-bottom: 2px solid transparent;
+}
+nav > .item > a:hover {
+    color: #006064;
+    border-color: #006064;
+}
+
+.body {
+    display: grid;
+    grid-template-columns: 200px 1fr;
+    grid-template-rows: 1fr;
+    grid-gap: 20px;
+}
+
+.catalog > .item {
+    padding: 10px;
+    color: black;
+}
+.catalog > .item:hover {
+    color: #006064;
+    background-color: #E0F7FA;
+    cursor: pointer;
+}
+
+p {
+    margin: 10px 0;
+}

BIN
assets/fonts/Scada-Bold.ttf


BIN
assets/fonts/Scada-BoldItalic.ttf


BIN
assets/fonts/Scada-Italic.ttf


BIN
assets/fonts/Scada-Regular.ttf


+ 0 - 0
assets/js/admin.js


+ 20 - 0
assets/js/authorization.js

@@ -0,0 +1,20 @@
+let LogIn = document.querySelector("#LogIn");
+let Password = document.querySelector("#Password");
+let Button = document.querySelector("button");
+
+if (Button) {
+	Button.onclick = function () {
+		if (LogIn && Password) {
+			Sender.Go(postLogin, "/login", { Login: LogIn.value, Password: Password.value });
+		}
+	};
+}
+
+function postLogin(answer) {
+	if (answer.Result && answer.Result == true) {
+		alert("Привет, " + answer.Name);
+		location.href = "/";
+	} else {
+		Notify.Show("Неверный логин/пароль");
+	}
+}

+ 89 - 0
assets/js/message.js

@@ -0,0 +1,89 @@
+Object.defineProperty(Object.prototype, "Error", {
+	value: null,
+	enumerable: false,
+});
+
+const NotifyBuild = (function () {
+	// локальная область видимости (приватные поля и методы)
+
+	/**
+	 * Задержка в миллисекундах перед удалением элемента (сообщения) при клике (должен совпадать с классом removing, в котором происходит анимация исчезновения (transition opacity))
+	 */
+	const HARDREMOVE_TIME = 100;
+
+	/**
+	 * Задержка в миллисекундах перед удалением элемента (сообщения) при автоматическом исчезновении (должен совпадать с классом removing-long, в котором происходит анимация исчезновения (transition opacity))
+	 */
+	const AUTOREMOVE_TIME = 2000;
+
+	const REMOVING_SHORT = "short";
+	const REMOVING_LONG = "long";
+
+	/**
+	 * Счётчик ID для создаваемых сообщений
+	 */
+	let MESSAGE_COUNTER = -1;
+
+	/**
+	 * Удаляет сообщение (или другой элемент, к которому было привязано данное событие)
+	 * @param {Number} time время, через которое сообщение будет удалено из DOM (в миллисекундах)
+	 */
+	const removeMessage = function (time = HARDREMOVE_TIME, transition = REMOVING_SHORT) {
+		this.classList.add("removing", transition);
+		setTimeout(
+			function ($elem) {
+				$elem.remove();
+			},
+			time,
+			this
+		);
+	};
+
+	/**
+	 * Для автоматического удаления сообщений, вызывается в setTimeout во время создания текущего сообщения
+	 */
+	const autoRemoveMessage = function () {
+		if (this instanceof HTMLElement) {
+			removeMessage.call(this, AUTOREMOVE_TIME, REMOVING_LONG);
+		}
+	};
+
+	/**
+	 * Класс создания всплывающих сообщений. Конструктор создаёт элемент-контейнер для помещения элементов-сообщений и добавляет его в конец BODY. Класс имеет один метод - Show - показать сообщение (создать элемент-сообщение и поместить в элемент-контейнер на указанное время жизни (аргумент time))
+	 */
+	return class Messenger {
+		/**
+		 * Конструктор сообщений
+		 */
+		constructor() {
+			this.$message = document.createElement("div");
+			this.$message.classList.add("messenger");
+			this.$message.id = "idMessenger";
+
+			document.body.appendChild(this.$message);
+		}
+
+		/**
+		 * Вывести сообщение одного из трёх типов. Выводит в прямоугольной области в нижнем правом углу экрана. А также дублируется в лог консоли.
+		 * @param {String} msg текст сообщения, допускается HTML формат
+		 * @param {MESSAGE_TYPE} type тип отображения сообщения (ошибка, предупреждение, информация)
+		 * @param {Number} time время отображения сообщения в миллисекундах
+		 */
+		Show(msg, type = "info", time = 10000) {
+			let message = document.createElement("div");
+			message.id = `idMsg${++MESSAGE_COUNTER}`;
+			message.innerHTML = msg;
+			message.classList.add(type);
+			let close = document.createElement("div");
+			close.classList.add("close");
+			close.onclick = removeMessage.bind(message);
+			message.append(close);
+
+			this.$message.appendChild(message);
+
+			setTimeout(autoRemoveMessage.bind(message), time);
+		}
+	}
+})();
+
+var Notify = new NotifyBuild();

+ 67 - 0
assets/js/query.js

@@ -0,0 +1,67 @@
+var Sender = (function () {
+	var module = {};
+
+	/**
+	 * Выполнить POST запрос
+	 * @param {Function} callback Функция обработчик результата запроса
+	 * @param {String} uri Ресурс запроса
+	 * @param {Object} params Параметры, передаваемые на сервер
+	 * @param {Object} callbackParams Параметры, которые необходимо передать в функцию callback
+	 * @param {Boolean} isAsinc Использовать ли асинхронный запрос (по умолчанию true)
+	 */
+	module.Go = function (callback, uri, params, callbackParams, isAsinc = true) {
+		if (uri == null || typeof uri != "string") {
+			console.warn("URI не был передан");
+			return;
+		}
+
+		if (params == null || typeof params != "object") {
+			params = {};
+		}
+
+		var xhr = new XMLHttpRequest();
+
+		// * Обработка результата запроса
+		xhr.onload = function (event) {
+			var data;
+
+			try {
+				data = JSON.parse(this.response);
+			} catch (error) {
+				Notify.Show(error);
+				data = null;
+			} finally {
+				if (typeof callback == "function") {
+					var nerror = data || data.Error || data.Error === null || data.Error === "null";
+
+					if (nerror) {
+						callback(data, callbackParams);
+					} else {
+						Notify.Show("Произошла ошибка в процессе выполнения запроса");
+					}
+				}
+			}
+		};
+
+		xhr.onabort = function (event) {
+			Notify.Show("Выполнение запроса было прервано...");
+		};
+
+		xhr.onerror = function (event) {
+			Notify.Show("Выполнение запроса завершилось неудачей. Перезагрузите страницу и повторите попытку. Если проблема сохраняется, пожалуйста, сообщите об этом администратору admin@ktk-45.ru");
+		};
+
+		xhr.ontimeout = function (event) {
+			Notify.Show("Время ожидания запроса истекло... Проверьте соединение с интернетом");
+		};
+
+		xhr.open("POST", uri, isAsinc);
+
+		xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
+		xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+		xhr.send(JSON.stringify(params));
+	};
+
+	return module;
+})();

+ 21 - 0
db.go

@@ -0,0 +1,21 @@
+package main
+
+import (
+	"database/sql"
+	"fmt"
+)
+
+func connect() {
+	var e error
+	db, e = sql.Open("postgres", fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", cfg.PgHost, cfg.PgPort, cfg.PgUser, cfg.PgPass, cfg.PgBase))
+	if e != nil {
+		panic("Не удалось подключиться к базе данных. " + e.Error())
+	}
+}
+
+type user struct {
+	Phone    string `json:"Login"`
+	Password string `json:"Password"`
+	Name     string `json:"Name"`
+	Role     string `json:"Role"`
+}

+ 38 - 0
html/404.html

@@ -0,0 +1,38 @@
+{{define "404"}}
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>404 Not Found</title>
+    <style>
+        body {
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            background-color: rgb(232, 255, 247);
+            font-family: sans-serif;
+        }
+
+        b {
+            color: rgb(173, 255, 228);
+            font-size: 50vh;
+            font-weight: bold;
+        }
+
+        div {
+            font-size: 20px;
+            color: cadetblue;
+        }
+    </style>
+</head>
+
+<body>
+    <b>404</b>
+    <div>Sorry, page not found.</div>
+</body>
+
+</html>
+{{end}}

+ 3 - 0
html/admin.html

@@ -0,0 +1,3 @@
+{{define "admin"}}
+<div class="admin">Тут можно создать какую-нибудь панель администратора</div>
+{{end}}

+ 27 - 0
html/authorization.html

@@ -0,0 +1,27 @@
+{{define "authorization"}}
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link rel="stylesheet" href="/assets/css/message.css">
+    <link rel="stylesheet" href="/assets/css/authorization.css">
+    <title>Document</title>
+</head>
+
+<body>
+    <div class="form">
+        <input type="text" id="LogIn" placeholder="Логин">
+        <input type="password" id="Password" placeholder="Пароль">
+        <button>Авторизация</button>
+    </div>
+    <a href="/">Назад</a>
+
+    <script src="/assets/js/message.js"></script>
+    <script src="/assets/js/query.js"></script>
+    <script src="/assets/js/authorization.js"></script>
+</body>
+
+</html>
+{{end}}

+ 5 - 0
html/footer.html

@@ -0,0 +1,5 @@
+{{define "footer"}}
+<footer>
+    (c) Все права защищены 2020
+</footer>
+{{end}}

+ 24 - 0
html/header.html

@@ -0,0 +1,24 @@
+{{define "header"}}
+<header>
+    <div class="header">
+        <div class="logo">
+            <!-- <img src="" alt="logo"> -->
+        </div>
+        <div class="org-name">
+            Organization name
+        </div>
+        {{if eq .IsLogin true}}
+        <a href="/logout">Выйти</a>
+        {{else}}
+        <a href="/authorization">Авторизация</a>
+        {{end}}
+    </div>
+    <nav>
+        <div class="item"><a href="#">Ссылка</a></div>
+        <div class="item"><a href="#">Ссылка</a></div>
+        <div class="item"><a href="#">Ссылка</a></div>
+        <div class="item"><a href="#">Ссылка</a></div>
+        <div class="item"><a href="#">Ссылка</a></div>
+    </nav>
+</header>
+{{end}}

+ 78 - 0
html/index.html

@@ -0,0 +1,78 @@
+{{define "index"}}
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link rel="stylesheet" href="/assets/css/message.css">
+    <link rel="stylesheet" href="/assets/css/style.css">
+    {{if eq .IsAdmin true}}
+    <link rel="stylesheet" href="/assets/css/admin.css">
+    {{end}}
+    <title>{{.Title}}</title>
+</head>
+
+<body>
+    {{template "header" .}}
+
+    <main>
+        <div class="body">
+            <div>
+                <div class="catalog">
+                    <div class="item">категория а</div>
+                    <div class="item">категория б</div>
+                    <div class="item">категория в</div>
+                    <div class="item">категория г</div>
+                    <div class="item">категория д</div>
+                    <div class="item">категория е</div>
+                </div>
+                {{if eq .IsAdmin true}}
+                {{template "admin" .}}
+                {{end}}
+            </div>
+            <div>
+                <p>Какая-то информация... <br></p>
+                <p>Какая-то информация... <br></p>
+                <p>Какая-то информация... <br></p>
+                <p>Какая-то информация... <br></p>
+                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Autem, dolorum, numquam tempora praesentium
+                    voluptas voluptatum et enim a repellendus itaque repudiandae dolores inventore rem distinctio nisi
+                    quidem. Minima, amet! Illo.</p>
+                <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Tempore voluptatum repellendus
+                    reprehenderit
+                    quidem officiis accusantium at. Ratione possimus voluptatibus consectetur odit doloremque tempore
+                    ullam
+                    impedit consequuntur nam nesciunt commodi autem unde delectus quidem, id ab vitae ipsam saepe
+                    tenetur
+                    quod. Rerum blanditiis, impedit quaerat ea expedita inventore, nesciunt sint illo ipsa sapiente,
+                    saepe
+                    corrupti minima recusandae labore fuga cumque aspernatur quisquam possimus officiis accusamus ipsam
+                    perferendis? Distinctio ex temporibus rerum, perspiciatis ducimus explicabo saepe. Officia nulla,
+                    reprehenderit illo vitae obcaecati esse nisi numquam distinctio. Numquam magnam iure incidunt
+                    beatae,
+                    nemo repudiandae ratione culpa, quis perspiciatis explicabo quod. Nisi dolore dolores saepe minima
+                    eos,
+                    tempore eius obcaecati quidem, non, dicta ex iusto qui ad eaque natus velit voluptate! Velit
+                    suscipit
+                    officia necessitatibus, molestiae non adipisci mollitia aliquid quisquam doloremque ipsam. Ratione
+                    nisi
+                    atque et. Delectus modi corrupti eum soluta laborum minus, ratione illum doloribus doloremque libero
+                    tenetur harum, asperiores distinctio facere similique. Fugit recusandae beatae eveniet perferendis
+                    enim
+                    error cupiditate aperiam.</p>
+            </div>
+        </div>
+    </main>
+
+    {{template "footer" .}}
+
+    <script src="/assets/js/message.js"></script>
+    <script src="/assets/js/query.js"></script>
+    {{if eq .IsAdmin true}}
+    <script src="/assets/js/admin.js"></script>
+    {{end}}
+</body>
+
+</html>
+{{end}}

+ 150 - 0
main.go

@@ -0,0 +1,150 @@
+package main
+
+import (
+	"database/sql"
+	"fmt"
+
+	"github.com/gin-gonic/contrib/sessions"
+
+	"github.com/gin-gonic/gin"
+
+	_ "github.com/lib/pq"
+)
+
+var router *gin.Engine
+var db *sql.DB
+
+func main() {
+
+	// Подключение к базе данных
+	connect()
+
+	// Создаем роутер по умолчанию
+	router = gin.Default()
+
+	// Загружаем файлы шаблонов HTML страниц
+	router.LoadHTMLFiles(
+		cfg.Template+"index.html",
+		cfg.Template+"footer.html",
+		cfg.Template+"header.html",
+		cfg.Template+"authorization.html",
+		cfg.Template+"admin.html",
+		cfg.Template+"404.html",
+	)
+
+	// Указываем папку статических файлов
+	router.Static("/assets", cfg.Assets)
+
+	// Создаем сессию (необходимо для сохранения авторизации на сайте)
+	word := sessions.NewCookieStore([]byte("my-private-key"))
+	router.Use(sessions.Sessions("session", word))
+
+	// Обработчик запроса, если пользователь будет долбиться по не существующему адресу
+	router.NoRoute(notFound)
+
+	router.GET("/", index)
+	router.GET("/authorization", authorization)
+	router.POST("/login", login)
+	router.GET("/logout", logout)
+
+	router.Run(cfg.ServerHost + ":" + cfg.ServerPort)
+}
+
+func notFound(c *gin.Context) {
+	c.HTML(404, "404", gin.H{})
+}
+
+func index(c *gin.Context) {
+	s := sessions.Default(c)
+
+	admin := false
+	isLogin := false
+
+	role, ok := s.Get("MySecretKey").(string)
+	if ok {
+		if role == "admin" {
+			admin = true
+		}
+		isLogin = true
+	}
+
+	c.HTML(200, "index", gin.H{
+		"Title":   "Мой сайт",
+		"IsAdmin": admin,
+		"IsLogin": isLogin,
+	})
+}
+
+func authorization(c *gin.Context) {
+	c.HTML(200, "authorization", gin.H{})
+}
+
+func login(c *gin.Context) {
+
+	s := sessions.Default(c)
+
+	_, ok := s.Get("MySecretKey").(string)
+	if ok {
+		s.Clear()
+	}
+
+	var u user
+
+	e := c.BindJSON(&u)
+	if e != nil {
+		fmt.Println(e.Error())
+
+		c.JSON(200, gin.H{
+			"Result": false,
+		})
+
+		return
+	}
+
+	row := db.QueryRow(`SELECT "Role", "Name" FROM "User" WHERE "Phone"=$1 AND "Password"=$2`, u.Phone, u.Password)
+
+	e = row.Scan(&u.Role, &u.Name)
+	if e != nil {
+		fmt.Println(e.Error())
+
+		c.JSON(200, gin.H{
+			"Result": false,
+		})
+
+		return
+	}
+
+	s.Set("MySecretKey", u.Role)
+
+	e = s.Save()
+	if e != nil {
+		fmt.Println(e.Error())
+
+		c.JSON(200, gin.H{
+			"Result": false,
+		})
+
+		return
+	}
+
+	c.JSON(200, gin.H{
+		"Result": true,
+		"Name":   u.Name,
+	})
+}
+
+func logout(c *gin.Context) {
+	s := sessions.Default(c)
+
+	role, ok := s.Get("MySecretKey").(string)
+	if ok {
+		s.Delete(role)
+		s.Save()
+	}
+
+	c.HTML(200, "index", gin.H{
+		"Title":   "Мой сайт",
+		"IsAdmin": false,
+		"IsLogin": false,
+	})
+}

+ 12 - 0
setting.cfg

@@ -0,0 +1,12 @@
+{
+    "ServerHost": "192.168.0.150",
+    "ServerPort": "8080",
+    "PgHost": "127.0.0.1",
+    "PgPort": "5432",
+    "PgUser": "postgres",
+    "PgPass": "1234",
+    "PgBase": "test",
+    "Data": "./data/",
+    "Assets": "./assets/",
+    "Template": "./html/"
+}

+ 55 - 0
setting.go

@@ -0,0 +1,55 @@
+package main
+
+import (
+	"encoding/json"
+	"os"
+)
+
+// Setting структура конфигурации сервера
+type Setting struct {
+	ServerHost string
+	ServerPort string
+	PgHost     string
+	PgPort     string
+	PgUser     string
+	PgPass     string
+	PgBase     string
+	Data       string
+	Assets     string
+	Template   string
+}
+
+// Переменная конфигурации
+var cfg Setting
+
+func init() {
+
+	// Открываем файл конфигурации
+	file, e := os.Open("setting.cfg")
+	if e != nil {
+		// Если файл открыть не удалось, останавливаем работу сервера
+		panic("Файл конфигурации не был найден")
+	}
+
+	// Отложенный вызов функции. Файл будет закрыт когда функция init завершит работу
+	defer file.Close()
+
+	// Получить информацию о файле (размер файла, чтобы знать, сколько байт нужно выделить для его чтения)
+	stat, e := file.Stat()
+	if e != nil {
+		panic("Не удалось получить информацю о файле конфигурации")
+	}
+
+	// Создаем переменную массив байтов с размером файла
+	bytesForFileRead := make([]byte, stat.Size())
+
+	_, e = file.Read(bytesForFileRead)
+	if e != nil {
+		panic("Не удалось прочитать файл конфигурации")
+	}
+
+	e = json.Unmarshal(bytesForFileRead, &cfg)
+	if e != nil {
+		panic("Не удалось считать данные файла конфигурации")
+	}
+}