aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2021-10-10 22:19:26 +0300
committerGravatar Hassan Abouelela <[email protected]>2021-10-10 23:06:46 +0300
commita7e9bdd9dbf086094dd138feb9464b7e7fe8b08b (patch)
treedddc532795211cae019b686d25edca7285828cc2
parentMerge pull request #609 from python-discord/static-previews (diff)
Adds Redirects To Static Builds
Dynamically adds static HTML redirects for static builds. Signed-off-by: Hassan Abouelela <[email protected]>
-rw-r--r--pydis_site/apps/redirect/redirects.yaml2
-rw-r--r--pydis_site/apps/redirect/urls.py114
-rw-r--r--pydis_site/urls.py16
3 files changed, 112 insertions, 20 deletions
diff --git a/pydis_site/apps/redirect/redirects.yaml b/pydis_site/apps/redirect/redirects.yaml
index def4154b..9bcf3afd 100644
--- a/pydis_site/apps/redirect/redirects.yaml
+++ b/pydis_site/apps/redirect/redirects.yaml
@@ -182,7 +182,7 @@ events_game_jams_twenty_twenty_rules_redirect:
redirect_arguments: ["game-jams/2020/rules"]
events_game_jams_twenty_twenty_technical_requirements_redirect:
- original_path: pages/events/game-jam-2020/technical-requirements
+ original_path: pages/events/game-jam-2020/technical-requirements/
redirect_route: "events:page"
redirect_arguments: ["game-jams/2020/technical-requirements"]
diff --git a/pydis_site/apps/redirect/urls.py b/pydis_site/apps/redirect/urls.py
index 6187af17..f7ddf45b 100644
--- a/pydis_site/apps/redirect/urls.py
+++ b/pydis_site/apps/redirect/urls.py
@@ -1,19 +1,105 @@
+import dataclasses
+import re
+
import yaml
-from django.conf import settings
-from django.urls import path
+from django import conf
+from django.urls import URLPattern, path
+from django_distill import distill_path
+from pydis_site import settings
+from pydis_site.apps.content import urls as pages_urls
from pydis_site.apps.redirect.views import CustomRedirectView
+from pydis_site.apps.resources import urls as resources_urls
app_name = "redirect"
-urlpatterns = [
- path(
- data["original_path"],
- CustomRedirectView.as_view(
- pattern_name=data["redirect_route"],
- static_args=tuple(data.get("redirect_arguments", ())),
- prefix_redirect=data.get("prefix_redirect", False)
- ),
- name=name
- )
- for name, data in yaml.safe_load(settings.REDIRECTIONS_PATH.read_text()).items()
-]
+
+
+__PARAMETER_REGEX = re.compile(r"<\w+:\w+>")
+REDIRECT_TEMPLATE = "<meta http-equiv=\"refresh\" content=\"0; URL={url}\"/>"
+
+
[email protected](frozen=True)
+class Redirect:
+ """Metadata about a redirect route."""
+
+ original_path: str
+ redirect_route: str
+ redirect_arguments: tuple[str] = tuple()
+
+ prefix_redirect: bool = False
+
+
+def map_redirect(name: str, data: Redirect) -> list[URLPattern]:
+ """Return a pattern using the Redirects app, or a static HTML redirect for static builds."""
+ if not settings.env("STATIC_BUILD"):
+ # Normal dynamic redirect
+ return [path(
+ data.original_path,
+ CustomRedirectView.as_view(
+ pattern_name=data.redirect_route,
+ static_args=tuple(data.redirect_arguments),
+ prefix_redirect=data.prefix_redirect
+ ),
+ name=name
+ )]
+
+ # Create static HTML redirects for static builds
+ new_app_name = data.redirect_route.split(":")[0]
+
+ if __PARAMETER_REGEX.search(data.original_path):
+ # Redirects for paths which accept parameters
+ # We generate an HTML redirect file for all possible entries
+ paths = []
+
+ class RedirectFunc:
+ def __init__(self, new_url: str, _name: str):
+ self.result = REDIRECT_TEMPLATE.format(url=new_url)
+ self.__qualname__ = _name
+
+ def __call__(self, *args, **kwargs):
+ return self.result
+
+ if new_app_name == resources_urls.app_name:
+ items = resources_urls.get_all_resources()
+ elif new_app_name == pages_urls.app_name:
+ items = pages_urls.get_all_pages()
+ else:
+ raise ValueError(f"Unknown app in redirect: {new_app_name}")
+
+ for item in items:
+ entry = list(item.values())[0]
+
+ # Replace dynamic redirect with concrete path
+ concrete_path = __PARAMETER_REGEX.sub(entry, data.original_path)
+ new_redirect = f"/{new_app_name}/{entry}"
+ pattern_name = f"{name}_{entry}"
+
+ paths.append(distill_path(
+ concrete_path,
+ RedirectFunc(new_redirect, pattern_name),
+ name=pattern_name
+ ))
+
+ return paths
+
+ else:
+ redirect_path_name = "pages" if new_app_name == "content" else new_app_name
+ if len(data.redirect_arguments) > 0:
+ redirect_arg = data.redirect_arguments[0]
+ else:
+ redirect_arg = "resources/"
+ new_redirect = f"/{redirect_path_name}/{redirect_arg}"
+
+ if new_redirect == "/resources/resources/":
+ new_redirect = "/resources/"
+
+ return [distill_path(
+ data.original_path,
+ lambda *args: REDIRECT_TEMPLATE.format(url=new_redirect),
+ name=name,
+ )]
+
+
+urlpatterns = []
+for _name, _data in yaml.safe_load(conf.settings.REDIRECTIONS_PATH.read_text()).items():
+ urlpatterns.extend(map_redirect(_name, Redirect(**_data)))
diff --git a/pydis_site/urls.py b/pydis_site/urls.py
index 51ef4214..6cd31f26 100644
--- a/pydis_site/urls.py
+++ b/pydis_site/urls.py
@@ -11,19 +11,25 @@ NON_STATIC_PATTERNS = [
# Internal API ingress (cluster local)
path('pydis-api/', include('pydis_site.apps.api.urls', namespace='internal_api')),
- # This must be mounted before the `content` app to prevent Django
- # from wildcard matching all requests to `pages/...`.
- path('', include('pydis_site.apps.redirect.urls')),
path('', include('django_prometheus.urls')),
-
- path('staff/', include('pydis_site.apps.staff.urls', namespace='staff')),
] if not settings.env("STATIC_BUILD") else []
urlpatterns = (
*NON_STATIC_PATTERNS,
+
+ # This must be mounted before the `content` app to prevent Django
+ # from wildcard matching all requests to `pages/...`.
+ path('', include('pydis_site.apps.redirect.urls')),
+
path('pages/', include('pydis_site.apps.content.urls', namespace='content')),
path('resources/', include('pydis_site.apps.resources.urls')),
path('events/', include('pydis_site.apps.events.urls', namespace='events')),
path('', include('pydis_site.apps.home.urls', namespace='home')),
)
+
+
+if not settings.env("STATIC_BUILD"):
+ urlpatterns += (
+ path('staff/', include('pydis_site.apps.staff.urls', namespace='staff')),
+ )