From 7e3d2191c685041650c676fd25fe604199339beb Mon Sep 17 00:00:00 2001 From: Cara Salter Date: Thu, 21 Mar 2024 11:04:37 +1100 Subject: [PATCH] Add shortlinks Officers can now create redirects from the root domain to other domains --- acmsite/admin/__init__.py | 62 ++++++- acmsite/admin/forms.py | 4 + acmsite/main/__init__.py | 13 +- acmsite/models.py | 13 ++ acmsite/templates/admin/admin-layout.html | 1 + acmsite/templates/admin/links.html | 171 ++++++++++++++++++ .../69cccb10f676_add_shortlinks_models.py | 34 ++++ 7 files changed, 293 insertions(+), 5 deletions(-) create mode 100644 acmsite/templates/admin/links.html create mode 100644 migrations/versions/69cccb10f676_add_shortlinks_models.py diff --git a/acmsite/admin/__init__.py b/acmsite/admin/__init__.py index faa5103..c6332de 100644 --- a/acmsite/admin/__init__.py +++ b/acmsite/admin/__init__.py @@ -3,9 +3,9 @@ import ulid import datetime from flask_login import current_user, login_required -from acmsite.models import User, Event +from acmsite.models import Link, User, Event -from .forms import EventForm +from .forms import EventForm, LinkForm from acmsite import db @@ -76,7 +76,9 @@ def delete_event(id): @bp.route("/event/", methods=["POST"]) @login_required def update_create_event(id): - + if not current_user.is_admin: + flash("Unauthorized") + return redirect(url_for("dashboard.home")) name = request.form.get('name') description = request.form.get('description') @@ -114,3 +116,57 @@ def update_create_event(id): return redirect(url_for("admin.events")) + +@bp.route("/links") +@login_required +def links(): + if not current_user.is_admin: + flash("Unauthorized") + return redirect(url_for("dashboard.home")) + + links = Link.query.all() + form = LinkForm(request.form) + + return render_template("admin/links.html", links=links, form=form) + +@bp.route("/link/") +@login_required +def link(id): + if not current_user.is_admin: + return {"status": "error", "message": "Unauthorized"} + + link = Link.query.filter_by(id=id).first() + + if link is None: + return {"status": "error", "message": "Invalid ID"} + + return link.create_json() + +@bp.route("/link/", methods=["POST"]) +@login_required +def update_create_link(id): + if not current_user.is_admin: + flash("Unauthorized") + return redirect(url_for("dashboard.home")) + + slug = request.form.get('slug') + destination = request.form.get('destination') + + if id == '0': + # new link + l = Link( + id=ulid.ulid(), + slug=slug, + destination=destination) + db.session.add(l) + db.session.commit() + else: + l = Link.query.filter_by(id=id).first() + if l is None: + flash("Invalid ID") + return redirect(url_for("admin.links")) + l.slug = slug + l.destination = destination + db.session.commit() + + return redirect(url_for("admin.links")) diff --git a/acmsite/admin/forms.py b/acmsite/admin/forms.py index 022a173..75ed1c7 100644 --- a/acmsite/admin/forms.py +++ b/acmsite/admin/forms.py @@ -10,3 +10,7 @@ class EventForm(FlaskForm): start_time = TimeField('Start Time') end_day = DateField('End Day', validators=[DataRequired()]) end_time = TimeField('End Time') + +class LinkForm(FlaskForm): + slug = StringField("Slug", validators=[DataRequired()]) + destination = StringField("Destination", validators=[DataRequired()]) diff --git a/acmsite/main/__init__.py b/acmsite/main/__init__.py index 3da4c2d..e4e48bb 100644 --- a/acmsite/main/__init__.py +++ b/acmsite/main/__init__.py @@ -1,6 +1,6 @@ import datetime -from flask import Blueprint, render_template -from acmsite.models import Event +from flask import Blueprint, render_template, abort, redirect +from acmsite.models import Event, Link bp = Blueprint('main', __name__) @@ -16,3 +16,12 @@ def events(): @bp.route("/join") def join(): return render_template("join.html") + + +@bp.route("/") +def shortlink(slug): + l = Link.query.filter_by(slug=slug).first() + if l is None: + abort(404) + + return redirect(l.destination) diff --git a/acmsite/models.py b/acmsite/models.py index 42a534c..ecf7da5 100644 --- a/acmsite/models.py +++ b/acmsite/models.py @@ -48,3 +48,16 @@ class Event(db.Model): "start_time": self.start_time.isoformat(), "end_time": self.end_time.isoformat(), } + +class Link(db.Model): + __tablename__ = "acm_links" + id = Column(String, primary_key=True) + slug = Column(String, nullable=False, unique=True) + destination = Column(String, nullable=False) + + def create_json(self): + return { + "id": self.id, + "slug": self.slug, + "destination": self.destination + } diff --git a/acmsite/templates/admin/admin-layout.html b/acmsite/templates/admin/admin-layout.html index 6592243..29f371a 100644 --- a/acmsite/templates/admin/admin-layout.html +++ b/acmsite/templates/admin/admin-layout.html @@ -22,6 +22,7 @@ {{ render_nav_item('admin.users', 'Member List')}} {{ render_nav_item('admin.events', 'Event List')}} {{ render_nav_item('admin.home', 'Bulk Mail Tool')}} + {{ render_nav_item('admin.links', 'Shortlinks')}}