Skip to content

Commit

Permalink
Set deleted attribute of history datasets when purging histories fr…
Browse files Browse the repository at this point in the history
…om grid

Use `history_manager.purge()` which implements that correctly.
Also remove unused `delete()` method of `HistoryController`, last use
removed in PR galaxyproject#4574 .
  • Loading branch information
nsoranzo committed Nov 7, 2019
1 parent 8e4371e commit ec774ab
Showing 1 changed file with 50 additions and 78 deletions.
128 changes: 50 additions & 78 deletions lib/galaxy/webapps/galaxy/controllers/history.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@

from markupsafe import escape
from six import string_types
from sqlalchemy import and_, false, null, true
from sqlalchemy.orm import eagerload, eagerload_all, undefer
from sqlalchemy import (
and_,
false,
null,
true
)
from sqlalchemy.orm import (
eagerload,
eagerload_all,
undefer
)

import galaxy.util
from galaxy import exceptions
Expand All @@ -15,9 +24,19 @@
UsesAnnotations,
UsesItemRatings
)
from galaxy.util import listify, Params, parse_int, sanitize_text
from galaxy.util import (
listify,
Params,
parse_int,
sanitize_text,
unicodify
)
from galaxy.web import url_for
from galaxy.web.framework.helpers import grids, iff, time_ago
from galaxy.web.framework.helpers import (
grids,
iff,
time_ago
)
from galaxy.webapps.base.controller import (
BaseUIController,
ERROR,
Expand Down Expand Up @@ -283,10 +302,7 @@ def list(self, trans, **kwargs):
else:
kwargs['refresh_frames'] = ['history']
elif operation in ("delete", "delete permanently"):
if operation == "delete permanently":
status, message = self._list_delete(trans, histories, purge=True)
else:
status, message = self._list_delete(trans, histories)
status, message = self._list_delete(trans, histories, purge=(operation == "delete permanently"))
if current_history in histories:
# Deleted the current history, so a new, empty history was
# created automatically, and we need to refresh the history frame
Expand All @@ -307,47 +323,26 @@ def _list_delete(self, trans, histories, purge=False):
deleted_current = False
message_parts = []
status = SUCCESS
current_history = trans.get_history()
for history in histories:
if history.users_shared_with:
message_parts.append("History (%s) has been shared with others, unshare it before deleting it. " % history.name)
try:
if history.users_shared_with:
raise exceptions.ObjectAttributeInvalidException(
"History (%s) has been shared with others, unshare it before deleting it." % history.name
)
if purge:
self.history_manager.purge(history)
else:
self.history_manager.delete(history)
if history == current_history:
deleted_current = True
except Exception as e:
message_parts.append(unicodify(e))
status = ERROR
else:
if not history.deleted:
# We'll not eliminate any DefaultHistoryPermissions in case we undelete the history later
history.deleted = True
# If deleting the current history, make a new current.
if history == trans.get_history():
deleted_current = True
trans.log_event("History (%s) marked as deleted" % history.name)
n_deleted += 1
if purge and trans.app.config.allow_user_dataset_purge:
for hda in history.datasets:
if trans.user:
trans.user.adjust_total_disk_usage(-hda.quota_amount(trans.user))
hda.purged = True
trans.sa_session.add(hda)
trans.log_event("HDA id %s has been purged" % hda.id)
trans.sa_session.flush()
if hda.dataset.user_can_purge:
try:
hda.dataset.full_delete()
trans.log_event("Dataset id %s has been purged upon the the purge of HDA id %s" % (hda.dataset.id, hda.id))
trans.sa_session.add(hda.dataset)
except Exception:
log.exception('Unable to purge dataset (%s) on purge of hda (%s):' % (hda.dataset.id, hda.id))
history.purged = True
self.sa_session.add(history)
self.sa_session.flush()
for hda in history.datasets:
# Not all datasets have jobs associated with them (e.g., datasets imported from libraries).
if hda.creating_job_associations:
# HDA has associated job, so try marking it deleted.
job = hda.creating_job_associations[0].job
if job.history_id == history.id and not job.finished:
# No need to check other outputs since the job's parent history is this history
job.mark_deleted(trans.app.config.track_jobs_in_database)
trans.app.job_manager.stop(job)
trans.sa_session.flush()
trans.log_event("History (%s) marked as deleted" % history.name)
n_deleted += 1

if n_deleted:
part = "Deleted %d %s" % (n_deleted, iff(n_deleted != 1, "histories", "history"))
if purge and trans.app.config.allow_user_dataset_purge:
Expand All @@ -356,8 +351,16 @@ def _list_delete(self, trans, histories, purge=False):
part += " but the datasets were not removed from disk because that feature is not enabled in this Galaxy instance"
message_parts.append("%s. " % part)
if deleted_current:
# if this history is the current history for this session,
# - attempt to find the most recently used, undeleted history and switch to it.
# - If no suitable recent history is found, create a new one and switch
# note: this needs to come after commits above or will use an empty history that was deleted above
trans.get_or_create_default_history()
not_deleted_or_purged = [model.History.deleted == false(), model.History.purged == false()]
most_recent_history = self.history_manager.most_recent(user=trans.user, filters=not_deleted_or_purged)
if most_recent_history:
self.history_manager.set_current(trans, most_recent_history)
else:
trans.get_or_create_default_history()
message_parts.append("Your active history was deleted, a new empty history is now active. ")
status = INFO
return (status, " ".join(message_parts))
Expand Down Expand Up @@ -1068,37 +1071,6 @@ def purge_deleted_datasets(self, trans):
return trans.show_ok_message("%d datasets have been deleted permanently" % count, refresh_frames=['history'])
return trans.show_error_message("Cannot purge deleted datasets from this session.")

@web.expose
def delete(self, trans, id, purge=False):
"""Delete the history -- this does not require a logged in user."""
# TODO: use api instead
try:
# get the history with the given id, delete and optionally purge
current_history = self.history_manager.get_current(trans)
history = self.history_manager.get_owned(self.decode_id(id), trans.user, current_history=current_history)
if history.users_shared_with:
raise exceptions.ObjectAttributeInvalidException(
"History has been shared with others. Unshare it before deleting it."
)
self.history_manager.delete(history, flush=(not purge))
if purge:
self.history_manager.purge(history)

# if this history is the current history for this session,
# - attempt to find the most recently used, undeleted history and switch to it.
# - If no suitable recent history is found, create a new one and switch
if history == current_history:
not_deleted_or_purged = [model.History.deleted == false(), model.History.purged == false()]
most_recent_history = self.history_manager.most_recent(user=trans.user, filters=not_deleted_or_purged)
if most_recent_history:
self.history_manager.set_current(trans, most_recent_history)
else:
trans.get_or_create_default_history()

except Exception as exc:
return trans.show_error_message(exc)
return trans.show_ok_message("History deleted", refresh_frames=['history'])

@web.expose
def resume_paused_jobs(self, trans, current=False, ids=None):
"""Resume paused jobs the active history -- this does not require a logged in user."""
Expand Down

0 comments on commit ec774ab

Please sign in to comment.