Fix source id being translated
- Additional fix, lutris source db subpath
This commit is contained in:
@@ -105,7 +105,7 @@ class Importer(ErrorProducer):
|
|||||||
manager.reset_cancellable()
|
manager.reset_cancellable()
|
||||||
|
|
||||||
for source in self.sources:
|
for source in self.sources:
|
||||||
logging.debug("Importing games from source %s", source.id)
|
logging.debug("Importing games from source %s", source.source_id)
|
||||||
task = Task.new(None, None, self.source_callback, (source,))
|
task = Task.new(None, None, self.source_callback, (source,))
|
||||||
self.n_source_tasks_created += 1
|
self.n_source_tasks_created += 1
|
||||||
task.set_task_data((source,))
|
task.set_task_data((source,))
|
||||||
@@ -138,16 +138,16 @@ class Importer(ErrorProducer):
|
|||||||
|
|
||||||
# Early exit if not available or not installed
|
# Early exit if not available or not installed
|
||||||
if not source.is_available:
|
if not source.is_available:
|
||||||
logging.info("Source %s skipped, not available", source.id)
|
logging.info("Source %s skipped, not available", source.source_id)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
iterator = iter(source)
|
iterator = iter(source)
|
||||||
except UnresolvableLocationError:
|
except UnresolvableLocationError:
|
||||||
logging.info("Source %s skipped, bad location", source.id)
|
logging.info("Source %s skipped, bad location", source.source_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get games from source
|
# Get games from source
|
||||||
logging.info("Scanning source %s", source.id)
|
logging.info("Scanning source %s", source.source_id)
|
||||||
while True:
|
while True:
|
||||||
# Handle exceptions raised when iterating
|
# Handle exceptions raised when iterating
|
||||||
try:
|
try:
|
||||||
@@ -155,7 +155,7 @@ class Importer(ErrorProducer):
|
|||||||
except StopIteration:
|
except StopIteration:
|
||||||
break
|
break
|
||||||
except Exception as error: # pylint: disable=broad-exception-caught
|
except Exception as error: # pylint: disable=broad-exception-caught
|
||||||
logging.exception("%s in %s", type(error).__name__, source.id)
|
logging.exception("%s in %s", type(error).__name__, source.source_id)
|
||||||
self.report_error(error)
|
self.report_error(error)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ class Importer(ErrorProducer):
|
|||||||
# Should not happen on production code
|
# Should not happen on production code
|
||||||
logging.warning(
|
logging.warning(
|
||||||
"%s produced an invalid iteration return type %s",
|
"%s produced an invalid iteration return type %s",
|
||||||
source.id,
|
source.source_id,
|
||||||
type(iteration_result),
|
type(iteration_result),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
@@ -194,7 +194,7 @@ class Importer(ErrorProducer):
|
|||||||
def source_callback(self, _obj, _result, data):
|
def source_callback(self, _obj, _result, data):
|
||||||
"""Callback executed when a source is fully scanned"""
|
"""Callback executed when a source is fully scanned"""
|
||||||
source, *_rest = data
|
source, *_rest = data
|
||||||
logging.debug("Import done for source %s", source.id)
|
logging.debug("Import done for source %s", source.source_id)
|
||||||
self.n_source_tasks_done += 1
|
self.n_source_tasks_done += 1
|
||||||
self.progress_changed_callback()
|
self.progress_changed_callback()
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class BottlesSourceIterable(SourceIterable):
|
|||||||
for entry in library.values():
|
for entry in library.values():
|
||||||
# Build game
|
# Build game
|
||||||
values = {
|
values = {
|
||||||
"source": self.source.id,
|
"source": self.source.source_id,
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"name": entry["name"],
|
"name": entry["name"],
|
||||||
"game_id": self.source.game_id_format.format(game_id=entry["id"]),
|
"game_id": self.source.game_id_format.format(game_id=entry["id"]),
|
||||||
@@ -84,6 +84,7 @@ class BottlesLocations(NamedTuple):
|
|||||||
class BottlesSource(URLExecutableSource):
|
class BottlesSource(URLExecutableSource):
|
||||||
"""Generic Bottles source"""
|
"""Generic Bottles source"""
|
||||||
|
|
||||||
|
source_id = "bottles"
|
||||||
name = _("Bottles")
|
name = _("Bottles")
|
||||||
iterable_class = BottlesSourceIterable
|
iterable_class = BottlesSourceIterable
|
||||||
url_format = 'bottles:run/"{bottle_name}"/"{game_name}"'
|
url_format = 'bottles:run/"{bottle_name}"/"{game_name}"'
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ class FlatpakSourceIterable(SourceIterable):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
values = {
|
values = {
|
||||||
"source": self.source.id,
|
"source": self.source.source_id,
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"name": name,
|
"name": name,
|
||||||
"game_id": self.source.game_id_format.format(game_id=flatpak_id),
|
"game_id": self.source.game_id_format.format(game_id=flatpak_id),
|
||||||
@@ -119,6 +119,7 @@ class FlatpakLocations(NamedTuple):
|
|||||||
class FlatpakSource(Source):
|
class FlatpakSource(Source):
|
||||||
"""Generic Flatpak source"""
|
"""Generic Flatpak source"""
|
||||||
|
|
||||||
|
source_id = "flatpak"
|
||||||
name = _("Flatpak")
|
name = _("Flatpak")
|
||||||
iterable_class = FlatpakSourceIterable
|
iterable_class = FlatpakSourceIterable
|
||||||
executable_format = "flatpak run {flatpak_id}"
|
executable_format = "flatpak run {flatpak_id}"
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class SubSourceIterable(Iterable):
|
|||||||
|
|
||||||
# Build game
|
# Build game
|
||||||
values = {
|
values = {
|
||||||
"source": f"{self.source.id}_{self.service}",
|
"source": f"{self.source.source_id}_{self.service}",
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"name": entry["title"],
|
"name": entry["title"],
|
||||||
"developer": entry.get("developer", None),
|
"developer": entry.get("developer", None),
|
||||||
@@ -356,6 +356,7 @@ class HeroicLocations(NamedTuple):
|
|||||||
class HeroicSource(URLExecutableSource):
|
class HeroicSource(URLExecutableSource):
|
||||||
"""Generic Heroic Games Launcher source"""
|
"""Generic Heroic Games Launcher source"""
|
||||||
|
|
||||||
|
source_id = "heroic"
|
||||||
name = _("Heroic")
|
name = _("Heroic")
|
||||||
iterable_class = HeroicSourceIterable
|
iterable_class = HeroicSourceIterable
|
||||||
url_format = "heroic://launch/{app_name}"
|
url_format = "heroic://launch/{app_name}"
|
||||||
@@ -384,4 +385,4 @@ class HeroicSource(URLExecutableSource):
|
|||||||
@property
|
@property
|
||||||
def game_id_format(self) -> str:
|
def game_id_format(self) -> str:
|
||||||
"""The string format used to construct game IDs"""
|
"""The string format used to construct game IDs"""
|
||||||
return self.id + "_{service}_{game_id}"
|
return self.source_id + "_{service}_{game_id}"
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class ItchSourceIterable(SourceIterable):
|
|||||||
for row in cursor:
|
for row in cursor:
|
||||||
values = {
|
values = {
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"source": self.source.id,
|
"source": self.source.source_id,
|
||||||
"name": row[1],
|
"name": row[1],
|
||||||
"game_id": self.source.game_id_format.format(game_id=row[0]),
|
"game_id": self.source.game_id_format.format(game_id=row[0]),
|
||||||
"executable": self.source.executable_format.format(cave_id=row[4]),
|
"executable": self.source.executable_format.format(cave_id=row[4]),
|
||||||
@@ -80,6 +80,7 @@ class ItchLocations(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
class ItchSource(URLExecutableSource):
|
class ItchSource(URLExecutableSource):
|
||||||
|
source_id = "itch"
|
||||||
name = _("itch")
|
name = _("itch")
|
||||||
iterable_class = ItchSourceIterable
|
iterable_class = ItchSourceIterable
|
||||||
url_format = "itch://caves/{cave_id}/launch"
|
url_format = "itch://caves/{cave_id}/launch"
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class LegendarySourceIterable(SourceIterable):
|
|||||||
app_name = entry["app_name"]
|
app_name = entry["app_name"]
|
||||||
values = {
|
values = {
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"source": self.source.id,
|
"source": self.source.source_id,
|
||||||
"name": entry["title"],
|
"name": entry["title"],
|
||||||
"game_id": self.source.game_id_format.format(game_id=app_name),
|
"game_id": self.source.game_id_format.format(game_id=app_name),
|
||||||
"executable": self.source.executable_format.format(app_name=app_name),
|
"executable": self.source.executable_format.format(app_name=app_name),
|
||||||
@@ -94,6 +94,7 @@ class LegendaryLocations(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
class LegendarySource(Source):
|
class LegendarySource(Source):
|
||||||
|
source_id = "legendary"
|
||||||
name = _("Legendary")
|
name = _("Legendary")
|
||||||
executable_format = "legendary launch {app_name}"
|
executable_format = "legendary launch {app_name}"
|
||||||
available_on = {"linux"}
|
available_on = {"linux"}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class LutrisSourceIterable(SourceIterable):
|
|||||||
"added": added_time,
|
"added": added_time,
|
||||||
"hidden": row[4],
|
"hidden": row[4],
|
||||||
"name": row[1],
|
"name": row[1],
|
||||||
"source": f"{self.source.id}_{row[3]}",
|
"source": f"{self.source.source_id}_{row[3]}",
|
||||||
"game_id": self.source.game_id_format.format(
|
"game_id": self.source.game_id_format.format(
|
||||||
runner=row[3], game_id=row[0]
|
runner=row[3], game_id=row[0]
|
||||||
),
|
),
|
||||||
@@ -92,6 +92,7 @@ class LutrisLocations(NamedTuple):
|
|||||||
class LutrisSource(URLExecutableSource):
|
class LutrisSource(URLExecutableSource):
|
||||||
"""Generic Lutris source"""
|
"""Generic Lutris source"""
|
||||||
|
|
||||||
|
source_id = "lutris"
|
||||||
name = _("Lutris")
|
name = _("Lutris")
|
||||||
iterable_class = LutrisSourceIterable
|
iterable_class = LutrisSourceIterable
|
||||||
url_format = "lutris:rungameid/{game_id}"
|
url_format = "lutris:rungameid/{game_id}"
|
||||||
@@ -108,7 +109,7 @@ class LutrisSource(URLExecutableSource):
|
|||||||
shared.home / ".local" / "share" / "lutris",
|
shared.home / ".local" / "share" / "lutris",
|
||||||
),
|
),
|
||||||
paths={
|
paths={
|
||||||
"pga.db": (False, "pga.db"),
|
"pga.db": LocationSubPath("pga.db"),
|
||||||
},
|
},
|
||||||
invalid_subtitle=Location.DATA_INVALID_SUBTITLE,
|
invalid_subtitle=Location.DATA_INVALID_SUBTITLE,
|
||||||
),
|
),
|
||||||
@@ -128,4 +129,4 @@ class LutrisSource(URLExecutableSource):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def game_id_format(self):
|
def game_id_format(self):
|
||||||
return self.id + "_{runner}_{game_id}"
|
return self.source_id + "_{runner}_{game_id}"
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class SourceIterable(Iterable):
|
|||||||
class Source(Iterable):
|
class Source(Iterable):
|
||||||
"""Source of games. E.g an installed app with a config file that lists game directories"""
|
"""Source of games. E.g an installed app with a config file that lists game directories"""
|
||||||
|
|
||||||
|
source_id: str
|
||||||
name: str
|
name: str
|
||||||
variant: str = None
|
variant: str = None
|
||||||
available_on: set[str] = set()
|
available_on: set[str] = set()
|
||||||
@@ -65,18 +66,10 @@ class Source(Iterable):
|
|||||||
full_name_ += f" ({self.variant})"
|
full_name_ += f" ({self.variant})"
|
||||||
return full_name_
|
return full_name_
|
||||||
|
|
||||||
@property
|
|
||||||
def id(self) -> str: # pylint: disable=invalid-name
|
|
||||||
"""The source's identifier"""
|
|
||||||
id_ = self.name.lower()
|
|
||||||
if self.variant is not None:
|
|
||||||
id_ += f"_{self.variant.lower()}"
|
|
||||||
return id_
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def game_id_format(self) -> str:
|
def game_id_format(self) -> str:
|
||||||
"""The string format used to construct game IDs"""
|
"""The string format used to construct game IDs"""
|
||||||
return self.id + "_{game_id}"
|
return self.source_id + "_{game_id}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_available(self):
|
def is_available(self):
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class SteamSourceIterable(SourceIterable):
|
|||||||
values = {
|
values = {
|
||||||
"added": added_time,
|
"added": added_time,
|
||||||
"name": local_data["name"],
|
"name": local_data["name"],
|
||||||
"source": self.source.id,
|
"source": self.source.source_id,
|
||||||
"game_id": self.source.game_id_format.format(game_id=appid),
|
"game_id": self.source.game_id_format.format(game_id=appid),
|
||||||
"executable": self.source.executable_format.format(game_id=appid),
|
"executable": self.source.executable_format.format(game_id=appid),
|
||||||
}
|
}
|
||||||
@@ -114,6 +114,7 @@ class SteamLocations(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
class SteamSource(URLExecutableSource):
|
class SteamSource(URLExecutableSource):
|
||||||
|
source_id = "steam"
|
||||||
name = _("Steam")
|
name = _("Steam")
|
||||||
available_on = {"linux", "win32"}
|
available_on = {"linux", "win32"}
|
||||||
iterable_class = SteamSourceIterable
|
iterable_class = SteamSourceIterable
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
):
|
):
|
||||||
source = source_class()
|
source = source_class()
|
||||||
if not source.is_available:
|
if not source.is_available:
|
||||||
expander_row = getattr(self, f"{source.id}_expander_row")
|
expander_row = getattr(self, f"{source.source_id}_expander_row")
|
||||||
expander_row.set_visible(False)
|
expander_row.set_visible(False)
|
||||||
else:
|
else:
|
||||||
self.init_source_row(source)
|
self.init_source_row(source)
|
||||||
@@ -250,12 +250,14 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
"""Set the dir subtitle for a source's action rows"""
|
"""Set the dir subtitle for a source's action rows"""
|
||||||
for location in ("data", "config", "cache"):
|
for location in ("data", "config", "cache"):
|
||||||
# Get the action row to subtitle
|
# Get the action row to subtitle
|
||||||
action_row = getattr(self, f"{source.id}_{location}_action_row", None)
|
action_row = getattr(
|
||||||
|
self, f"{source.source_id}_{location}_action_row", None
|
||||||
|
)
|
||||||
if not action_row:
|
if not action_row:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
infix = "-cache" if location == "cache" else ""
|
infix = "-cache" if location == "cache" else ""
|
||||||
key = f"{source.id}{infix}-location"
|
key = f"{source.source_id}{infix}-location"
|
||||||
path = Path(shared.schema.get_string(key)).expanduser()
|
path = Path(shared.schema.get_string(key)).expanduser()
|
||||||
|
|
||||||
# Remove the path prefix if picked via Flatpak portal
|
# Remove the path prefix if picked via Flatpak portal
|
||||||
@@ -269,7 +271,9 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
label.select_region(-1, -1)
|
label.select_region(-1, -1)
|
||||||
|
|
||||||
for location_name, location in source.locations._asdict().items():
|
for location_name, location in source.locations._asdict().items():
|
||||||
action_row = getattr(self, f"{source.id}_{location_name}_action_row", None)
|
action_row = getattr(
|
||||||
|
self, f"{source.source_id}_{location_name}_action_row", None
|
||||||
|
)
|
||||||
if not action_row:
|
if not action_row:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -311,7 +315,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
menu_button.add_css_class("warning")
|
menu_button.add_css_class("warning")
|
||||||
|
|
||||||
action_row.add_prefix(menu_button)
|
action_row.add_prefix(menu_button)
|
||||||
self.warning_menu_buttons[source.id] = menu_button
|
self.warning_menu_buttons[source.source_id] = menu_button
|
||||||
|
|
||||||
def init_source_row(self, source: Source):
|
def init_source_row(self, source: Source):
|
||||||
"""Initialize a preference row for a source class"""
|
"""Initialize a preference row for a source class"""
|
||||||
@@ -333,18 +337,18 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
infix = ""
|
infix = ""
|
||||||
case _:
|
case _:
|
||||||
infix = f"-{location_name}"
|
infix = f"-{location_name}"
|
||||||
key = f"{source.id}{infix}-location"
|
key = f"{source.source_id}{infix}-location"
|
||||||
value = str(path)
|
value = str(path)
|
||||||
shared.schema.set_string(key, value)
|
shared.schema.set_string(key, value)
|
||||||
# Update the row
|
# Update the row
|
||||||
self.update_source_action_row_paths(source)
|
self.update_source_action_row_paths(source)
|
||||||
|
|
||||||
if self.warning_menu_buttons.get(source.id):
|
if self.warning_menu_buttons.get(source.source_id):
|
||||||
action_row = getattr(
|
action_row = getattr(
|
||||||
self, f"{source.id}_{location_name}_action_row", None
|
self, f"{source.source_id}_{location_name}_action_row", None
|
||||||
)
|
)
|
||||||
action_row.remove(self.warning_menu_buttons[source.id])
|
action_row.remove(self.warning_menu_buttons[source.source_id])
|
||||||
self.warning_menu_buttons.pop(source.id)
|
self.warning_menu_buttons.pop(source.source_id)
|
||||||
|
|
||||||
logging.debug("User-set value for schema key %s: %s", key, value)
|
logging.debug("User-set value for schema key %s: %s", key, value)
|
||||||
|
|
||||||
@@ -366,9 +370,9 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
dialog.connect("response", on_response)
|
dialog.connect("response", on_response)
|
||||||
|
|
||||||
# Bind expander row activation to source being enabled
|
# Bind expander row activation to source being enabled
|
||||||
expander_row = getattr(self, f"{source.id}_expander_row")
|
expander_row = getattr(self, f"{source.source_id}_expander_row")
|
||||||
shared.schema.bind(
|
shared.schema.bind(
|
||||||
source.id,
|
source.source_id,
|
||||||
expander_row,
|
expander_row,
|
||||||
"enable-expansion",
|
"enable-expansion",
|
||||||
Gio.SettingsBindFlags.DEFAULT,
|
Gio.SettingsBindFlags.DEFAULT,
|
||||||
@@ -377,7 +381,7 @@ class PreferencesWindow(Adw.PreferencesWindow):
|
|||||||
# Connect dir picker buttons
|
# Connect dir picker buttons
|
||||||
for location_name in source.locations._asdict():
|
for location_name in source.locations._asdict():
|
||||||
button = getattr(
|
button = getattr(
|
||||||
self, f"{source.id}_{location_name}_file_chooser_button", None
|
self, f"{source.source_id}_{location_name}_file_chooser_button", None
|
||||||
)
|
)
|
||||||
if button is not None:
|
if button is not None:
|
||||||
button.connect("clicked", self.choose_folder, set_dir, location_name)
|
button.connect("clicked", self.choose_folder, set_dir, location_name)
|
||||||
|
|||||||
Reference in New Issue
Block a user