aboutsummaryrefslogtreecommitdiffstats
path: root/pysite
diff options
context:
space:
mode:
Diffstat (limited to 'pysite')
-rw-r--r--pysite/__init__.py3
-rw-r--r--pysite/base_route.py29
-rw-r--r--pysite/route_manager.py41
-rw-r--r--pysite/views/__init__.py3
-rw-r--r--pysite/views/error_handlers/__init__.py3
-rw-r--r--pysite/views/error_handlers/http_404.py14
-rw-r--r--pysite/views/healthcheck.py15
-rw-r--r--pysite/views/index.py12
-rw-r--r--pysite/views/invite.py15
9 files changed, 135 insertions, 0 deletions
diff --git a/pysite/__init__.py b/pysite/__init__.py
new file mode 100644
index 00000000..ba286add
--- /dev/null
+++ b/pysite/__init__.py
@@ -0,0 +1,3 @@
+# coding=utf-8
+
+__author__ = "Gareth Coles"
diff --git a/pysite/base_route.py b/pysite/base_route.py
new file mode 100644
index 00000000..76338280
--- /dev/null
+++ b/pysite/base_route.py
@@ -0,0 +1,29 @@
+# coding=utf-8
+from flask import Flask
+from flask.views import MethodView
+
+__author__ = "Gareth Coles"
+
+
+class BaseView(MethodView):
+ path = None #: str
+ name = None #: str
+
+ @classmethod
+ def setup(cls: "BaseView", app: Flask):
+ if not cls.path or not cls.name:
+ raise RuntimeError("Route views must have both `path` and `name` defined")
+
+ app.add_url_rule(cls.path, view_func=cls.as_view(cls.name))
+
+
+class ErrorView(MethodView):
+ name = None #: str
+ error_code = None #: int
+
+ @classmethod
+ def setup(cls: "ErrorView", app: Flask):
+ if not cls.name or not cls.error_code:
+ raise RuntimeError("Error views must have both `name` and `error_code` defined")
+
+ app._register_error_handler(None, 404, cls.as_view(cls.name))
diff --git a/pysite/route_manager.py b/pysite/route_manager.py
new file mode 100644
index 00000000..501076b7
--- /dev/null
+++ b/pysite/route_manager.py
@@ -0,0 +1,41 @@
+# coding=utf-8
+import importlib
+import inspect
+import os
+
+from flask import Flask
+
+from pysite.base_route import BaseView, ErrorView
+
+__author__ = "Gareth Coles"
+
+
+class RouteManager:
+ def __init__(self):
+ self.app = Flask(__name__)
+ self.app.secret_key = os.environ.get("WEBPAGE_SECRET_KEY")
+
+ self.load_views()
+
+ def run(self):
+ self.app.run(port=int(os.environ.get("WEBPAGE_PORT")), debug=False)
+
+ def load_views(self, location="pysite/views"):
+ for filename in os.listdir(location):
+ if os.path.isdir(f"{location}/{filename}"):
+ # Recurse if it's a directory; load ALL the views!
+ self.load_views(location=f"{location}/{filename}")
+ continue
+
+ if filename.endswith(".py") and not filename.startswith("__init__"):
+ module = importlib.import_module(f"{location}/{filename}".replace("/", ".")[:-3])
+
+ for cls_name, cls in inspect.getmembers(module):
+ if (
+ inspect.isclass(cls) and
+ cls is not BaseView and
+ cls is not ErrorView and
+ (BaseView in cls.__mro__ or ErrorView in cls.__mro__)
+ ):
+ cls.setup(self.app)
+ print(f"View loaded: {cls.name: <25} ({module.__name__}.{cls_name})")
diff --git a/pysite/views/__init__.py b/pysite/views/__init__.py
new file mode 100644
index 00000000..ba286add
--- /dev/null
+++ b/pysite/views/__init__.py
@@ -0,0 +1,3 @@
+# coding=utf-8
+
+__author__ = "Gareth Coles"
diff --git a/pysite/views/error_handlers/__init__.py b/pysite/views/error_handlers/__init__.py
new file mode 100644
index 00000000..ba286add
--- /dev/null
+++ b/pysite/views/error_handlers/__init__.py
@@ -0,0 +1,3 @@
+# coding=utf-8
+
+__author__ = "Gareth Coles"
diff --git a/pysite/views/error_handlers/http_404.py b/pysite/views/error_handlers/http_404.py
new file mode 100644
index 00000000..eea1e630
--- /dev/null
+++ b/pysite/views/error_handlers/http_404.py
@@ -0,0 +1,14 @@
+# coding=utf-8
+from werkzeug.exceptions import NotFound
+
+from pysite.base_route import ErrorView
+
+__author__ = "Gareth Coles"
+
+
+class Error404View(ErrorView):
+ name = "error_404"
+ error_code = 404
+
+ def get(self, error: NotFound):
+ return "replace me with a template, 404 not found", 404
diff --git a/pysite/views/healthcheck.py b/pysite/views/healthcheck.py
new file mode 100644
index 00000000..660c8a96
--- /dev/null
+++ b/pysite/views/healthcheck.py
@@ -0,0 +1,15 @@
+# coding=utf-8
+from flask import jsonify
+
+from pysite.base_route import BaseView
+
+
+__author__ = "Gareth Coles"
+
+
+class IndexView(BaseView):
+ path = "/healthcheck"
+ name = "healthcheck"
+
+ def get(self):
+ return jsonify({"status": "ok"})
diff --git a/pysite/views/index.py b/pysite/views/index.py
new file mode 100644
index 00000000..2e779003
--- /dev/null
+++ b/pysite/views/index.py
@@ -0,0 +1,12 @@
+# coding=utf-8
+from pysite.base_route import BaseView
+
+__author__ = "Gareth Coles"
+
+
+class IndexView(BaseView):
+ path = "/"
+ name = "index"
+
+ def get(self):
+ return "Coming soon:tm:"
diff --git a/pysite/views/invite.py b/pysite/views/invite.py
new file mode 100644
index 00000000..d035fc99
--- /dev/null
+++ b/pysite/views/invite.py
@@ -0,0 +1,15 @@
+# coding=utf-8
+from flask import redirect
+
+from pysite.base_route import BaseView
+
+
+__author__ = "Gareth Coles"
+
+
+class InviteView(BaseView):
+ path = "/invite"
+ name = "invite"
+
+ def get(self):
+ return redirect("http://invite.pythondiscord.com/")