diff options
| author | Frederick Muriuki Muriithi | 2026-01-30 12:31:34 -0600 |
|---|---|---|
| committer | Frederick Muriuki Muriithi | 2026-01-30 12:32:16 -0600 |
| commit | 4fb7f4a9d69611be0358c64a8de2a3b349933382 (patch) | |
| tree | a14b51a30cb1a0e5fec5fe827bd60006ef38bc6b | |
| parent | b627bd70df9c634be276e7db1aa6a038d7ccf1bc (diff) | |
| download | gn-uploader-4fb7f4a9d69611be0358c64a8de2a3b349933382.tar.gz | |
Implement UI logic to trigger phenotype deletion job.
| -rw-r--r-- | uploader/phenotypes/views.py | 96 | ||||
| -rw-r--r-- | uploader/templates/phenotypes/confirm-delete-phenotypes.html | 24 |
2 files changed, 105 insertions, 15 deletions
diff --git a/uploader/phenotypes/views.py b/uploader/phenotypes/views.py index 2cf0ca0..9b635e2 100644 --- a/uploader/phenotypes/views.py +++ b/uploader/phenotypes/views.py @@ -612,6 +612,11 @@ def load_phenotypes_success_handler(job): job_id=job["job_id"])) +def proceed_to_job_status(job): + app.logger.debug("The new job: %s", job) + return redirect(url_for("background-jobs.job_status", job_id=job["job_id"])) + + @phenotypesbp.route( "<int:species_id>/populations/<int:population_id>/phenotypes/datasets" "/<int:dataset_id>/load-data-to-database", @@ -654,11 +659,6 @@ def load_data_to_database( def __handle_error__(resp): return render_template("http-error.html", *resp.json()) - def __handle_success__(load_job): - app.logger.debug("The phenotypes loading job: %s", load_job) - return redirect(url_for( - "background-jobs.job_status", job_id=load_job["job_id"])) - return request_token( token_uri=urljoin(oauth2client.authserver_uri(), "auth/token"), @@ -689,7 +689,7 @@ def load_data_to_database( Path(f"{uploads_dir(app)}/job_errors"), worker_manager="gn_libs.jobs.launcher", loglevel=_loglevel) - ).either(__handle_error__, __handle_success__) + ).either(__handle_error__, proceed_to_job_status) def update_phenotype_metadata(conn, metadata: dict): @@ -1158,6 +1158,12 @@ def rerun_qtlreaper_success_handler(job): return return_to_dataset_view_handler(job, "QTLReaper ran successfully!") +def delete_phenotypes_success_handler(job): + """Handle success running the 'delete-phenotypes' script.""" + return return_to_dataset_view_handler( + job, "Phenotypes deleted successfully.") + + @phenotypesbp.route( "<int:species_id>/populations/<int:population_id>/phenotypes/datasets" "/<int:dataset_id>/delete", @@ -1174,7 +1180,21 @@ def delete_phenotypes(# pylint: disable=[unused-argument] **kwargs ): """Delete the specified phenotype data.""" - with database_connection(app.config["SQL_URI"]) as conn: + _dataset_page = redirect(url_for( + "species.populations.phenotypes.view_dataset", + species_id=species["SpeciesId"], + population_id=population["Id"], + dataset_id=dataset["Id"])) + + def __handle_error__(resp): + flash( + "Error retrieving authorisation token. Phenotype deletion " + "failed. Please try again later.") + return _dataset_page + + _jobs_db = app.config["ASYNCHRONOUS_JOBS_SQLITE_DB"] + with (database_connection(app.config["SQL_URI"]) as conn, + sqlite3.connection(_jobs_db) as jobsconn): form = request.form xref_ids = tuple(int(item) for item in set(form.getlist("xref_ids"))) @@ -1186,16 +1206,64 @@ def delete_phenotypes(# pylint: disable=[unused-argument] population_id=population["Id"], dataset_id=dataset["Id"])) case "delete": - # delete everything - # python3 -m scripts.phenotypes.delete_phenotypes <mariadburi> <authdburi> <speciesid> <populationid> - # - # delete selected phenotypes - # python3 -m scripts.phenotypes.delete_phenotypes <mariadburi> <authdburi> <speciesid> <populationid> --xref-ids-file=/path/to/file.txt - return "Would actually delete the data!" + _loglevel = logging.getLevelName( + app.logger.getEffectiveLevel()).lower() + if form.get("confirm_delete_all_phenotypes", "") == "on": + _cmd = ["--delete-all"] + else: + # setup phenotypes xref_ids file + _xref_ids_file = Path( + app.config["SCRATCH_DIRECTORY"], + f"delete-phenotypes-{uuid.uuid4()}.txt") + with _xref_ids_file.open(mode="w", encoding="utf8") as ptr: + ptr.write("\n".join(str(_id) for _id in xref_ids)) + + _cmd = ["--xref_ids_file", str(_xref_ids_file)] + + _job_id = uuid.uuid4() + return request_token( + token_uri=urljoin( + oauth2client.authserver_uri(), "auth/token"), + user_id=session.user_details()["user_id"] + ).then( + lambda token: gnlibs_jobs.initialise_job( + jobsconn, + _job_id, + [ + sys.executable, + "-u", + "-m", + "scripts.phenotypes.delete_phenotypes", + "--log-level", _loglevel, + app.config["SQL_URI"], + str(species["SpeciesId"]), + str(population["Id"]), + str(dataset["Id"]), + app.config["AUTH_SERVER_URL"], + token["access_token"]] + _cmd, + "delete-phenotypes", + extra_meta={ + "species_id": species["SpeciesId"], + "population_id": population["Id"], + "dataset_id": dataset["Id"], + "success_handler": ( + "uploader.phenotypes.views." + "delete_phenotypes_success_handler") + }, + external_id=session.logged_in_user_id()) + ).then( + lambda _job: gnlibs_jobs.launch_job( + _job, + _jobs_db, + Path(f"{uploads_dir(app)}/job_errors"), + worker_manager="gn_libs.jobs.launcher", + loglevel=_loglevel) + ).either(__handle_error__, proceed_to_job_status) case _: return render_template( "phenotypes/confirm-delete-phenotypes.html", species=species, population=population, dataset=dataset, - phenotypes=xref_ids) + phenotypes=[{"xref_id": xref_id} + for xref_id in xref_ids]) diff --git a/uploader/templates/phenotypes/confirm-delete-phenotypes.html b/uploader/templates/phenotypes/confirm-delete-phenotypes.html index b59fd7b..3b16698 100644 --- a/uploader/templates/phenotypes/confirm-delete-phenotypes.html +++ b/uploader/templates/phenotypes/confirm-delete-phenotypes.html @@ -56,9 +56,10 @@ {%for phenotype in phenotypes%} <tr> <td> - <input id="chk-xref-id-{{phenotype}}" + <input id="chk-xref-id-{{phenotype.xref_id}}" name="xref_ids" type="checkbox" + value="{{phenotype.xref_id}}" class="chk-row-select" /> </td> <td>{{phenotype}}</td> @@ -166,6 +167,27 @@ $("#btn-deselect-all-phenotypes").on("click", function(event) { dt.deselectAll(); }); + + $("#btn-delete-phenotypes-selected").on("click", function(event) { + event.preventDefault(); + form = $("#frm-delete-phenotypes-selected"); + form.find(".dynamically-added-element").remove(); + dt.rows({selected: true}).nodes().each(function(node, index) { + var xref_id = $(node) + .find('input[type="checkbox"]:checked') + .val(); + var chk = $('<input type="checkbox">'); + chk.attr("class", "dynamically-added-element"); + chk.attr("value", xref_id); + chk.attr("name", "xref_ids"); + chk.attr("style", "display: none"); + chk.prop("checked", true); + form.append(chk); + }); + form.append( + $('<input type="hidden" name="action" value="delete" />')); + form.submit(); + }) }); </script> {%endblock%} |
