diff --git a/snikket_web/templates/user_home.html b/snikket_web/templates/user_home.html index 15b7a79..faf2b68 100644 --- a/snikket_web/templates/user_home.html +++ b/snikket_web/templates/user_home.html @@ -30,6 +30,7 @@
{% trans user_name=user_info.display_name %}Welcome home, {{ user_name }}.{% endtrans %}
+ +{% endblock %} diff --git a/snikket_web/user.py b/snikket_web/user.py index a51ec37..978ae4b 100644 --- a/snikket_web/user.py +++ b/snikket_web/user.py @@ -1,9 +1,12 @@ +import aiohttp import asyncio import typing +import urllib import quart.flask_patch from quart import ( Blueprint, + Response, render_template, request, redirect, @@ -168,6 +171,50 @@ async def profile() -> typing.Union[str, quart.Response]: avatar_too_big_warning=EAVATARTOOBIG) +class DataExportForm(BaseForm): + action_export = wtforms.SubmitField( + _l("Export") + ) + + +@bp.route("/manage_data", methods=["GET", "POST"]) +@client.require_session() +async def manage_data() -> typing.Union[str, quart.Response]: + form = DataExportForm() + + if form.validate_on_submit(): + user_info = await client.get_user_info() + # The UTF-8 version of the filename needs to be percent-encoded + encoded_address = urllib.parse.quote( + user_info["address"].encode(encoding='utf-8', errors='strict') + ) + try: + account_data = await client.export_account_data() + except aiohttp.ClientResponseError as e: + if e.status == 404: + await flash( + _("You currently have no account data to export."), + "alert" + ) + else: + raise e + else: + return Response(account_data, + mimetype="application/xml", + headers={ + # We provide the UTF-8 filename, but the ASCII + # one will be used as a fallback for legacy + # browsers (RFC 5987) + "Content-Disposition": ( + 'attachment; filename="account-data.xml"; ' + 'filename*="UTF-8\'\'account-data-{}.xml"' + ).format(encoded_address) + }) + return await render_template("user_manage_data.html", + form=form, + ) + + @bp.route("/logout", methods=["GET", "POST"]) @client.require_session() async def logout() -> typing.Union[quart.Response, str]: