portal: refactor origin views into module

This commit is contained in:
Iain Learmonth 2022-05-04 13:46:52 +01:00
parent 33e6d58455
commit 22f850cf6b
8 changed files with 158 additions and 134 deletions

View file

@ -4,19 +4,20 @@ from flask import Blueprint, render_template, Response, flash, redirect, url_for
from sqlalchemy import exc, desc, or_
from app.extensions import db
from app.models import AbstractResource
from app.models.bridges import BridgeConf, Bridge
from app.models.alarms import Alarm
from app import Origin, Proxy
from app.models.base import Group, MirrorList
from app.portal.forms import NewOriginForm, EditOriginForm, LifecycleForm, \
NewBridgeConfForm, EditBridgeConfForm, NewMirrorListForm
from app.portal.forms import LifecycleForm, NewBridgeConfForm, EditBridgeConfForm, NewMirrorListForm
from app.portal.group import bp as group
from app.portal.origin import bp as origin
from app.portal.proxy import bp as proxy
from app.portal.util import response_404, view_lifecycle
portal = Blueprint("portal", __name__, template_folder="templates", static_folder="static")
portal.register_blueprint(group, url_prefix="/group")
portal.register_blueprint(origin, url_prefix="/origin")
portal.register_blueprint(proxy, url_prefix="/proxy")
@ -48,72 +49,6 @@ def portal_home():
lastweek=lastweek, proxies=proxies)
@portal.route("/origin/new", methods=['GET', 'POST'])
@portal.route("/origin/new/<group_id>", methods=['GET', 'POST'])
def new_origin(group_id=None):
form = NewOriginForm()
form.group.choices = [(x.id, x.group_name) for x in Group.query.all()]
if form.validate_on_submit():
origin = Origin()
origin.group_id = form.group.data
origin.domain_name = form.domain_name.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.created = datetime.utcnow()
origin.updated = datetime.utcnow()
try:
db.session.add(origin)
db.session.commit()
flash(f"Created new origin {origin.domain_name}.", "success")
return redirect(url_for("portal.edit_origin", origin_id=origin.id))
except exc.SQLAlchemyError as e:
print(e)
flash("Failed to create new origin.", "danger")
return redirect(url_for("portal.view_origins"))
if group_id:
form.group.data = group_id
return render_template("new.html.j2", section="origin", form=form)
@portal.route('/origin/edit/<origin_id>', methods=['GET', 'POST'])
def edit_origin(origin_id):
origin = Origin.query.filter(Origin.id == origin_id).first()
if origin is None:
return Response(render_template("error.html.j2",
section="origin",
header="404 Origin Not Found",
message="The requested origin could not be found."),
status=404)
form = EditOriginForm(group=origin.group_id,
description=origin.description,
auto_rotate=origin.auto_rotation)
form.group.choices = [(x.id, x.group_name) for x in Group.query.all()]
if form.validate_on_submit():
origin.group_id = form.group.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.updated = datetime.utcnow()
try:
db.session.commit()
flash("Saved changes to group.", "success")
except exc.SQLAlchemyError:
flash("An error occurred saving the changes to the group.", "danger")
return render_template("origin.html.j2",
section="origin",
origin=origin, form=form)
@portal.route("/origins")
def view_origins():
origins = Origin.query.order_by(Origin.domain_name).all()
return render_template("list.html.j2",
section="origin",
title="Origins",
item="origin",
new_link=url_for("portal.new_origin"),
items=origins)
@portal.route("/search")
def search():
query = request.args.get("query")
@ -294,39 +229,6 @@ def blocked_bridge(bridge_id):
form=form)
def response_404(message: str):
return Response(render_template("error.html.j2",
header="404 Not Found",
message=message))
def view_lifecycle(*,
header: str,
message: str,
success_message: str,
success_view: str,
section: str,
resource: AbstractResource,
action: str):
form = LifecycleForm()
if form.validate_on_submit():
if action == "destroy":
resource.destroy()
elif action == "deprecate":
resource.deprecate(reason="manual")
else:
flash("Unknown action")
return redirect(url_for("portal.portal_home"))
db.session.commit()
flash(success_message, "success")
return redirect(url_for(success_view))
return render_template("lifecycle.html.j2",
header=header,
message=message,
section=section,
form=form)
@portal.route("/bridgeconf/destroy/<bridgeconf_id>", methods=['GET', 'POST'])
def destroy_bridgeconf(bridgeconf_id: int):
bridgeconf = BridgeConf.query.filter(BridgeConf.id == bridgeconf_id, BridgeConf.destroyed == None).first()
@ -343,17 +245,3 @@ def destroy_bridgeconf(bridgeconf_id: int):
)
@portal.route("/origin/destroy/<origin_id>", methods=['GET', 'POST'])
def destroy_origin(origin_id: int):
origin = Origin.query.filter(Origin.id == origin_id, Origin.destroyed == None).first()
if origin is None:
return response_404("The requested origin could not be found.")
return view_lifecycle(
header=f"Destroy origin {origin.domain_name}",
message=origin.description,
success_message="All proxies from the destroyed origin will shortly be destroyed at their providers.",
success_view="portal.view_origins",
section="origin",
resource=origin,
action="destroy"
)

View file

@ -3,19 +3,6 @@ from wtforms import StringField, SubmitField, SelectField, BooleanField, Integer
from wtforms.validators import DataRequired, NumberRange
class NewOriginForm(FlaskForm):
domain_name = StringField('Domain Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?", default=True)
submit = SubmitField('Save Changes')
class EditOriginForm(FlaskForm):
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?")
submit = SubmitField('Save Changes')
class EditMirrorForm(FlaskForm):

111
app/portal/origin.py Normal file
View file

@ -0,0 +1,111 @@
from datetime import datetime
from flask import flash, redirect, url_for, render_template, Response, Blueprint
from flask_wtf import FlaskForm
from sqlalchemy import exc
from wtforms import StringField, SelectField, SubmitField, BooleanField
from wtforms.validators import DataRequired
from app.extensions import db
from app.models.base import Group
from app.models.mirrors import Origin
from app.portal.util import response_404, view_lifecycle
bp = Blueprint("origin", __name__)
class NewOriginForm(FlaskForm):
domain_name = StringField('Domain Name', validators=[DataRequired()])
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?", default=True)
submit = SubmitField('Save Changes')
class EditOriginForm(FlaskForm):
description = StringField('Description', validators=[DataRequired()])
group = SelectField('Group', validators=[DataRequired()])
auto_rotate = BooleanField("Enable auto-rotation?")
submit = SubmitField('Save Changes')
@bp.route("/new", methods=['GET', 'POST'])
@bp.route("/new/<group_id>", methods=['GET', 'POST'])
def origin_new(group_id=None):
form = NewOriginForm()
form.group.choices = [(x.id, x.group_name) for x in Group.query.all()]
if form.validate_on_submit():
origin = Origin()
origin.group_id = form.group.data
origin.domain_name = form.domain_name.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.created = datetime.utcnow()
origin.updated = datetime.utcnow()
try:
db.session.add(origin)
db.session.commit()
flash(f"Created new origin {origin.domain_name}.", "success")
return redirect(url_for("portal.origin.origin_edit", origin_id=origin.id))
except exc.SQLAlchemyError as e:
print(e)
flash("Failed to create new origin.", "danger")
return redirect(url_for("portal.origin.origin_list"))
if group_id:
form.group.data = group_id
return render_template("new.html.j2", section="origin", form=form)
@bp.route('/edit/<origin_id>', methods=['GET', 'POST'])
def origin_edit(origin_id):
origin = Origin.query.filter(Origin.id == origin_id).first()
if origin is None:
return Response(render_template("error.html.j2",
section="origin",
header="404 Origin Not Found",
message="The requested origin could not be found."),
status=404)
form = EditOriginForm(group=origin.group_id,
description=origin.description,
auto_rotate=origin.auto_rotation)
form.group.choices = [(x.id, x.group_name) for x in Group.query.all()]
if form.validate_on_submit():
origin.group_id = form.group.data
origin.description = form.description.data
origin.auto_rotation = form.auto_rotate.data
origin.updated = datetime.utcnow()
try:
db.session.commit()
flash("Saved changes to group.", "success")
except exc.SQLAlchemyError:
flash("An error occurred saving the changes to the group.", "danger")
return render_template("origin.html.j2",
section="origin",
origin=origin, form=form)
@bp.route("/list")
def origin_list():
origins = Origin.query.order_by(Origin.domain_name).all()
return render_template("list.html.j2",
section="origin",
title="Origins",
item="origin",
new_link=url_for("portal.origin.origin_new"),
items=origins)
@bp.route("/destroy/<origin_id>", methods=['GET', 'POST'])
def origin_destroy(origin_id: int):
origin = Origin.query.filter(Origin.id == origin_id, Origin.destroyed == None).first()
if origin is None:
return response_404("The requested origin could not be found.")
return view_lifecycle(
header=f"Destroy origin {origin.domain_name}",
message=origin.description,
success_message="All proxies from the destroyed origin will shortly be destroyed at their providers.",
success_view="portal.view_origins",
section="origin",
resource=origin,
action="destroy"
)

View file

@ -31,7 +31,7 @@ def proxy_block(proxy_id):
proxy.deprecate(reason="manual")
db.session.commit()
flash("Proxy will be shortly replaced.", "success")
return redirect(url_for("portal.edit_origin", origin_id=proxy.origin.id))
return redirect(url_for("portal.origin.origin_edit", origin_id=proxy.origin.id))
return render_template("lifecycle.html.j2",
header=f"Mark proxy for {proxy.origin.domain_name} as blocked?",
message=proxy.url,

View file

@ -78,7 +78,7 @@
</li>
<li class="nav-item">
<a class="nav-link{% if section == "origin" %} active{% endif %}"
href="{{ url_for("portal.view_origins") }}">
href="{{ url_for("portal.origin.origin_list") }}">
Origins
</a>
</li>

View file

@ -11,7 +11,7 @@
</div>
<h3 class="mt-3">Origins</h3>
<a href="{{ url_for("portal.new_origin", group_id=group.id) }}" class="btn btn-success btn-sm">Create new origin</a>
<a href="{{ url_for("portal.origin.origin_new", group_id=group.id) }}" class="btn btn-success btn-sm">Create new origin</a>
{% if group.origins %}
{{ origins_table(group.origins) }}
{% endif %}

View file

@ -80,7 +80,7 @@
<a href="{{ url_for("portal.group.group_edit", group_id=origin.group.id) }}">{{ origin.group.group_name }}</a>
</td>
<td>
<a href="{{ url_for("portal.edit_origin", origin_id=origin.id) }}"
<a href="{{ url_for("portal.origin.origin_edit", origin_id=origin.id) }}"
class="btn btn-primary btn-sm">View/Edit</a>
</td>
</tr>
@ -113,7 +113,7 @@
<a href="https://{{ proxy.origin.domain_name }}" class="btn btn-secondary btn-sm"
target="_bypass"
rel="noopener noreferer">⎋</a>
<a href="{{ url_for("portal.edit_origin", origin_id=proxy.origin.id) }}">{{ proxy.origin.domain_name }}</a>
<a href="{{ url_for("portal.origin.origin_edit", origin_id=proxy.origin.id) }}">{{ proxy.origin.domain_name }}</a>
</td>
<td>
<a href="{{ url_for("portal.group.group_edit", group_id=proxy.origin.group.id) }}">{{ proxy.origin.group.group_name }}</a>

38
app/portal/util.py Normal file
View file

@ -0,0 +1,38 @@
from flask import Response, render_template, flash, redirect, url_for
from app import db
from app.models import AbstractResource
from app.portal.forms import LifecycleForm
def response_404(message: str):
return Response(render_template("error.html.j2",
header="404 Not Found",
message=message))
def view_lifecycle(*,
header: str,
message: str,
success_message: str,
success_view: str,
section: str,
resource: AbstractResource,
action: str):
form = LifecycleForm()
if form.validate_on_submit():
if action == "destroy":
resource.destroy()
elif action == "deprecate":
resource.deprecate(reason="manual")
else:
flash("Unknown action")
return redirect(url_for("portal.portal_home"))
db.session.commit()
flash(success_message, "success")
return redirect(url_for(success_view))
return render_template("lifecycle.html.j2",
header=header,
message=message,
section=section,
form=form)