aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.snekrc19
-rw-r--r--app.py110
-rw-r--r--error_handlers/http_404.py8
-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
-rw-r--r--requirements.txt2
-rw-r--r--routes/healthcheck.py8
-rw-r--r--routes/index.py8
-rw-r--r--routes/invite.py9
-rw-r--r--templates/.gitkeep0
17 files changed, 155 insertions, 144 deletions
diff --git a/.snekrc b/.snekrc
index 3f26eea5..1d18fb0c 100644
--- a/.snekrc
+++ b/.snekrc
@@ -1,6 +1,21 @@
[all]
-linters = flake8, safety, dodgy
+linters = flake8, safety, dodgy, yapf, isort
[flake8]
max-line-length=120
-application_import_names=pysite \ No newline at end of file
+application_import_names=pysite
+ignore=I100
+
+[isort]
+line_length=120
+indent=' '
+multi_line_output=0
+length_sort=1
+use_parentheses=true
+sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
+import_heading_stdlib=Stdlib
+import_heading_thirdparty=External Libraries
+import_heading_firstparty=Site Internals
+force_sort_within_sections=true
+
+[style] # yapf \ No newline at end of file
diff --git a/app.py b/app.py
index f3bb9a60..5efc1ee7 100644
--- a/app.py
+++ b/app.py
@@ -1,10 +1,108 @@
-# coding=utf-8
+#!/usr/bin/env python3.6
-from pysite.route_manager import RouteManager
+# Stdlib
+from importlib.util import module_from_spec, spec_from_file_location
+import mimetypes
+import os
+# External Libraries
+from japronto import Application
-manager = RouteManager()
-app = manager.app
+app = Application()
-if __name__ == '__main__':
- manager.run()
+
+def static_file(path: str): # type: (str) -> (req: {Response}) -> Coroutine
+ async def inner(req): # type: ({Response}) -> Coroutine
+ with open(path) as file:
+ return req.Response(
+ text=file.read(), mime_type=mimetypes.guess_type(path)[0])
+
+ return inner
+
+
+def find_static_files(dir_: str) -> list: # type: (str) -> List[str]
+ data = []
+ for path, _, files in os.walk(dir_):
+ if not files:
+ continue
+
+ for file in files:
+ if not file.split(".")[-1] not in ("html", "css", "js"):
+ continue
+
+ pathname = f"{path[len(dir_):]}/{file.strip()}"
+ data.append(pathname.split(".")[0], static_file(pathname))
+
+ return data
+
+
+def find_routes(
+ dir_: str) -> list: # type: (str) -> List[Tuple[str, str, callable]]
+ data = []
+ for path, _, files in os.walk(dir_):
+ if not files:
+ continue
+
+ for file in files:
+ if not file.endswith(".py"):
+ continue
+ pathname = f"{path}/{file.strip()}"
+ spec = spec_from_file_location(file[:-3], pathname)
+ module = module_from_spec(spec)
+ spec.loader.exec_module(module)
+
+ if not hasattr(module, "Index"):
+ raise Exception("No `Index` class!")
+
+ res = module.Index()
+ del module, spec
+
+ route_paths = res.path
+ for path_ in route_paths:
+ # TODO: Add all request types here
+ for method in ("GET", "POST", "DELETE", "PATCH"):
+ if hasattr(res, method.lower()):
+ data.append((path_, method, getattr(
+ res, method.lower())))
+
+ return data
+
+
+def find_errors(dir_: str) -> list: # type: (str) -> List[str]
+ data = []
+ for path, _, files in os.walk(dir_):
+ if not files:
+ continue
+
+ for file in files:
+ if not file.endswith(".py"):
+ continue
+ pathname = f"{path}/{file.strip()}"
+ spec = spec_from_file_location(file[:-3], pathname)
+ module = module_from_spec(spec)
+ spec.loader.exec_module(module)
+
+ if not hasattr(module, "Index"):
+ raise Exception("No `Index` class!")
+
+ res = module.Index()
+ del module, spec
+ data.append((res.error_code, res.err))
+
+ return data
+
+
+routes = find_routes("routes")
+static = find_static_files("static")
+errors = find_errors("error_handlers")
+
+for route in routes:
+ app.router.add_route(route.path, route.run, method=route.method)
+
+for path, method, handle in static:
+ app.router.add_route(path, handle, method=method)
+
+for errcode, handler in errors:
+ app.add_error_handler(errcode, handler)
+
+app.run(debug=True, port=80)
diff --git a/error_handlers/http_404.py b/error_handlers/http_404.py
new file mode 100644
index 00000000..712bf748
--- /dev/null
+++ b/error_handlers/http_404.py
@@ -0,0 +1,8 @@
+# coding=utf-8
+
+
+class Index:
+ error_code = 404
+
+ def err(self, req):
+ return req.Response(text="Page not found!", code=404)
diff --git a/pysite/__init__.py b/pysite/__init__.py
deleted file mode 100644
index ba286add..00000000
--- a/pysite/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# coding=utf-8
-
-__author__ = "Gareth Coles"
diff --git a/pysite/base_route.py b/pysite/base_route.py
deleted file mode 100644
index 76338280..00000000
--- a/pysite/base_route.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# 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
deleted file mode 100644
index 501076b7..00000000
--- a/pysite/route_manager.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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
deleted file mode 100644
index ba286add..00000000
--- a/pysite/views/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# coding=utf-8
-
-__author__ = "Gareth Coles"
diff --git a/pysite/views/error_handlers/__init__.py b/pysite/views/error_handlers/__init__.py
deleted file mode 100644
index ba286add..00000000
--- a/pysite/views/error_handlers/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# coding=utf-8
-
-__author__ = "Gareth Coles"
diff --git a/pysite/views/error_handlers/http_404.py b/pysite/views/error_handlers/http_404.py
deleted file mode 100644
index eea1e630..00000000
--- a/pysite/views/error_handlers/http_404.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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
deleted file mode 100644
index 660c8a96..00000000
--- a/pysite/views/healthcheck.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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
deleted file mode 100644
index 2e779003..00000000
--- a/pysite/views/index.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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
deleted file mode 100644
index d035fc99..00000000
--- a/pysite/views/invite.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# 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/")
diff --git a/requirements.txt b/requirements.txt
index 69ca547f..8f1f53e4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1 @@
-flask==0.12.2 \ No newline at end of file
+japronto
diff --git a/routes/healthcheck.py b/routes/healthcheck.py
new file mode 100644
index 00000000..11a5fc24
--- /dev/null
+++ b/routes/healthcheck.py
@@ -0,0 +1,8 @@
+# coding=utf-8
+
+
+class Index:
+ path = ["/healthcheck"]
+
+ def get(self, req):
+ return req.Response(json={"status": "ok"})
diff --git a/routes/index.py b/routes/index.py
new file mode 100644
index 00000000..76671ed1
--- /dev/null
+++ b/routes/index.py
@@ -0,0 +1,8 @@
+# coding=utf-8
+
+
+class Index:
+ path = ["/", "/index"]
+
+ def get(self, req):
+ return req.Response("Coming soon:tm:")
diff --git a/routes/invite.py b/routes/invite.py
new file mode 100644
index 00000000..29553345
--- /dev/null
+++ b/routes/invite.py
@@ -0,0 +1,9 @@
+# coding=utf-8
+
+
+class Index:
+ path = ["/invite"]
+
+ def get(self, res):
+ return res.Response(
+ status_code=301, text="http://invite.pythondiscord.com/")
diff --git a/templates/.gitkeep b/templates/.gitkeep
deleted file mode 100644
index e69de29b..00000000
--- a/templates/.gitkeep
+++ /dev/null