From 2b6bc653a6b097dd2b30d858061e3bd7b7cc6eb2 Mon Sep 17 00:00:00 2001 From: BeefTron Date: Mon, 12 Jun 2017 17:56:45 -0700 Subject: [PATCH 01/76] Add button to delete selected genomes --- web/dist/js/islandcompare-rest-urls.js | 1 + web/pages/home.html | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/web/dist/js/islandcompare-rest-urls.js b/web/dist/js/islandcompare-rest-urls.js index 1b66ae35..2846a256 100644 --- a/web/dist/js/islandcompare-rest-urls.js +++ b/web/dist/js/islandcompare-rest-urls.js @@ -4,6 +4,7 @@ var authUrl = rootUrl + "accounts/auth-token/"; var registerUrl = rootUrl + "accounts/register/"; var genomesUrl = rootUrl + "genomes/"; var genomesUploadUrl = rootUrl + "genomes/upload/"; +var genomesUpdateUrl = rootUrl + "genomes/details/"; var genomesGenesUrl = rootUrl + "genomes/genes/"; var analysisUrl = rootUrl + "analysis/"; var analysisRunUrl = rootUrl + "analysis/run/"; diff --git a/web/pages/home.html b/web/pages/home.html index bb465f0a..d267e8b2 100644 --- a/web/pages/home.html +++ b/web/pages/home.html @@ -49,6 +49,9 @@

Upload Genomes

Uploaded Genomes

+
@@ -207,6 +210,27 @@

Run Analysis

return false; }); + $("#genome-delete").click(function() { + var selected_genomes = $("select#selected-genomes-field option").map(function () { + return $(this).val(); + }).get(); + for (var i = 0; i < selected_genomes.length; i++) { + $.ajax({ + type: "DELETE", + url: genomesUpdateUrl + selected_genomes[i], + headers: { + "Authorization": 'Token' + ' ' + getAuthenticationCookie() + }, + success: function() { + genomesTable.row('.selected').remove().draw(); + }, + error: function(message) { + BootstrapDialog.warning(message.responseText); + } + }); + } + }); + $.ajax({ type: "GET", url: analysisUrl, @@ -234,7 +258,7 @@

Run Analysis

"Authorization": 'Token'+' '+getAuthenticationCookie() }, success: function(){ - ReloadGenomesTable(); + ReloadGenomesTable(); //TODO } }); From 3641181d5c040867bfc14c01b4915df8d652186f Mon Sep 17 00:00:00 2001 From: BeefTron Date: Tue, 13 Jun 2017 11:37:41 -0700 Subject: [PATCH 02/76] Uploaded genomes now appear in table immediately --- web/pages/home.html | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/web/pages/home.html b/web/pages/home.html index d267e8b2..5fa95315 100644 --- a/web/pages/home.html +++ b/web/pages/home.html @@ -210,6 +210,8 @@

Run Analysis

return false; }); + // DELETE on the url of each selected genome + // Genome is then removed from table and from the selected genomes area $("#genome-delete").click(function() { var selected_genomes = $("select#selected-genomes-field option").map(function () { return $(this).val(); @@ -223,6 +225,7 @@

Run Analysis

}, success: function() { genomesTable.row('.selected').remove().draw(); + $("#selected-genomes-field option").remove(); }, error: function(message) { BootstrapDialog.warning(message.responseText); @@ -243,7 +246,7 @@

Run Analysis

success: function(data){ ReloadRecentAnalysisTable(data); } - }) + }); }); @@ -257,8 +260,24 @@

Run Analysis

