Fix all pylint warnings for services package

This commit is contained in:
Mathieu Comandon 2020-01-12 19:42:22 -08:00
parent f683964726
commit 8adf835882
10 changed files with 101 additions and 80 deletions

2
debian/copyright vendored
View file

@ -15,7 +15,7 @@ Files: lutris/vendor/gi_composites.py
Copyright: 2015 Dustin Spicuzza <dustin@virtualroadside.com>
License: LGPL-2.1
Files: lutris/services/tosec.py
Files: lutris/vendor/tosec.py
Copyright: 2013 Adrien Plazas
License: GPL-3

View file

@ -287,7 +287,9 @@ class ServiceSyncBox(Gtk.Box):
if self.service.ONLINE and not self.service.is_connected():
return
syncer = self.service.SYNCER()
AsyncCall(syncer.load, self.on_games_loaded, force_reload)
if force_reload:
self.service.SERVICE.wipe_game_cache()
AsyncCall(syncer.load, self.on_games_loaded)
def on_games_loaded(self, result, _error):
self.games = result

39
lutris/services/base.py Normal file
View file

@ -0,0 +1,39 @@
"""Generic service utilities"""
import os
from lutris.util.cookies import WebkitCookieJar
from lutris.util.log import logger
class OnlineService:
"""Base class for online gaming services"""
cookies_path = NotImplemented
cache_path = NotImplemented
@property
def credential_files(self):
"""Return a list of all files used for authentication
"""
return [self.cookies_path]
def is_authenticated(self):
"""Return whether the service is authenticated"""
return all([os.path.exists(path) for path in self.credential_files])
def disconnect(self):
"""Disconnect from the service by removing all credentials"""
for auth_file in self.credential_files + [self.cache_path]:
try:
os.remove(auth_file)
except OSError:
logger.warning("Unable to remove %s", auth_file)
def load_cookies(self):
"""Load cookies from disk"""
logger.debug("Loading cookies from %s", self.cookies_path)
if not os.path.exists(self.cookies_path):
logger.debug("No cookies found, please authenticate first")
return
cookiejar = WebkitCookieJar(self.cookies_path)
cookiejar.load()
return cookiejar

View file

