Instead of passing the extra-ids everwhere and hoping it lines up, we pass them to the installer to generate the InstallerFiles, but it provides the extra files separately.
We can then extract the download destination paths for each extra file we're downloading, and we can put those in the script.
This way, if there are more or fewer files than we expect, it will still work.
This may help with #4974, but it's hard to be sure.
The None result from get_cache_path() was leaking into the Preferences dialog, so now it never returns None - there's always ~/.cache/lutris/installer to fall back on, after all. A separate function checks if it is even configured.
Also, the sanity check for whether the custom dir even exists was inconsistently applied and would accept a file; it needs to be a directory. So now it checks with os.path.isdir().
Remove NoScreenDetected; this exception is just an if statement is disguise. We still need to handle GLib.Error though.
Rename ExtractFailure to ExtractError.
Rename AuthTokenExpired to AuthTokenExpiredError, provide a minimal message.
Replace InvalidPid with ValueError with the custom message. This is never caught, and it's misleading - it means the pid given isn't convertible to int, not that it's a valid PID.
Rename UnauthorizedAccess to UnauthorizedAccessError,
Remove FileNotAvailable; it's never used.
Rename MissingDependency to MissingGameDependencyError and ensure it has a message. We do put that message in the logs at least! It should be a LutrisError too.
This is really just an assertion and is pretty useless - we'd crash on the very next line anyway without it.
But for documentation I'll leave a RuntimeError.
This way we need not duplicate the __init__ function in each.
Most are just LutrisError subclasses now, but InvalidRunnerError is a MisconfigurationError. I can't see a bogus runner name coming from anywhere but the configuration.
We use game.runner in many places without checking, so returning None is a bad thing here. Better to raise.
For the few places that check, I've added game.has_runner. Also added a few defensing checks and an exception handler for safety.
What an ugly mess!
queue_draw() on every window does not work on the ListView, though I don't understand why not.
This replaces that with a notification system so that the views can register callbacks to redraw themselves.
I've added a Notification class to tame this beast, in the hope that this will at least be reusable.
Returning False for bad URLS sometimes, but not always, is not sensible.
This commit makes it throw ValueError, which is what the only caller did with the False return anyway.
The trick is that we almost always call it with fixed arguments: get_default_runner_version_info("wine", None).
So, I provide a function to do just that at moving the caching there.
The remaining call to get_default_runner_version_info() is from an install() method that does lots of heavy slow things, so the caching there should not be missed.
The uninstall-game dialog computes folder sizes one at time. With this commit, it updates the UI for each one as it completes, instead of waiting for the whole set to be done.
Looks nicer this way.
Only NO_BIOS gets its own exception class, as its hte only one raised in more than one place. This way we can avoid repeating the message.
elif error == "NO_BIOS":
message_text = _("A bios file is required to run this game")