diff options
Diffstat (limited to 'src/hydrilla/proxy/web_ui/repos.py')
-rw-r--r-- | src/hydrilla/proxy/web_ui/repos.py | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/src/hydrilla/proxy/web_ui/repos.py b/src/hydrilla/proxy/web_ui/repos.py index d4e81c0..166cf53 100644 --- a/src/hydrilla/proxy/web_ui/repos.py +++ b/src/hydrilla/proxy/web_ui/repos.py @@ -34,6 +34,7 @@ from __future__ import annotations import typing as t import flask +import werkzeug from .. import state as st from . import _app @@ -41,11 +42,36 @@ from . import _app bp = flask.Blueprint('repos', __package__) +@bp.route('/repos/add', methods=['GET']) +def add_repo_get(errors: t.Mapping[str, bool] = {}) -> werkzeug.Response: + html = flask.render_template('repos__add.html.jinja', **errors) + return flask.make_response(html, 200) + +@bp.route('/repos/add', methods=['POST']) +def add_repo_post() -> werkzeug.Response: + form_data = flask.request.form + if 'name' not in form_data or 'url' not in form_data: + return add_repo_get() + + try: + new_repo_ref = _app.get_haketilo_state().repo_store().add( + name = form_data['name'], + url = form_data['url'] + ) + except st.RepoNameInvalid: + return add_repo_get({'repo_name_invalid': True}) + except st.RepoNameTaken: + return add_repo_get({'repo_name_taken': True}) + except st.RepoUrlInvalid: + return add_repo_get({'repo_url_invalid': True}) + + return flask.redirect(flask.url_for('.show_repo', repo_id=new_repo_ref.id)) + @bp.route('/repos') -def repos() -> flask.Response: - state = t.cast(_app.WebUIApp, flask.current_app)._haketilo_state +def repos() -> werkzeug.Response: + repo_store = _app.get_haketilo_state().repo_store() - local_semirepo_info, *repo_infos = state.repo_store().get_display_infos() + local_semirepo_info, *repo_infos = repo_store.get_display_infos() html = flask.render_template( 'repos.html.jinja', @@ -54,12 +80,10 @@ def repos() -> flask.Response: ) return flask.make_response(html, 200) -@bp.route('/repos/view/<string:repo_id>', methods=['GET']) -def show_repo(repo_id: str) -> flask.Response: - state = t.cast(_app.WebUIApp, flask.current_app)._haketilo_state - +@bp.route('/repos/view/<string:repo_id>') +def show_repo(repo_id: str) -> werkzeug.Response: try: - store = state.repo_store() + store = _app.get_haketilo_state().repo_store() display_info = store.get(repo_id).get_display_info() html = flask.render_template( @@ -70,6 +94,44 @@ def show_repo(repo_id: str) -> flask.Response: except st.MissingItemError: flask.abort(404) -@bp.route('/repos/view/<string:repo_id>', methods=['POST']) -def update_repo(repo_id: str) -> flask.Response: - raise NotImplementedError() +def sanitize_altered_repo_id(repo_id: str) -> str: + repo_id = str(int(repo_id)) + if repo_id == '1': + # Protect local semi-repo. + flask.abort(403) + + return repo_id + +@bp.route('/repos/update_url/<string:repo_id>', methods=['POST']) +def update_repo_url(repo_id: str) -> werkzeug.Response: + repo_id = sanitize_altered_repo_id(repo_id) + + try: + repo_ref = _app.get_haketilo_state().repo_store().get(repo_id) + repo_ref.update() + except st.MissingItemError: + flask.abort(404) + + return flask.redirect(flask.url_for('.show_repo', repo_id=repo_id)) + +@bp.route('/repos/remove/<string:repo_id>', methods=['POST']) +def remove_repo(repo_id: str): + repo_id = sanitize_altered_repo_id(repo_id) + + try: + _app.get_haketilo_state().repo_store().get(repo_id).remove() + except st.MissingItemError: + flask.abort(404) + + return flask.redirect(flask.url_for('.repos')) + +@bp.route('/repos/refresh/<string:repo_id>', methods=['POST']) +def refresh_repo(repo_id: str): + repo_id = sanitize_altered_repo_id(repo_id) + + try: + _app.get_haketilo_state().repo_store().get(repo_id).refresh() + except st.MissingItemError: + flask.abort(404) + + return flask.redirect(flask.url_for('.show_repo', repo_id=repo_id)) |