aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/web_ui/prompts.py
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-09-09 11:44:59 +0200
committerWojtek Kosior <koszko@koszko.org>2022-09-28 14:03:18 +0200
commitbeb163cfd15b93bf664b6a0590e114d4432e3ef9 (patch)
tree4a98def490dabb5f4df927a7a79504eb2ab66c9c /src/hydrilla/proxy/web_ui/prompts.py
parent45e5cf8dc3ca936e2db8e7e45689d0a3331aad43 (diff)
downloadhaketilo-hydrilla-beb163cfd15b93bf664b6a0590e114d4432e3ef9.tar.gz
haketilo-hydrilla-beb163cfd15b93bf664b6a0590e114d4432e3ef9.zip
[proxy] allow prompting the user when a package suitable for current site is found; add proxy's options page
This commit also causes uncached responses to be forced on all HTTP request to external servers. This is needed to make sure that changes Haketilo makes to HTTP response headers are always picked up by the browser. The drawback is that this increases network traffic causing a performance hit. We might optimize this in the future.
Diffstat (limited to 'src/hydrilla/proxy/web_ui/prompts.py')
-rw-r--r--src/hydrilla/proxy/web_ui/prompts.py116
1 files changed, 92 insertions, 24 deletions
diff --git a/src/hydrilla/proxy/web_ui/prompts.py b/src/hydrilla/proxy/web_ui/prompts.py
index b546e47..58b7906 100644
--- a/src/hydrilla/proxy/web_ui/prompts.py
+++ b/src/hydrilla/proxy/web_ui/prompts.py
@@ -42,30 +42,37 @@ from . import _app
bp = flask.Blueprint('prompts', __package__)
-@bp.route('/auto_install_error', methods=['GET'])
-def auto_install_error_prompt() -> werkzeug.Response:
- state = _app.get_haketilo_state()
+def deserialized_request_details(salt: str) -> t.Mapping[str, str]:
serializer = URLSafeSerializer(
- state.get_secret(),
- salt = 'auto_install_error'
+ _app.get_haketilo_state().get_secret(),
+ salt = salt
)
+ return serializer.loads(flask.request.args['details'])
+
+
+@bp.route('/auto_install_error', methods=['GET'])
+def auto_install_error_prompt(errors: t.Mapping[str, bool] = {}) \
+ -> werkzeug.Response:
try:
- details: t.Mapping[str, str] = \
- serializer.loads(flask.request.args['details'])
+ details = deserialized_request_details('auto_install_error')
except:
return flask.redirect(flask.url_for('home'))
try:
- payload_ref = state.payload_store().get(details['payload_id'])
+ payload_store = _app.get_haketilo_state().payload_store()
+ payload_ref = payload_store.get(details['payload_id'])
display_info = payload_ref.get_display_info()
+ if not display_info.has_problems:
+ return flask.redirect(details['next_url'])
+
html = flask.render_template(
'prompts/auto_install_error.html.jinja',
display_info = display_info,
- next_url = details['next_url']
+ **errors
)
return flask.make_response(html, 200)
except st.MissingItemError:
@@ -73,12 +80,16 @@ def auto_install_error_prompt() -> werkzeug.Response:
@bp.route('/auto_install_error', methods=['POST'])
def auto_install_error_prompt_post() -> werkzeug.Response:
+ try:
+ details = deserialized_request_details('auto_install_error')
+ except:
+ return flask.redirect(flask.url_for('home'), code=303)
+
form_data = flask.request.form
action = form_data['action']
mapping_ver_id = str(int(form_data['mapping_ver_id']))
- payload_id = str(int(form_data['payload_id']))
- next_url = form_data['next_url']
+ payload_id = str(int(details['payload_id']))
state = _app.get_haketilo_state()
@@ -92,24 +103,81 @@ def auto_install_error_prompt_post() -> werkzeug.Response:
if action == 'disable_mapping':
mapping_ver_ref.update_mapping_status(st.EnabledStatus.DISABLED)
elif action == 'retry_install':
- payload_ref.ensure_items_installed()
+ payload_ref.ensure_items_installed()
else:
raise ValueError()
- except (st.RepoCommunicationError, st.FileInstallationError):
- params = {'payload_id': payload_id, 'next_url': next_url}
+ except st.RepoCommunicationError:
+ assert action == 'retry_install'
+ return auto_install_error_prompt({'repo_communication_error': True})
+ except st.FileInstallationError:
+ assert action == 'retry_install'
+ return auto_install_error_prompt({'file_installation_error': True})
+ except st.MissingItemError:
+ flask.abort(404)
- serializer = URLSafeSerializer(
- state.get_secret(),
- salt = 'auto_install_error'
- )
- query = urlencode({'details': params})
- redirect_url = flask.url_for(
- '.auto_install_error_prompt',
- details = serializer.dumps(params)
+ return flask.redirect(details['next_url'])
+
+
+@bp.route('/package_suggestion', methods=['GET'])
+def package_suggestion_prompt(errors: t.Mapping[str, bool] = {}) \
+ -> werkzeug.Response:
+ try:
+ details = deserialized_request_details('package_suggestion')
+ except:
+ return flask.redirect(flask.url_for('home'))
+
+ try:
+ payload_store = _app.get_haketilo_state().payload_store()
+ payload_ref = payload_store.get(details['payload_id'])
+
+ display_info = payload_ref.get_display_info()
+
+ if display_info.mapping_info.active != st.ActiveStatus.AUTO:
+ return flask.redirect(details['next_url'])
+
+ html = flask.render_template(
+ 'prompts/package_suggestion.html.jinja',
+ display_info = display_info,
+ **errors
)
+ return flask.make_response(html, 200)
+ except st.MissingItemError:
+ flask.abort(404)
+
+@bp.route('/package_suggestion', methods=['POST'])
+def package_suggestion_prompt_post() -> werkzeug.Response:
+ try:
+ details = deserialized_request_details('package_suggestion')
+ except:
+ return flask.redirect(flask.url_for('home'))
+
+ form_data = flask.request.form
+ action = form_data['action']
- return flask.redirect(redirect_url)
+ mapping_ver_id = str(int(form_data['mapping_ver_id']))
+
+ state = _app.get_haketilo_state()
+
+ try:
+ mapping_ver_store = state.mapping_version_store()
+ mapping_ver_ref = mapping_ver_store.get(mapping_ver_id)
+
+ if action == 'disable_mapping':
+ mapping_ver_ref.update_mapping_status(st.EnabledStatus.DISABLED)
+ elif action == 'enable_mapping':
+ mapping_ver_ref.update_mapping_status(
+ enabled = st.EnabledStatus.ENABLED,
+ frozen = st.FrozenStatus.EXACT_VERSION
+ )
+ else:
+ raise ValueError()
+ except st.RepoCommunicationError:
+ assert action == 'enable_mapping'
+ return package_suggestion_prompt({'repo_communication_error': True})
+ except st.FileInstallationError:
+ assert action == 'enable_mapping'
+ return package_suggestion_prompt({'file_installation_error': True})
except st.MissingItemError:
flask.abort(404)
- return flask.redirect(next_url)
+ return flask.redirect(details['next_url'])