@ -10,10 +10,10 @@ from lutris.services import AuthenticationError, UnavailableGame
from lutris.util.http import Request, HTTPError
from lutris.util import system
from lutris.util.log import logger
from lutris.util.cookies import WebkitCookieJar
from lutris.util.resources import download_media
from lutris.gui.dialogs import WebConnectDialog
from lutris.services.service_game import ServiceGame
from lutris.services.base import OnlineService
NAME = "GOG"
@ -21,7 +21,7 @@ ICON = "gog"
ONLINE = True
class GogService:
class GogService(OnlineService):
"""Service class for GOG"""
name = "GOG"
@ -52,17 +52,6 @@ class GogService:
def credential_files(self):
return [self.cookies_path, self.token_path]
def disconnect(self):
"""Disconnect from GOG by removing all credentials"""
for auth_file in self.credential_files + [self.cache_path]:
try:
os.remove(auth_file)
except OSError:
logger.warning("Unable to remove %s", auth_file)
def is_authenticated(self):
return all([os.path.exists(path) for path in self.credential_files])
def is_available(self):
"""Return whether the user is authenticated and if the service is available"""
if not self.is_authenticated():
@ -106,16 +95,6 @@ class GogService:
with open(self.token_path, "w") as token_file:
token_file.write(json.dumps(token))
def load_cookies(self):
"""Load cookies from disk"""
logger.debug("Loading cookies from %s", self.cookies_path)
if not os.path.exists(self.cookies_path):
logger.debug("No cookies found, please authenticate first")
return
cookiejar = WebkitCookieJar(self.cookies_path)
cookiejar.load()
return cookiejar
def load_token(self):
"""Load token from disk"""
if not os.path.exists(self.token_path):
@ -164,15 +143,20 @@ class GogService:
request.get()
return request.json
def wipe_game_cache(self):
"""Wipe the game cache, allowing it to be reloaded"""
if os.path.exists(self.cache_path):
os.remove(self.cache_path)
def get_user_data(self):
"""Return GOG profile information"""
url = "https://embed.gog.com/userData.json"
return self.make_api_request(url)
def get_library(self, force_reload=False):
def get_library(self):
"""Return the user's library of GOG games"""
if system.path_exists(self.cache_path) and not force_reload:
if system.path_exists(self.cache_path):
logger.debug("Returning cached GOG library")
with open(self.cache_path, "r") as gog_cache:
return json.load(gog_cache)
@ -190,6 +174,7 @@ class GogService:
return games
def get_products_page(self, page=1, search=None):
"""Return a single page of games"""
if not self.is_authenticated():
raise RuntimeError("User is not logged in")
params = {"mediaType": "1"}
@ -221,6 +206,7 @@ class GogService:
class GOGGame(ServiceGame):
"""Representation of a GOG game"""
store = "gog"
@classmethod
@ -249,35 +235,35 @@ class GOGGame(ServiceGame):
return cache_path
GOG_SERVICE = GogService()
SERVICE = GogService()
def is_connected():
"""Return True if user is connected to GOG"""
return GOG_SERVICE.is_available()
return SERVICE.is_available()
def connect(parent=None):
"""Connect to GOG"""
logger.debug("Connecting to GOG")
dialog = WebConnectDialog(GOG_SERVICE, parent)
dialog = WebConnectDialog(SERVICE, parent)
dialog.run()
def disconnect():
"""Disconnect from GOG"""
GOG_SERVICE.disconnect()
SERVICE.disconnect()
class GOGSyncer:
"""Sync GOG games to Lutris"""
@classmethod
def load(cls, force_reload=False):
def load(cls):
"""Load the user game library from the GOG API"""
return [
GOGGame.new_from_gog_game(game)
for game in GOG_SERVICE.get_library(force_reload=force_reload)
for game in SERVICE.get_library()
]
@classmethod

View file

