|
|
|
@ -19,6 +19,7 @@
|
|
|
|
|
import arrow |
|
|
|
|
|
|
|
|
|
from flask import Blueprint |
|
|
|
|
from flask import abort |
|
|
|
|
from flask import flash |
|
|
|
|
from flask import redirect |
|
|
|
|
from flask import render_template |
|
|
|
@ -44,6 +45,8 @@ from vowel.models.tokens import TokenPurchase
|
|
|
|
|
import vowel.utils.branding |
|
|
|
|
from vowel.utils import cache |
|
|
|
|
from vowel.utils.auth import is_staff_member |
|
|
|
|
from vowel.utils.organisation import OrganisationNotFound |
|
|
|
|
from vowel.utils.organisation import organisation_from_id_or_slug |
|
|
|
|
from vowel.utils.tokens import update_token_types |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -51,17 +54,23 @@ organisation = Blueprint("organisations", __name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/") |
|
|
|
|
@organisation.route("/<organisation_slug>/") |
|
|
|
|
@login_required |
|
|
|
|
def view(organisation_id): |
|
|
|
|
def view(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
View lesson presentation using reveal.js |
|
|
|
|
View organisation information |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation to view |
|
|
|
|
:param organisation_id: organisation to view, selected by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation to view, selected by slug name |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
org = Organisation.query.filter_by(id=organisation_id).first_or_404() |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
|
|
|
|
|
return render_template("organisation/view.html", organisation=org) |
|
|
|
|
|
|
|
|
@ -152,44 +161,60 @@ def _edit_organisation(organisation_id=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/edit/", methods=["GET", "POST"]) |
|
|
|
|
@organisation.route("/<organisation_slug>/edit/", methods=["GET", "POST"]) |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def edit(organisation_id): |
|
|
|
|
def edit(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Edit organisation. |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation to view |
|
|
|
|
:param organisation_id: organisation to edit, by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation to edit, by slug name |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
return _edit_organisation(organisation_id) |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
|
|
|
|
|
return _edit_organisation(org.id) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/edit/branding/", |
|
|
|
|
methods=["GET", "POST"]) |
|
|
|
|
@organisation.route("/<organisation_slug>/edit/branding/", |
|
|
|
|
methods=["GET", "POST"]) |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def branding(organisation_id): |
|
|
|
|
def branding(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Edit organisation branding. |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation branding to edit |
|
|
|
|
:param organisation_id: organisation branding to edit, by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation branding to edit, by slug name |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
organisation = Organisation.query.get_or_404(organisation_id) |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
|
|
|
|
|
org_branding = OrganisationBranding.query.filter_by( |
|
|
|
|
organisation_id=organisation_id).first() |
|
|
|
|
organisation_id=org.id).first() |
|
|
|
|
if not org_branding: |
|
|
|
|
org_branding = OrganisationBranding(organisation_id=organisation_id) |
|
|
|
|
org_branding = OrganisationBranding(organisation_id=org.id) |
|
|
|
|
|
|
|
|
|
form = OrganisationBrandingForm(obj=org_branding) |
|
|
|
|
|
|
|
|
|
if org_branding.logo_id: |
|
|
|
|
logo_url = url_for("resources.file_view", |
|
|
|
|
organisation_id=organisation_id, |
|
|
|
|
organisation_id=org.id, |
|
|
|
|
purpose=org_branding.logo.purpose, |
|
|
|
|
document_id=org_branding.logo_id, |
|
|
|
|
_external=True) |
|
|
|
@ -203,7 +228,7 @@ def branding(organisation_id):
|
|
|
|
|
except ValueError: |
|
|
|
|
flash("Logo could not be found", "danger") |
|
|
|
|
return redirect(url_for("organisations.branding", |
|
|
|
|
organisation_id=organisation_id)) |
|
|
|
|
organisation_id=org.id)) |
|
|
|
|
|
|
|
|
|
resource = Resource.query.get(logo_res_id) |
|
|
|
|
if resource: |
|
|
|
@ -211,7 +236,7 @@ def branding(organisation_id):
|
|
|
|
|
else: |
|
|
|
|
flash("Logo could not be found", "danger") |
|
|
|
|
return redirect(url_for("organisations.branding", |
|
|
|
|
organisation_id=organisation_id)) |
|
|
|
|
organisation_id=org.id)) |
|
|
|
|
elif form.logo_delete.data: |
|
|
|
|
org_branding.logo_id = None |
|
|
|
|
|
|
|
|
@ -221,15 +246,14 @@ def branding(organisation_id):
|
|
|
|
|
db.session.commit() |
|
|
|
|
|
|
|
|
|
# Drop the cached branding info as it has changed |
|
|
|
|
cache.delete_memoized(vowel.utils.branding._branding, organisation_id) |
|
|
|
|
cache.delete_memoized(vowel.utils.branding._branding, org.id) |
|
|
|
|
|
|
|
|
|
flash("Organisation branding saved", "success") |
|
|
|
|
return redirect(url_for("organisations.branding", |
|
|
|
|
organisation_id=organisation_id)) |
|
|
|
|
organisation_id=org.id)) |
|
|
|
|
|
|
|
|
|
return render_template("organisation/branding.html", |
|
|
|
|
organisation=organisation, form=form, |
|
|
|
|
logo_url=logo_url) |
|
|
|
|
organisation=org, form=form, logo_url=logo_url) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/new/", methods=["GET", "POST"]) |
|
|
|
@ -246,21 +270,28 @@ def new():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/tokens/") |
|
|
|
|
@organisation.route("/<organisation_slug>/tokens/") |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def tokens(organisation_id): |
|
|
|
|
def tokens(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Tokens for this organisation. |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation identification |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation identification by slug |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
org = Organisation.query.get_or_404(organisation_id) |
|
|
|
|
update_token_types(organisation_id) |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
|
|
|
|
|
update_token_types(org.id) |
|
|
|
|
|
|
|
|
|
org_tokens = Token.query.filter_by(organisation_id=organisation_id).all() |
|
|
|
|
org_tokens = Token.query.filter_by(organisation_id=org.id).all() |
|
|
|
|
|
|
|
|
|
return render_template("organisation/tokens.html", organisation=org, |
|
|
|
|
tokens=org_tokens) |
|
|
|
@ -268,20 +299,27 @@ def tokens(organisation_id):
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/tokens/purchase/<int:token_id>/", |
|
|
|
|
methods=["GET", "POST"]) |
|
|
|
|
@organisation.route("/<organisation_slug>/tokens/purchase/<int:token_id>/", |
|
|
|
|
methods=["GET", "POST"]) |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def token_purchase(organisation_id, token_id): |
|
|
|
|
def token_purchase(token_id, organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Purchase tokens for this organisation. |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation identification |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param token_id: token identification |
|
|
|
|
:type token_id: int |
|
|
|
|
:param organisation_id: organisation identification, by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation identification, by slug |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
org = Organisation.query.get_or_404(organisation_id) |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
token = Token.query.get_or_404(token_id) |
|
|
|
|
|
|
|
|
|
token_form = TokenPurchaseForm() |
|
|
|
@ -315,7 +353,7 @@ def token_purchase(organisation_id, token_id):
|
|
|
|
|
|
|
|
|
|
flash("Tokens purchased", "success") |
|
|
|
|
return redirect(url_for("organisations.tokens", |
|
|
|
|
organisation_id=organisation_id)) |
|
|
|
|
organisation_id=org.id)) |
|
|
|
|
else: |
|
|
|
|
token_form.currency.data = "GBP" |
|
|
|
|
|
|
|
|
@ -324,35 +362,47 @@ def token_purchase(organisation_id, token_id):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/tokens/history/") |
|
|
|
|
@organisation.route("/<organisation_slug>/tokens/history/") |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def token_history(organisation_id): |
|
|
|
|
def token_history(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Token purchase history |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation |
|
|
|
|
:param organisation_id: organisation by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation by slug |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
org = Organisation.query.get_or_404(organisation_id) |
|
|
|
|
update_token_types(organisation_id) |
|
|
|
|
org_tokens = Token.query.filter_by(organisation_id=organisation_id).all() |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|
update_token_types(org.id) |
|
|
|
|
org_tokens = Token.query.filter_by(organisation_id=org.id).all() |
|
|
|
|
|
|
|
|
|
return render_template("organisation/tokens_list.html", organisation=org, |
|
|
|
|
tokens=org_tokens) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@organisation.route("/<int:organisation_id>/tokens/payment_info/") |
|
|
|
|
@organisation.route("/<organisation_slug>/tokens/payment_info/") |
|
|
|
|
@login_required |
|
|
|
|
@is_staff_member() |
|
|
|
|
def token_payment_info(organisation_id): |
|
|
|
|
def token_payment_info(organisation_id=None, organisation_slug=None): |
|
|
|
|
""" |
|
|
|
|
Token payment methods |
|
|
|
|
|
|
|
|
|
:param organisation_id: organisation |
|
|
|
|
:param organisation_id: organisation by ID |
|
|
|
|
:type organisation_id: int |
|
|
|
|
:param organisation_slug: organisation by slug |
|
|
|
|
:type organisation_slug: str |
|
|
|
|
:return: HTML output |
|
|
|
|
:rtype: jinja2.Template |
|
|
|
|
""" |
|
|
|
|
pass |
|
|
|
|
try: |
|
|
|
|
org = organisation_from_id_or_slug(organisation_id, organisation_slug) |
|
|
|
|
except OrganisationNotFound: |
|
|
|
|
raise abort(404) |
|
|
|
|