Create sidebar entries for services

This commit is contained in:
Mathieu Comandon 2020-08-10 00:36:01 -07:00 committed by Mathieu Comandon
parent b3236a99d3
commit f1fb952cfa
6 changed files with 45 additions and 73 deletions

View file

@ -6,7 +6,7 @@ from gettext import gettext as _
from gi.repository import Gdk, Gio, GLib, GObject, Gtk
from lutris import api, settings
from lutris import api, settings, services
from lutris.database import categories as categories_db
from lutris.database import games as games_db
from lutris.game import Game
@ -26,7 +26,6 @@ from lutris.gui.widgets.services import SyncServiceWindow
from lutris.gui.widgets.sidebar import LutrisSidebar
from lutris.gui.widgets.utils import IMAGE_SIZES, open_uri
from lutris.runtime import RuntimeUpdater
from lutris.services import get_services_synced_at_startup
from lutris.sync import sync_from_remote
from lutris.util import datapath, http
from lutris.util.jobs import AsyncCall
@ -230,8 +229,6 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
self.toggle_connection(False)
self.sync_library()
self.sync_services()
def hidden_state_change(self, action, value):
"""Hides or shows the hidden games"""
action.set_state(value)
@ -324,11 +321,17 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
def get_games_from_filters(self):
if "dynamic_category" in self.filters:
category = self.filters["dynamic_category"]
if category.startswith("lutris.services"):
service = services.import_service(category.rsplit(".", 1)[-1])
service_games = service.SYNCER.load()
return [service_game.as_dict() for service_game in service_games]
game_providers = {
"running": self.get_running_games,
"lutrisnet": self.get_api_games,
}
return game_providers[self.filters["dynamic_category"]]()
return game_providers[category]()
if self.filters.get("category"):
game_ids = categories_db.get_game_ids_for_category(self.filters["category"])
return games_db.get_games_by_ids(game_ids)
@ -377,36 +380,6 @@ class LutrisWindow(Gtk.ApplicationWindow): # pylint: disable=too-many-public-me
return self.game_store.update(pga_game)
return self.game_store.remove_game(game_id)
def sync_services(self):
"""Sync local lutris library with current Steam games and desktop games"""
def full_sync(syncer_cls):
syncer = syncer_cls()
games = syncer.load()
return syncer.sync(games, full=True)
def on_sync_complete(response, errors):
"""Callback to update the view on sync complete
XXX: This might go away.
"""
if errors:
logger.error("Sync failed: %s", errors)
return
added_games, removed_games = response
for game_id in added_games:
try:
self.update_game_by_id(game_id)
except ValueError:
self.game_store.add_games(games_db.get_games_by_ids([game_id]))
for game_id in removed_games:
self.update_game_by_id(game_id)
self.sidebar.update()
for service in get_services_synced_at_startup():
AsyncCall(full_sync, on_sync_complete, service.SYNCER)
def set_dark_theme(self):
"""Enables or disbales dark theme"""
gtksettings = Gtk.Settings.get_default()

View file

@ -3,7 +3,7 @@ from gettext import gettext as _
from gi.repository import GObject, Gtk, Pango
from lutris import platforms, runners
from lutris import platforms, runners, services
from lutris.database import categories as categories_db
from lutris.database import games as games_db
from lutris.game import Game
@ -179,6 +179,15 @@ class LutrisSidebar(Gtk.ListBox):
Gtk.Image.new_from_icon_name("lutris", Gtk.IconSize.MENU)
)
)
for service in services.get_services():
self.add(
SidebarRow(
service.__name__,
"dynamic_category",
service.NAME,
Gtk.Image.new_from_icon_name(service.ICON, Gtk.IconSize.MENU)
)
)
all_row = RunnerSidebarRow(None, "runner", _("All"), None)
self.add(all_row)

View file

@ -1,20 +1,16 @@
"""Service package"""
# Standard Library
from importlib import import_module
# Lutris Modules
from lutris.settings import read_setting
__all__ = ["xdg", "gog", "humblebundle", "steam", "winesteam"]
__all__ = ["xdg", "gog", "humblebundle", "steam"]
class AuthenticationError(Exception):
"""Raised when authentication to a service fails"""
class UnavailableGame(Exception):
"""Raised when a game is available from a service"""
@ -26,8 +22,3 @@ def import_service(name):
def get_services():
"""Return a list of active services"""
return [import_service(name) for name in __all__]
def get_services_synced_at_startup():
"""Return services synced at startup"""
return [import_service(name) for name in __all__ if read_setting("sync_at_startup", name) == "True"]

View file

@ -35,7 +35,7 @@ class ServiceGame:
"""Return the SteamID, this is a special case since Steam's appid's are
a field in the game table. Keeping this here allows to reuse the install method.
"""
if hasattr(self, "appid") and hasattr(self, "runner") and "steam" in self.runner:
if hasattr(self, "appid") and self.runner and "steam" in self.runner:
return int(self.appid)
return None
@ -70,3 +70,20 @@ class ServiceGame:
def create_config(self):
"""Implement this in subclasses to properly create the game config"""
def as_dict(self):
"""Return the data in a format compatible with lutris views"""
return {
"id": self.game_id,
"name": self.name,
"slug": self.slug,
"runner": self.runner,
"steamid": self.steamid,
"installed": 1,
"year": None,
"platform": None,
"lastplayed": None,
"installed_at": None,
"playtime": None,
"icon": self.icon,
}

View file

@ -65,9 +65,7 @@ class SteamGame(ServiceGame):
class SteamSyncer:
"""Sync Steam games to the local library"""
platform = "linux"
def __init__(self):
self._lutris_games = None
@ -92,15 +90,17 @@ class SteamSyncer:
self._lutris_steamids = {str(game["steamid"]) for game in self.lutris_games}
return self._lutris_steamids
def load(self):
@classmethod
def load(cls):
"""Return importable Steam games"""
games = []
steamapps_paths = get_steamapps_paths()
for steamapps_path in steamapps_paths[self.platform]:
for appmanifest_file in get_appmanifests(steamapps_path):
app_manifest = AppManifest(os.path.join(steamapps_path, appmanifest_file))
if SteamGame.is_importable(app_manifest):
games.append(SteamGame.new_from_steam_game(app_manifest))
for platform in ('linux', 'windows'):
for steamapps_path in steamapps_paths[platform]:
for appmanifest_file in get_appmanifests(steamapps_path):
app_manifest = AppManifest(os.path.join(steamapps_path, appmanifest_file))
if SteamGame.is_importable(app_manifest):
games.append(SteamGame.new_from_steam_game(app_manifest))
return games
def get_pga_game(self, game):

View file

@ -1,18 +0,0 @@
"""Steam for Windows service"""
from gettext import gettext as _
# Lutris Modules
from lutris.services.steam import SteamSyncer
NAME = _("Steam for Windows")
ICON = "winesteam"
ONLINE = False
class WineSteamSyncer(SteamSyncer):
"""Sync games with Steam for Windows"""
platform = "windows"
SYNCER = WineSteamSyncer