summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxengineering <mail2xengineering@protonmail.com>2021-02-11 13:01:43 +0100
committerxengineering <mail2xengineering@protonmail.com>2021-02-11 13:01:43 +0100
commitbc6b03ab29703dfff857b63727657ca3127eb381 (patch)
tree009fc7df794754917ddb3fecfde8b2f739e7b1df
parent7293dae63a07ec23e779fef20fbe81104ebc7d3f (diff)
downloadweb-template-bc6b03ab29703dfff857b63727657ca3127eb381.tar
web-template-bc6b03ab29703dfff857b63727657ca3127eb381.tar.zst
web-template-bc6b03ab29703dfff857b63727657ca3127eb381.zip
Refactoring: Reimplement Webroot Deployment
-rw-r--r--.gitignore2
-rw-r--r--Makefile21
-rw-r--r--config.json11
-rw-r--r--example_settings.json13
-rwxr-xr-xflask/main.py.jinja2 (renamed from flask/main.py)2
-rw-r--r--lib/css/debug.html31
-rw-r--r--lib/css/xengineering.css111
-rw-r--r--lib/html/example.html31
-rw-r--r--lib/img/xengineering.icobin0 -> 6715 bytes
-rw-r--r--lib/js/example.js14
-rw-r--r--[-rwxr-xr-x]manage.py103
-rw-r--r--systemd/webtemplate.service.jinja214
l---------[-rw-r--r--]webroot/css/xengineering.css112
l---------[-rw-r--r--]webroot/favicon.icobin6715 -> 27 bytes
l---------[-rw-r--r--]webroot/index.html32
l---------[-rw-r--r--]webroot/js/example.js15
16 files changed, 323 insertions, 189 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..08c5ba6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+settings.json
+archive
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..9fe5771
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,21 @@
+# vim: tabstop=4 shiftwidth=4 noexpandtab
+
+
+all:
+ mkdir -p systemd/build
+ python3 manage.py build_systemd_files
+ mkdir -p flask/build
+ python3 manage.py build_flask_files
+
+clean:
+ rm -rf systemd/build
+ rm -rf flask/build
+
+install: all
+ python3 manage.py install_webroot
+ #find systemd/build -type f -exec sudo install -Dm 644 "{}" "/etc/systemd/system" \;
+
+uninstall:
+ python3 manage.py uninstall_webroot
+ #python3 manage.py uninstall_systemd_files
+
diff --git a/config.json b/config.json
deleted file mode 100644
index 1ad14b1..0000000
--- a/config.json
+++ /dev/null
@@ -1,11 +0,0 @@
-
-{
- "deployments":[
- {
- "host":"example.com",
- "username":"exampleuser",
- "webroot":"/srv/http/example.com/public/"
- }
- ]
-}
-
diff --git a/example_settings.json b/example_settings.json
new file mode 100644
index 0000000..c08c89c
--- /dev/null
+++ b/example_settings.json
@@ -0,0 +1,13 @@
+
+{
+ "project_name":"webtemplate",
+ "project_description":"A Template Web Application",
+ "user":"http",
+ "group":"http",
+ "webroot_installation_path":"/srv/http/example.com/public",
+ "web_framework":"flask",
+ "web_framework_installation_path":"/opt",
+ "framework_port":"8080",
+ "framework_bind":"127.0.0.1"
+}
+
diff --git a/flask/main.py b/flask/main.py.jinja2
index be270b1..1e1a653 100755
--- a/flask/main.py
+++ b/flask/main.py.jinja2
@@ -36,7 +36,7 @@ def api():
if __name__ == '__main__':
- waitress.serve(app, listen='*:8080') # production server / bind to port
+ waitress.serve(app, listen='{{ framework_bind }}:{{ framework_port }}') # production server / bind to port
#serve(app, unix_socket='/run/web-template/unix.sock') # production server / unix domain socket
#app.run() # debug server - NOT FOR PRODUCTION!
diff --git a/lib/css/debug.html b/lib/css/debug.html
new file mode 100644
index 0000000..8d4b997
--- /dev/null
+++ b/lib/css/debug.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<html>
+
+ <head>
+
+ <title>CSS Debugger</title>
+
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="xengineering.css" type="text/css">
+
+ </head>
+
+ <body>
+
+ <div class="xmenu">
+ <a href="https://example.com">HOME</a>
+ </div>
+
+ <div class="xcontent">
+ <h1>Web Template</h1>
+ <button onclick="example_post()">Call JS Function</button>
+ </div>
+
+ <script src="js/example.js"></script>
+
+ </body>
+
+</html>
+
diff --git a/lib/css/xengineering.css b/lib/css/xengineering.css
new file mode 100644
index 0000000..1e14b72
--- /dev/null
+++ b/lib/css/xengineering.css
@@ -0,0 +1,111 @@
+
+
+/*
+ web-template - A Template Project for dynamic Web Applications.
+
+ Copyright (C) 2020 xengineering
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+
+/*
+ General Stuff
+*/
+
+* {
+ box-sizing: border-box; /* Include padding and border in the element's total width and height */
+}
+
+body {
+ margin: 0; /* avoid ugly white margin */
+ font-family: Arial, Helvetica, sans-serif; /* select a nice font */
+}
+
+.xmenu {
+ background-color: black;
+}
+
+.xcontent {
+ background-color: white;
+}
+
+.xmenu a {
+ color: lightgray;
+ text-decoration: none; /* disable ugly underlined links */
+}
+
+/* How should the link behave if the mouse is over this item? */
+.xmenu a:hover {
+ background-color: lightgray;
+ color: black;
+}
+
+
+
+/*
+ Default Geometry / Geometry for Phones ('Mobile First Development')
+*/
+
+.xcontent {
+ padding-left: 20px;
+ padding-right: 20px;
+ text-align: justify;
+}
+
+.xmenu a {
+ display: block;
+ padding: 16px;
+ text-align: center;
+}
+
+
+
+/*
+ Geometry for Tablets
+*/
+
+@media only screen and (min-width: 600px) {
+ /* empty --> same rules as for phones */
+}
+
+
+
+/*
+ Geometry for Desktops
+*/
+
+@media only screen and (min-width: 768px) {
+
+ .xmenu {
+ height: 100%;
+ width: 200px;
+ position: fixed; /* position fixed in top left corner (with offset) */
+ top: 0px; /* disable the offset from top left corner */
+ }
+
+ .xmenu a {
+ text-align: left;
+ }
+
+ .xcontent {
+ margin-left: 200px; /* transparent margin on the left for .xmenu */
+ }
+
+ .xcontent *{ /* everything inside the content container */
+ max-width: 960px; /* maximum width on desktops should be 960 px */
+ margin-left: auto; /* center it with margin */
+ margin-right: auto; /* center it with margin */
+ }
+}
diff --git a/lib/html/example.html b/lib/html/example.html
new file mode 100644
index 0000000..a406de7
--- /dev/null
+++ b/lib/html/example.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<html>
+
+ <head>
+
+ <title>Web Template</title>
+
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <link rel="stylesheet" href="css/xengineering.css" type="text/css">
+
+ </head>
+
+ <body>
+
+ <div class="xmenu">
+ <a href="https://example.com">HOME</a>
+ </div>
+
+ <div class="xcontent">
+ <h1>Web Template</h1>
+ <button onclick="example_post()">Call JS Function</button>
+ </div>
+
+ <script src="js/example.js"></script>
+
+ </body>
+
+</html>
+
diff --git a/lib/img/xengineering.ico b/lib/img/xengineering.ico
new file mode 100644
index 0000000..969b451
--- /dev/null
+++ b/lib/img/xengineering.ico
Binary files differ
diff --git a/lib/js/example.js b/lib/js/example.js
new file mode 100644
index 0000000..59cf1ee
--- /dev/null
+++ b/lib/js/example.js
@@ -0,0 +1,14 @@
+
+function example_post() {
+
+ var data = {
+ "key":"value",
+ }
+ var json = JSON.stringify(data);
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", "api", true);
+ xhr.send(json);
+
+}
+
diff --git a/manage.py b/manage.py
index 50249e5..6df9902 100755..100644
--- a/manage.py
+++ b/manage.py
@@ -1,45 +1,106 @@
#!/usr/bin/python3
+# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
import sys
+import os
import subprocess
import json
+import jinja2
+
+
+SETTINGS_PATH = "settings.json"
+SYSTEMD_TEMPLATE = "systemd/webtemplate.service.jinja2"
+FLASK_TEMPLATE = "flask/main.py.jinja2"
+REPOSITORY_WEBROOT = "webroot"
+
+
+def read_settings():
+ """Read the SETTINGS_PATH File and return a Dictionary with its Content"""
+
+ with open(SETTINGS_PATH, "r") as settings:
+ settings = settings.read()
+
+ settings = json.loads(settings)
+ return settings
+
+
+def build_systemd_files(settings):
+ """Generate all Systemd Unit Files with Settings from SETTINGS_PATH"""
+
+ with open(SYSTEMD_TEMPLATE, "r") as template:
+ template = template.read()
+
+ template = jinja2.Template(template)
+ systemd_file = template.render(settings)
+
+ file_path = "systemd/build/{}.service".format(settings["project_name"])
+
+ with open(file_path, "w") as _file:
+ _file.write(systemd_file)
+
+
+def build_flask_files(settings):
+ """Generate all Python Flask Files with Settings from SETTINGS_PATH"""
+
+ if settings["web_framework"] == "flask":
+ with open(FLASK_TEMPLATE, "r") as template:
+ template = template.read()
+
+ template = jinja2.Template(template)
+ flask_file = template.render(settings)
+
+ file_path = "flask/build/{}".format(settings["project_name"])
+
+ with open(file_path, "w") as _file:
+ _file.write(flask_file)
+ else:
+ print("Flask not enabled in settings.json - skipping file generation for Flask")
+
+
+def install_webroot(settings):
+ """Install every File from the Repositories Webroot to the Systems Webroot"""
+
+ for directory, subdirs, files in os.walk(REPOSITORY_WEBROOT, topdown=False):
+ for _file in files:
+ path_to_file = os.path.join(directory, _file)
+ relative_path = os.path.relpath(path_to_file, REPOSITORY_WEBROOT)
+ target_path = os.path.join(settings["webroot_installation_path"], relative_path)
+ subprocess.run("install -Dm 644 {} {}".format(path_to_file, target_path), shell=True)
-CONFIG_PATH = "./config.json"
+def uninstall_webroot(settings):
+ """Uninstalls every File from the Systems Webroot"""
+
+ path_to_delete = os.path.join(settings["webroot_installation_path"], "*")
+ subprocess.run("rm -rf {}".format(path_to_delete), shell=True)
def main():
+ """The main Function"""
+
+ settings = read_settings() # get settings from SETTINGS_PATH
+ # just one argument is allowed:
if len(sys.argv) != 2:
print("Provide exactly one parameter")
sys.exit(1)
- cfg = read_config()
-
+ # execute given command
command = sys.argv[1]
-
- if command == "deploy":
- for deployment in cfg["deployments"]:
- subprocess.call(
- "rsync -av ./webroot/ {0}@{1}:{2}".format(
- deployment["username"],
- deployment["host"],
- deployment["webroot"]
- ),
- shell=True
- )
+ if command == "build_systemd_files":
+ build_systemd_files(settings)
+ elif command == "build_flask_files":
+ build_flask_files(settings)
+ elif command == "install_webroot":
+ install_webroot(settings)
+ elif command == "uninstall_webroot":
+ uninstall_webroot(settings)
else:
print("Unknown command")
+ exit(1)
-def read_config():
- with open(CONFIG_PATH, "r") as f:
- content = f.read()
- return json.loads(content)
if __name__ == "__main__":
main()
-
-# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
-
diff --git a/systemd/webtemplate.service.jinja2 b/systemd/webtemplate.service.jinja2
new file mode 100644
index 0000000..6861b57
--- /dev/null
+++ b/systemd/webtemplate.service.jinja2
@@ -0,0 +1,14 @@
+
+[Unit]
+Description={{ project_description }}
+After=network.target
+
+[Service]
+User={{ user }}
+Group={{ group }}
+WorkingDirectory={{ web_framework_installation_path }}/{{ project_name }}/
+ExecStart={{ web_framework_installation_path }}/{{ project_name }}/{{ project_name }}
+
+[Install]
+WantedBy=multi-user.target
+
diff --git a/webroot/css/xengineering.css b/webroot/css/xengineering.css
index 1e14b72..73f09ef 100644..120000
--- a/webroot/css/xengineering.css
+++ b/webroot/css/xengineering.css
@@ -1,111 +1 @@
-
-
-/*
- web-template - A Template Project for dynamic Web Applications.
-
- Copyright (C) 2020 xengineering
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-*/
-
-
-/*
- General Stuff
-*/
-
-* {
- box-sizing: border-box; /* Include padding and border in the element's total width and height */
-}
-
-body {
- margin: 0; /* avoid ugly white margin */
- font-family: Arial, Helvetica, sans-serif; /* select a nice font */
-}
-
-.xmenu {
- background-color: black;
-}
-
-.xcontent {
- background-color: white;
-}
-
-.xmenu a {
- color: lightgray;
- text-decoration: none; /* disable ugly underlined links */
-}
-
-/* How should the link behave if the mouse is over this item? */
-.xmenu a:hover {
- background-color: lightgray;
- color: black;
-}
-
-
-
-/*
- Default Geometry / Geometry for Phones ('Mobile First Development')
-*/
-
-.xcontent {
- padding-left: 20px;
- padding-right: 20px;
- text-align: justify;
-}
-
-.xmenu a {
- display: block;
- padding: 16px;
- text-align: center;
-}
-
-
-
-/*
- Geometry for Tablets
-*/
-
-@media only screen and (min-width: 600px) {
- /* empty --> same rules as for phones */
-}
-
-
-
-/*
- Geometry for Desktops
-*/
-
-@media only screen and (min-width: 768px) {
-
- .xmenu {
- height: 100%;
- width: 200px;
- position: fixed; /* position fixed in top left corner (with offset) */
- top: 0px; /* disable the offset from top left corner */
- }
-
- .xmenu a {
- text-align: left;
- }
-
- .xcontent {
- margin-left: 200px; /* transparent margin on the left for .xmenu */
- }
-
- .xcontent *{ /* everything inside the content container */
- max-width: 960px; /* maximum width on desktops should be 960 px */
- margin-left: auto; /* center it with margin */
- margin-right: auto; /* center it with margin */
- }
-}
+../../lib/css/xengineering.css \ No newline at end of file
diff --git a/webroot/favicon.ico b/webroot/favicon.ico
index 969b451..18c5c39 100644..120000
--- a/webroot/favicon.ico
+++ b/webroot/favicon.ico
Binary files differ
diff --git a/webroot/index.html b/webroot/index.html
index a406de7..f040f3e 100644..120000
--- a/webroot/index.html
+++ b/webroot/index.html
@@ -1,31 +1 @@
-<!DOCTYPE html>
-
-<html>
-
- <head>
-
- <title>Web Template</title>
-
- <meta charset="utf-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <link rel="stylesheet" href="css/xengineering.css" type="text/css">
-
- </head>
-
- <body>
-
- <div class="xmenu">
- <a href="https://example.com">HOME</a>
- </div>
-
- <div class="xcontent">
- <h1>Web Template</h1>
- <button onclick="example_post()">Call JS Function</button>
- </div>
-
- <script src="js/example.js"></script>
-
- </body>
-
-</html>
-
+../lib/html/example.html \ No newline at end of file
diff --git a/webroot/js/example.js b/webroot/js/example.js
index 59cf1ee..3faf334 100644..120000
--- a/webroot/js/example.js
+++ b/webroot/js/example.js
@@ -1,14 +1 @@
-
-function example_post() {
-
- var data = {
- "key":"value",
- }
- var json = JSON.stringify(data);
-
- var xhr = new XMLHttpRequest();
- xhr.open("POST", "api", true);
- xhr.send(json);
-
-}
-
+../../lib/js/example.js \ No newline at end of file