@ -1,3 +1,4 @@
"""Legacy ScummVM 'service', has to be ported to the current architecture"""
import re
import os
from configparser import ConfigParser
@ -36,12 +37,8 @@ def mark_as_installed(scummvm_id, name, path):
return game_id
def mark_as_uninstalled(game_info):
logger.info("Uninstalling %s", game_info["name"])
return pga.add_or_update(id=game_info["id"], installed=0)
def get_scummvm_games():
"""Return the available ScummVM games"""
if not system.path_exists(SCUMMVM_CONFIG_FILE):
logger.info("No ScummVM config found")
return []
@ -58,6 +55,7 @@ def get_scummvm_games():
def sync_with_lutris():
"""Sync the ScummVM games to Lutris"""
scummvm_games = {
game["slug"]: game
for game in pga.get_games_where(
@ -72,4 +70,4 @@ def sync_with_lutris():
if slug not in scummvm_games.keys():
mark_as_installed(scummvm_id, name, path)
for slug in set(scummvm_games.keys()).difference(seen):
mark_as_uninstalled(scummvm_games[slug])
return pga.add_or_update(id=scummvm_games[slug]["id"], installed=0)

View file

@ -29,13 +29,33 @@ class ServiceGame:
"""Returns the ID to use for the lutris config file"""
return self.slug + "-" + self.installer_slug
def install(self):
"""Add an installed game to the library"""
@property
def steamid(self):
"""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"):
return int(self.appid)
return None
def install(self, updated_info=None):
"""Add an installed game to the library
Params:
updated_info (dict): Optional dictonary containing existing data not to overwrite
"""
if updated_info:
name = updated_info["name"]
slug = updated_info["slug"]
else:
name = self.name
slug = self.slug
self.game_id = pga.add_or_update(
id=self.game_id,
name=self.name,
name=name,
runner=self.runner,
slug=self.slug,
slug=slug,
steamid=self.steamid,
installed=1,
configpath=self.config_id,
installer_slug=self.installer_slug,
@ -49,4 +69,3 @@ class ServiceGame:
def create_config(self):
"""Implement this in subclasses to properly create the game config"""
raise NotImplementedError

View file

@ -55,31 +55,6 @@ class SteamGame(ServiceGame):
return False
return True
def install(self, updated_info=None):
"""Add an installed game to the library
Params:
updated_info (dict): Optional dictonary containing existing data not to overwrite
"""
if updated_info:
name = updated_info["name"]
slug = updated_info["slug"]
else:
name = self.name
slug = self.slug
self.game_id = pga.add_or_update(
id=self.game_id,
name=name,
runner=self.runner,
slug=slug,
steamid=int(self.appid),
installed=1,
configpath=self.config_id,
installer_slug=self.installer_slug,
)
self.create_config()
return self.game_id
def create_config(self):
"""Create the game configuration for a Steam game"""
game_config = LutrisConfig(
@ -90,6 +65,7 @@ class SteamGame(ServiceGame):
class SteamSyncer:
"""Sync Steam games to the local library"""
platform = "linux"
def __init__(self):
@ -98,10 +74,12 @@ class SteamSyncer:
@property
def runner(self):
"""Return the appropriate runner for the platform"""
return "steam" if self.platform == "linux" else "winesteam"
@property
def lutris_games(self):
"""Return all Steam games present in the Lutris library"""
if not self._lutris_games:
self._lutris_games = pga.get_games_where(
steamid__isnull=False, steamid__not=""
@ -110,11 +88,12 @@ class SteamSyncer:
@property
def lutris_steamids(self):
"""Return the Steam IDs of the games installed in Lutris"""
if not self._lutris_steamids:
self._lutris_steamids = {str(game["steamid"]) for game in self.lutris_games}
return self._lutris_steamids
def load(self, force_reload=False):
def load(self):
"""Return importable Steam games"""
games = []
steamapps_paths = get_steamapps_paths()

View file

@ -1,3 +1,4 @@
"""Steam for Windows service"""
from lutris.services.steam import SteamSyncer
NAME = "Steam for Windows"
@ -6,6 +7,7 @@ ONLINE = False
class WineSteamSyncer(SteamSyncer):
"""Sync games with Steam for Windows"""
platform = "windows"

View file

@ -126,7 +126,7 @@ class XDGSyncer:
def lutris_games(self):
"""Iterates through Lutris games imported from XDG"""
for game in pga.get_games_where(
runner=XDGGame.runner, installer_slug=XDGGame.installer_slug, installed=1
runner=XDGGame.runner, installer_slug=XDGGame.installer_slug, installed=1
):
yield game
@ -135,15 +135,13 @@ class XDGSyncer:
"""Returns whether a XDG game is importable to Lutris"""
appid = get_appid(app)
executable = app.get_executable() or ""
if any(
[
if any([
app.get_nodisplay() or app.get_is_hidden(), # App is hidden
not executable, # Check app has an executable
appid.startswith("net.lutris"), # Skip lutris created shortcuts
appid.lower() in map(str.lower, cls.ignored_games), # game blacklisted
executable.lower() in cls.ignored_executables, # exe blacklisted
]
):
]):
return False
# must be in Game category
@ -153,18 +151,16 @@ class XDGSyncer:
return False
# contains a blacklisted category
if bool(
[
if bool([
category
for category in categories
if category in map(str.lower, cls.ignored_categories)
]
):
]):
return False
return True
@classmethod
def load(cls, force_reload=False):
def load(cls):
"""Return the list of games stored in the XDG menu."""
return [XDGGame.new_from_xdg_app(app) for app in cls.iter_xdg_games()]