diff options
author | xengineering <mail2xengineering@protonmail.com> | 2021-02-11 13:01:43 +0100 |
---|---|---|
committer | xengineering <mail2xengineering@protonmail.com> | 2021-02-11 13:01:43 +0100 |
commit | bc6b03ab29703dfff857b63727657ca3127eb381 (patch) | |
tree | 009fc7df794754917ddb3fecfde8b2f739e7b1df | |
parent | 7293dae63a07ec23e779fef20fbe81104ebc7d3f (diff) | |
download | web-template-bc6b03ab29703dfff857b63727657ca3127eb381.tar web-template-bc6b03ab29703dfff857b63727657ca3127eb381.tar.zst web-template-bc6b03ab29703dfff857b63727657ca3127eb381.zip |
Refactoring: Reimplement Webroot Deployment
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 21 | ||||
-rw-r--r-- | config.json | 11 | ||||
-rw-r--r-- | example_settings.json | 13 | ||||
-rwxr-xr-x | flask/main.py.jinja2 (renamed from flask/main.py) | 2 | ||||
-rw-r--r-- | lib/css/debug.html | 31 | ||||
-rw-r--r-- | lib/css/xengineering.css | 111 | ||||
-rw-r--r-- | lib/html/example.html | 31 | ||||
-rw-r--r-- | lib/img/xengineering.ico | bin | 0 -> 6715 bytes | |||
-rw-r--r-- | lib/js/example.js | 14 | ||||
-rw-r--r--[-rwxr-xr-x] | manage.py | 103 | ||||
-rw-r--r-- | systemd/webtemplate.service.jinja2 | 14 | ||||
l---------[-rw-r--r--] | webroot/css/xengineering.css | 112 | ||||
l---------[-rw-r--r--] | webroot/favicon.ico | bin | 6715 -> 27 bytes | |||
l---------[-rw-r--r--] | webroot/index.html | 32 | ||||
l---------[-rw-r--r--] | webroot/js/example.js | 15 |
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 Binary files differnew file mode 100644 index 0000000..969b451 --- /dev/null +++ b/lib/img/xengineering.ico 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 Binary files differindex 969b451..18c5c39 100644..120000 --- a/webroot/favicon.ico +++ b/webroot/favicon.ico 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 |