massively simplify deleting something

This commit is contained in:
Michael Hudson-Doyle 2018-07-04 13:56:03 +12:00
parent a8eb32f3cc
commit 7ac7bd86fc
1 changed files with 22 additions and 127 deletions

View File

@ -14,147 +14,44 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from urwid import Text, WidgetDisable
from urwid import Text
from subiquitycore.ui.buttons import danger_btn, other_btn
from subiquitycore.ui.utils import button_pile, Color
from subiquitycore.ui.utils import button_pile
from subiquitycore.ui.stretchy import Stretchy
from subiquity.models.filesystem import (
_Device,
Raid,
raidlevels_by_value,
)
log = logging.getLogger('subiquity.ui.filesystem.disk_info')
def can_delete(obj, obj_desc=_("it")):
if isinstance(obj, _Device):
for p in obj.partitions():
ok, reason = can_delete(
p, obj_desc=_("partition {}").format(p._number))
if not ok:
return False, reason
cd = obj.constructed_device()
if cd is None:
return True, ""
if isinstance(cd, Raid):
rl = raidlevels_by_value[cd.raidlevel]
if len(cd.devices) > rl.min_devices:
return True, ""
else:
reason = _("deleting {obj} would leave the {desc} {label} with "
"less than {min_devices} devices.").format(
obj=_(obj_desc),
desc=cd.desc(),
label=cd.label,
min_devices=rl.min_devices)
return False, reason
else:
raise Exception("unexpected constructed device {}".format(cd.label))
def make_device_remover(cd, obj):
def remover():
cd.devices.remove(obj)
obj._constructed_device = None
return remover
def make_device_deleter(controller, obj):
meth = getattr(controller, 'delete_' + obj.type)
def remover():
meth(obj)
return remover
def delete_consequences(controller, obj, obj_desc=_("It")):
log.debug("building consequences for deleting %s", obj.label)
deleter = (
"delete {} {}".format(obj.type, obj.label),
make_device_deleter(controller, obj),
)
if isinstance(obj, _Device):
if len(obj.partitions()) > 0:
lines = [_("Proceeding will delete the following partitions:"), ""]
delete_funcs = []
for p in obj.partitions():
desc = _("Partition {}, which").format(p._number)
new_lines, new_delete_funcs = delete_consequences(
controller, p, desc)
lines.extend(new_lines)
lines.append("")
delete_funcs.extend(new_delete_funcs)
return lines[:-1], delete_funcs + [deleter]
unused_desc = _("{} is not formatted, partitioned, or part of any "
"constructed device.").format(obj_desc)
else:
unused_desc = _("{} is not formatted or part of any constructed "
"device.").format(obj_desc)
fs = obj.fs()
cd = obj.constructed_device()
if fs is not None:
desc = _("{} is formatted as {}").format(obj_desc, fs.fstype)
if fs.mount():
desc += _(" and mounted at {}.").format(fs.mount().path)
else:
desc += _(" and not mounted.")
return [desc], [deleter]
elif cd is not None:
if isinstance(cd, Raid):
delete_funcs = [(
"remove {} from {}".format(obj.label, cd.name),
make_device_remover(cd, obj),
),
deleter,
]
return [
_("{} is part of the {} {}. {} will be left with {} "
"devices.").format(
obj_desc,
cd.desc(),
cd.label,
cd.label,
len(cd.devices) - 1),
], delete_funcs
else:
raise Exception(
"unexpected constructed device {}".format(cd.label))
else:
return [unused_desc], [deleter]
class ConfirmDeleteStretchy(Stretchy):
def __init__(self, parent, obj):
self.parent = parent
self.obj = obj
delete_ok, reason = can_delete(obj)
if delete_ok:
title = _("Confirm deletion of {}").format(obj.desc())
title = _("Confirm deletion of {}").format(obj.desc())
lines = [
_("Do you really want to delete {}?").format(obj.label),
"",
]
new_lines, delete_funcs = delete_consequences(
self.parent.controller, obj)
lines.extend(new_lines)
self.delete_funcs = delete_funcs
lines = [
_("Do you really want to delete {}?").format(obj.label),
"",
]
fs = obj.fs()
if fs is not None:
m = fs.mount()
if m is not None:
lines.append(_(
"It is formatted as {fstype} and mounted at "
"{path}").format(
fstype=fs.fstype,
path=m.path))
else:
lines.append(_(
"It is formatted as {fstype} and not mounted.").format(
fstype=fs.fstype))
else:
title = "Cannot delete {}".format(obj.desc())
lines = [
_("Cannot delete {} because {}").format(obj.label, reason)]
lines.append(_("It is not formatted or mounted."))
delete_btn = danger_btn(label=_("Delete"), on_press=self.confirm)
if not delete_ok:
delete_btn = WidgetDisable(
Color.info_minor(
delete_btn.original_widget))
widgets = [
Text("\n".join(lines)),
Text(""),
@ -166,9 +63,7 @@ class ConfirmDeleteStretchy(Stretchy):
super().__init__(title, widgets, 0, 2)
def confirm(self, sender=None):
for desc, func in self.delete_funcs:
log.debug("executing delete_func %s", desc)
func()
getattr(self.parent.controller, 'delete_' + self.obj.type)(self.obj)
self.parent.refresh_model_inputs()
self.parent.remove_overlay()