diff --git a/app/api/tasks.py b/app/api/tasks.py index a04e0389..10930569 100644 --- a/app/api/tasks.py +++ b/app/api/tasks.py @@ -153,6 +153,10 @@ class TaskViewSet(viewsets.ViewSet): def remove(self, *args, **kwargs): return self.set_pending_action(pending_actions.REMOVE, *args, perms=('delete_project', ), **kwargs) + @action(detail=True, methods=['post']) + def compact(self, *args, **kwargs): + return self.set_pending_action(pending_actions.COMPACT, *args, perms=('delete_project', ), **kwargs) + @action(detail=True, methods=['get']) def output(self, request, pk=None, project_pk=None): """ diff --git a/app/models/task.py b/app/models/task.py index 72529f65..c84f1b1b 100644 --- a/app/models/task.py +++ b/app/models/task.py @@ -235,6 +235,7 @@ class Task(models.Model): (pending_actions.RESTART, 'RESTART'), (pending_actions.RESIZE, 'RESIZE'), (pending_actions.IMPORT, 'IMPORT'), + (pending_actions.COMPACT, 'COMPACT'), ) TASK_PROGRESS_LAST_VALUE = 0.85 @@ -807,6 +808,14 @@ class Task(models.Model): # Stop right here! return + + elif self.pending_action == pending_actions.COMPACT: + logger.info("Compacting {}".format(self)) + time.sleep(2) # Purely to make sure the user sees the "compacting..." message in the UI since this is so fast + self.compact() + self.pending_action = None + self.save() + return if self.processing_node: # Need to update status (first time, queued or running?) @@ -1142,6 +1151,18 @@ class Task(models.Model): plugin_signals.task_removed.send_robust(sender=self.__class__, task_id=task_id) + def compact(self): + # Remove all images + images_path = self.task_path() + images = [os.path.join(images_path, i) for i in self.scan_images()] + for im in images: + try: + os.unlink(im) + except Exception as e: + logger.warning(e) + + self.update_size(commit=True) + def set_failure(self, error_message): logger.error("FAILURE FOR {}: {}".format(self, error_message)) self.last_error = error_message @@ -1157,7 +1178,8 @@ class Task(models.Model): def check_if_canceled(self): # Check if task has been canceled/removed if Task.objects.only("pending_action").get(pk=self.id).pending_action in [pending_actions.CANCEL, - pending_actions.REMOVE]: + pending_actions.REMOVE, + pending_actions.COMPACT]: raise TaskInterruptedException() def resize_images(self): diff --git a/app/pending_actions.py b/app/pending_actions.py index c7f02532..df21044c 100644 --- a/app/pending_actions.py +++ b/app/pending_actions.py @@ -3,3 +3,4 @@ REMOVE = 2 RESTART = 3 RESIZE = 4 IMPORT = 5 +COMPACT = 6 diff --git a/app/static/app/js/classes/PendingActions.js b/app/static/app/js/classes/PendingActions.js index 2b89fb04..a059151f 100644 --- a/app/static/app/js/classes/PendingActions.js +++ b/app/static/app/js/classes/PendingActions.js @@ -4,7 +4,8 @@ const CANCEL = 1, REMOVE = 2, RESTART = 3, RESIZE = 4, - IMPORT = 5; + IMPORT = 5, + COMPACT = 6; let pendingActions = { [CANCEL]: { @@ -21,6 +22,9 @@ let pendingActions = { }, [IMPORT]: { descr: _("Importing...") + }, + [COMPACT]: { + descr: _("Compacting...") } }; @@ -30,6 +34,7 @@ export default { RESTART: RESTART, RESIZE: RESIZE, IMPORT: IMPORT, + COMPACT: COMPACT, description: function(pendingAction) { if (pendingActions[pendingAction]) return pendingActions[pendingAction].descr; diff --git a/app/static/app/js/components/NewTaskPanel.jsx b/app/static/app/js/components/NewTaskPanel.jsx index 0c9189fc..a8900cfc 100644 --- a/app/static/app/js/components/NewTaskPanel.jsx +++ b/app/static/app/js/components/NewTaskPanel.jsx @@ -239,7 +239,7 @@ class NewTaskPanel extends React.Component { ref={(domNode) => { if (domNode) this.taskForm = domNode; }} /> - {this.state.editTaskFormLoaded && this.props.showAlign && this.state.showMapPreview ? + {this.state.editTaskFormLoaded && this.props.showAlign && this.state.showMapPreview && this.state.alignTasks.length > 0 ?