diff options
author | 2018-05-15 14:55:26 +0100 | |
---|---|---|
committer | 2018-05-15 14:55:26 +0100 | |
commit | 84820fb712eece3d99d0ff3b5af474165703fcbe (patch) | |
tree | 04dee49b72c8ee57a646e2a6d41565a37fda4cf9 /pysite | |
parent | Fix editing wiki in debug mode (diff) |
Add RedirectView class for views that only redirect elsewhere
Diffstat (limited to 'pysite')
-rw-r--r-- | pysite/base_route.py | 49 | ||||
-rw-r--r-- | pysite/route_manager.py | 3 | ||||
-rw-r--r-- | pysite/views/main/redirects/github.py | 10 | ||||
-rw-r--r-- | pysite/views/main/redirects/invite.py | 10 | ||||
-rw-r--r-- | pysite/views/main/redirects/stats.py | 10 | ||||
-rw-r--r-- | pysite/views/wiki/index.py | 12 |
6 files changed, 63 insertions, 31 deletions
diff --git a/pysite/base_route.py b/pysite/base_route.py index 58be7598..98b50a12 100644 --- a/pysite/base_route.py +++ b/pysite/base_route.py @@ -1,7 +1,7 @@ from collections import Iterable from typing import Any -from flask import Blueprint, Response, jsonify, render_template, url_for +from flask import Blueprint, Response, jsonify, render_template, url_for, redirect from flask.views import MethodView from werkzeug.exceptions import default_exceptions @@ -243,3 +243,50 @@ class TemplateView(RouteView): def get(self, *_): return self.render(self.template) + + +class RedirectView(RouteView): + """ + An easy view for routes that simply redirect to another page or view. + + This class is intended to be subclassed - use it as a base class for your own views, and set the class-level + attributes as appropriate. For example: + + >>> class MyView(RedirectView): + ... name = "my_view" # Flask internal name for this route + ... path = "/my_view" # Actual URL path to reach this route + ... code = 303 # HTTP status code to use for the redirect; 303 by default + ... page = "staff.index" # Page to redirect to + ... kwargs = {} # Any extra keyword args to pass to the url_for call, if redirecting to another view + + You can specify a full URL, including the protocol, eg "http://google.com" or a Flask internal route name, + eg "main.index". Nothing else is supported. + + Note that this view only handles GET requests. If you need any other verbs, you can implement them yourself + or just use one of the more customizable base view classes. + """ + + code = 303 # type: int + page = None # type: str + kwargs = {} # type: Optional[dict] + + @classmethod + def setup(cls: "RedirectView", manager: "pysite.route_manager.RouteManager", blueprint: Blueprint): + """ + Set up the view, deferring most setup to the superclasses but checking for the template attribute. + + :param manager: Instance of the current RouteManager + :param blueprint: Current Flask blueprint to register the error handler for + """ + + if hasattr(super(), "setup"): + super().setup(manager, blueprint) # pragma: no cover + + if not cls.page or not cls.code: + raise RuntimeError("Redirect views must have both `code` and `page` defined") + + def get(self, *_): + if "://" in self.page: + return redirect(self.page, code=self.code) + + return redirect(url_for(self.page, **self.kwargs), code=self.code) diff --git a/pysite/route_manager.py b/pysite/route_manager.py index 764049cd..ef992113 100644 --- a/pysite/route_manager.py +++ b/pysite/route_manager.py @@ -8,7 +8,7 @@ from flask_dance.contrib.discord import make_discord_blueprint from flask_sockets import Sockets from gunicorn_config import _when_ready as when_ready -from pysite.base_route import APIView, BaseView, ErrorView, RouteView, TemplateView +from pysite.base_route import APIView, BaseView, ErrorView, RouteView, TemplateView, RedirectView from pysite.constants import ( CSRF, DEBUG_MODE, DISCORD_OAUTH_AUTHORIZED, DISCORD_OAUTH_ID, DISCORD_OAUTH_REDIRECT, DISCORD_OAUTH_SCOPE, DISCORD_OAUTH_SECRET, PREFERRED_URL_SCHEME) @@ -132,6 +132,7 @@ class RouteManager: cls is not APIView and cls is not WS and cls is not TemplateView and + cls is not RedirectView and ( BaseView in cls.__mro__ or WS in cls.__mro__ diff --git a/pysite/views/main/redirects/github.py b/pysite/views/main/redirects/github.py index f861a91c..b709cd79 100644 --- a/pysite/views/main/redirects/github.py +++ b/pysite/views/main/redirects/github.py @@ -1,11 +1,7 @@ -from flask import redirect +from pysite.base_route import RedirectView -from pysite.base_route import RouteView - -class GitHubView(RouteView): +class GitHubView(RedirectView): path = "/github" name = "github" - - def get(self): - return redirect("https://github.com/discord-python/") + page = "https://github.com/discord-python/" diff --git a/pysite/views/main/redirects/invite.py b/pysite/views/main/redirects/invite.py index 1895d36a..327ad48e 100644 --- a/pysite/views/main/redirects/invite.py +++ b/pysite/views/main/redirects/invite.py @@ -1,11 +1,7 @@ -from flask import redirect +from pysite.base_route import RedirectView -from pysite.base_route import RouteView - -class InviteView(RouteView): +class InviteView(RedirectView): path = "/invite" name = "invite" - - def get(self): - return redirect("https://discord.gg/8NWhsvT") + page = "https://discord.gg/8NWhsvT" diff --git a/pysite/views/main/redirects/stats.py b/pysite/views/main/redirects/stats.py index 935f8539..cf738e4b 100644 --- a/pysite/views/main/redirects/stats.py +++ b/pysite/views/main/redirects/stats.py @@ -1,11 +1,7 @@ -from flask import redirect +from pysite.base_route import RedirectView -from pysite.base_route import RouteView - -class StatsView(RouteView): +class StatsView(RedirectView): path = "/stats" name = "stats" - - def get(self): - return redirect("https://p.datadoghq.com/sb/ac8680a8c-c01b556f01b96622fd4f57545b81d568") + page = "https://p.datadoghq.com/sb/ac8680a8c-c01b556f01b96622fd4f57545b81d568" diff --git a/pysite/views/wiki/index.py b/pysite/views/wiki/index.py index 8290eac9..53a4d269 100644 --- a/pysite/views/wiki/index.py +++ b/pysite/views/wiki/index.py @@ -1,12 +1,8 @@ -from flask import url_for -from werkzeug.utils import redirect +from pysite.base_route import RedirectView -from pysite.base_route import RouteView - -class WikiView(RouteView): +class WikiView(RedirectView): path = "/" name = "index" - - def get(self): - return redirect(url_for("wiki.page", page="home")) + page = "wiki.page" + kwargs = {"page": "home"} |