Trash the media files on refresh, don't just delete them.

This commit is contained in:
Daniel Johnson 2023-12-31 08:23:06 -05:00 committed by Mathieu Comandon
parent 76ecd7ba83
commit c8c6c0c756
4 changed files with 43 additions and 17 deletions

View file

@ -707,7 +707,7 @@ class GameDialogCommon(SavableModelessDialog, DialogInstallUIDelegate):
dialog.destroy()
def on_custom_image_reset_clicked(self, _widget, image_type):
AsyncCall(self.refresh_image, self.image_refreshed_cb, image_type)
self.refresh_image(image_type)
def save_custom_media(self, image_type, image_path, scale_factor):
slug = self.slug or self.game.slug
@ -748,8 +748,17 @@ class GameDialogCommon(SavableModelessDialog, DialogInstallUIDelegate):
service_media = self.service_medias[image_type]
self.game.custom_images.discard(image_type)
service_media.discard_media(slug)
download_lutris_media(slug)
def on_trashed():
AsyncCall(download, self.image_refreshed_cb)
def download():
download_lutris_media(slug)
return image_type
service_media.trash_media(slug,
completion_function=on_trashed)
def refresh_image_cb(self, image_type, error):
return image_type
def image_refreshed_cb(self, image_type, _error):

View file

@ -8,6 +8,7 @@ from lutris.database.services import ServiceGameCollection
from lutris.util import system
from lutris.util.http import HTTPError, download_file
from lutris.util.log import logger
from lutris.util.portals import TrashPortal
def resolve_media_path(possible_paths: List[str]) -> str:
@ -54,6 +55,19 @@ class ServiceMedia:
if os.path.isfile(path):
os.remove(path)
def trash_media(self, slug: str,
completion_function: TrashPortal.CompletionFunction = None,
error_function: TrashPortal.ErrorFunction = None) -> None:
"""Sends each media file for a game to the trash, and invokes callsbacks when this
has been completed or has failed."""
paths = [path for path in self.get_possible_media_paths(slug) if os.path.exists(path)]
if paths:
TrashPortal(paths,
completion_function=completion_function,
error_function=error_function)
elif completion_function:
completion_function()
def get_media_url(self, details):
if self.api_field not in details:
logger.warning("No field '%s' in API game %s", self.api_field, details)

View file

@ -1,5 +1,5 @@
import os
from typing import Callable
from typing import Callable, Iterable
from gi.repository import Gio, GLib, GObject
@ -17,11 +17,11 @@ class TrashPortal(GObject.Object):
CompletionFunction = Callable[[], None]
ErrorFunction = Callable[[Exception], None]
def __init__(self, file_path: str,
def __init__(self, file_paths: Iterable[str],
completion_function: CompletionFunction = None,
error_function: ErrorFunction = None):
super().__init__()
self.file_path = file_path
self.file_paths = list(file_paths)
self.completion_function = completion_function
self.error_function = error_function
Gio.DBusProxy.new_for_bus(
@ -43,15 +43,18 @@ class TrashPortal(GObject.Object):
def trash_file(self):
try:
flags = os.O_RDONLY | os.O_PATH | os.O_CLOEXEC
# You'd think you could use O_NOFOLLOW for any file, but
# I find TrashFile fails. We don't want to trash the link target
# in any case.
if os.path.islink(self.file_path):
flags |= os.O_NOFOLLOW
file_handle = os.open(self.file_path, flags)
fds_in = Gio.UnixFDList.new()
fds_in.append(file_handle)
for file_path in self.file_paths:
flags = os.O_RDONLY | os.O_PATH | os.O_CLOEXEC
# You'd think you could use O_NOFOLLOW for any file, but
# I find TrashFile fails. We don't want to trash the link target
# in any case.
if os.path.islink(file_path):
flags |= os.O_NOFOLLOW
file_handle = os.open(file_path, flags)
fds_in.append(file_handle)
self._dbus_proxy.call_with_unix_fd_list(
"TrashFile",
GLib.Variant.new_tuple(
@ -71,7 +74,7 @@ class TrashPortal(GObject.Object):
if values:
result = values[0]
if result == 0:
self.report_error(RuntimeError("The folder could not be moved to the trash."))
self.report_error(RuntimeError("The item could not be moved to the trash."))
return
self.report_completion()
@ -79,7 +82,7 @@ class TrashPortal(GObject.Object):
if self.error_function:
schedule_at_idle(self.error_function, error)
else:
logger.exception("Failed to trash folder %s: %s", self.file_path, error)
logger.exception("Failed to trash %s: %s", ", ".join(self.file_paths), error)
def report_completion(self):
if self.completion_function:

View file

@ -353,7 +353,7 @@ def remove_folder(path: str,
return
logger.debug("Trashing folder %s", path)
TrashPortal(path,
TrashPortal([path],
completion_function=completion_function,
error_function=error_function)