"Cache-Control": "", "Authorization": 'Token'+' '+getAuthenticationCookie() }, - success: function(){ - ReloadGenomesTable(); //TODO + // If upload was successful, another GET call is made to find the id of the last genome - the one that was just + // uploaded. This id is needed to add a row for the new genome into the DataTable. + // There must be a better way to do this. While the data returned by the upload (up_data) contains the + // file name (up_data.name), it doesn't seem to contain the id. + success: function(up_data){ + var new_row_id; + $.ajax({ + type: "GET", + url: genomesUrl, + headers: { + "Authorization": 'Token' + ' ' + getAuthenticationCookie() + }, + success: function(data) { + var new_row_id = data[data.length - 1].id; + var genomesTable = $("#uploaded-genomes").DataTable(); + genomesTable.row.add({ name: up_data.name, id: new_row_id }).draw(); + } + }); } }); From af4a040ef0d2489da7e5a9844ad7a7ba61256855 Mon Sep 17 00:00:00 2001 From: BeefTron Date: Wed, 14 Jun 2017 16:39:30 -0700 Subject: [PATCH 03/76] Deleting genome now deletes related analyses on confirmation from user --- IslandCompare/analysis/urls.py | 1 + IslandCompare/analysis/views.py | 9 +++++ IslandCompare/genomes/views.py | 9 +++++ web/pages/home.html | 67 +++++++++++++++++++++++++-------- 4 files changed, 70 insertions(+), 16 deletions(-) diff --git a/IslandCompare/analysis/urls.py b/IslandCompare/analysis/urls.py index 7d6ea063..628756bc 100644 --- a/IslandCompare/analysis/urls.py +++ b/IslandCompare/analysis/urls.py @@ -7,4 +7,5 @@ url(r'^export/(?P[0-9]+)$', views.ExportAnalysisResultView.as_view(), name="analysis_export"), url(r'^results/(?P[0-9]+)$', views.AnalysisResultsView.as_view(), name="analysis_results"), url(r'^run/', views.AnalysisRunView.as_view(), name="analysis_run"), + url(r'^delete/(?P[0-9]+)$', views.AnalysisDestroyView.as_view(), name="analysis_destroy"), ] diff --git a/IslandCompare/analysis/views.py b/IslandCompare/analysis/views.py index 5aae6bfd..2f843347 100644 --- a/IslandCompare/analysis/views.py +++ b/IslandCompare/analysis/views.py @@ -40,6 +40,15 @@ class AnalysisRetrieveUpdateView(generics.RetrieveUpdateAPIView): def get_queryset(self): return Analysis.objects.filter(owner=self.request.user) +class AnalysisDestroyView(generics.RetrieveDestroyAPIView): + """ + Destroy Analysis + """ + permission_classes = [IsAuthenticated] + serializer_class = AnalysisSerializer + + def get_queryset(self): + return Analysis.objects.filter(owner=self.request.user) class AnalysisRunView(APIView): """ diff --git a/IslandCompare/genomes/views.py b/IslandCompare/genomes/views.py index d0813d96..b597baa7 100644 --- a/IslandCompare/genomes/views.py +++ b/IslandCompare/genomes/views.py @@ -2,6 +2,7 @@ from rest_framework.permissions import IsAuthenticated from genomes.serializers import GenomeSerializer, GenomeUploadSerializer, GenomeGenesSerializer from genomes.models import Genome +from analysis.models import Analysis from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.response import Response @@ -54,6 +55,14 @@ class GenomeRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView): def get_queryset(self): return Genome.objects.filter(owner=self.request.user) + def delete(self, request, *args, **kwargs): + genome = self.get_object() + for a in Analysis.objects.filter(genomes__id__contains=genome.id): + # print(a.name) + a.delete() + genome.delete() + return response.Response(status=204) + class GenomeGeneRetrieveView(generics.RetrieveAPIView): """ diff --git a/web/pages/home.html b/web/pages/home.html index 5fa95315..09de3369 100644 --- a/web/pages/home.html +++ b/web/pages/home.html @@ -216,22 +216,37 @@

Run Analysis

var selected_genomes = $("select#selected-genomes-field option").map(function () { return $(this).val(); }).get(); - for (var i = 0; i < selected_genomes.length; i++) { - $.ajax({ - type: "DELETE", - url: genomesUpdateUrl + selected_genomes[i], - headers: { - "Authorization": 'Token' + ' ' + getAuthenticationCookie() - }, - success: function() { - genomesTable.row('.selected').remove().draw(); - $("#selected-genomes-field option").remove(); - }, - error: function(message) { - BootstrapDialog.warning(message.responseText); + var names = $("select#selected-genomes-field option").map(function () { + return $(this).text(); + }).get(); + $.ajax({ + type: "GET", + url: analysisUrl, + headers: { + "Authorization": 'Token' + ' ' + getAuthenticationCookie() + }, + success: function(data) { + var corresponding_analyses = []; + for (var analysis_i = 0; analysis_i < data.length; analysis_i++) { + for (var genome_i = 0; genome_i < selected_genomes.length; genome_i++) { + var gen_id = parseInt(selected_genomes[genome_i]); + if ($.inArray(gen_id, data[analysis_i].genomes) !== -1) { + if ($.inArray(data[analysis_i].name, corresponding_analyses) == -1) { + corresponding_analyses.push(data[analysis_i].name); + } + } + } } - }); - } + if (corresponding_analyses.length) { + var ask = confirm("Deleting the genomes " + names + " will delete corresponding analyses:\n" + corresponding_analyses + "\nAre you sure?"); + if (ask) { + deleteGenomes(selected_genomes); + } + } else { + deleteGenomes(selected_genomes); + } + } + }); }); $.ajax({ @@ -273,7 +288,7 @@

Run Analysis

"Authorization": 'Token' + ' ' + getAuthenticationCookie() }, success: function(data) { - var new_row_id = data[data.length - 1].id; + var new_row_id = data[data.length - 1].id; // TODO validate this is correct genome var genomesTable = $("#uploaded-genomes").DataTable(); genomesTable.row.add({ name: up_data.name, id: new_row_id }).draw(); } @@ -349,6 +364,26 @@

Run Analysis

}); } + function deleteGenomes(selected_genomes) { + for (var i = 0; i < selected_genomes.length; i++) { + $.ajax({ + type: "DELETE", + url: genomesUpdateUrl + selected_genomes[i], + headers: { + "Authorization": 'Token' + ' ' + getAuthenticationCookie() + }, + success: function() { + var genomesTable = $("#uploaded-genomes").DataTable(); + genomesTable.row('.selected').remove().draw(); + $("#selected-genomes-field option").remove(); + }, + error: function(message) { + BootstrapDialog.warning(message.responseText); + } + }); + } + } + From 055d64bb7978b69df1b161e1f5d76de266e786a7 Mon Sep 17 00:00:00 2001 From: BeefTron Date: Wed, 14 Jun 2017 17:47:25 -0700 Subject: [PATCH 04/76] Add option to remove analysis on job history page --- web/dist/js/islandcompare-rest-urls.js | 3 ++- web/pages/history.html | 29 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/web/dist/js/islandcompare-rest-urls.js b/web/dist/js/islandcompare-rest-urls.js index 2846a256..84dfd2db 100644 --- a/web/dist/js/islandcompare-rest-urls.js +++ b/web/dist/js/islandcompare-rest-urls.js @@ -9,4 +9,5 @@ var genomesGenesUrl = rootUrl + "genomes/genes/"; var analysisUrl = rootUrl + "analysis/"; var analysisRunUrl = rootUrl + "analysis/run/"; var analysisResultsUrl = rootUrl + "analysis/results/"; -var analysisExportUrl = rootUrl + "analysis/export/"; \ No newline at end of file +var analysisExportUrl = rootUrl + "analysis/export/"; +var analysisDeleteUrl = rootUrl + "analysis/delete/"; \ No newline at end of file diff --git a/web/pages/history.html b/web/pages/history.html index 57348845..c8764ee9 100644 --- a/web/pages/history.html +++ b/web/pages/history.html @@ -33,6 +33,7 @@

Job History

Mash-MCL Status Results Export + Delete @@ -87,6 +88,26 @@

Job History

}); } + function delete_job(jobid) { + var ask = confirm("Are you sure you want to delete analysis " + jobid + "?"); + if (ask) { + $.ajax({ + type: "DELETE", + url: analysisDeleteUrl + jobid, + beforeSend: function (request) { + request.setRequestHeader("Authorization", 'Token'+' '+getAuthenticationCookie()); + }, + success: function(data){ + var jobtable = $("#job-history").DataTable(); + jobtable.row('#' + jobid).remove().draw(); + }, + error: function(message) { + BootstrapDialog.warning(message.responseText); + } + }); + } + } + $(document).ready(function () { jobtable = $("#job-history").DataTable({ ajax: { @@ -190,6 +211,14 @@

Job History

return '