mirror of
https://github.com/lutris/lutris
synced 2024-09-04 23:13:35 +00:00
- Fixed instances of unspecified-encoding, super-with-arguments, raise-missing-from, consider-using-dict-items, consider-iterating-dictionary
- Refactored connect() from api.py to use requests
This commit is contained in:
parent
f5e8e007b3
commit
7cff0a0301
|
@ -2,11 +2,12 @@
|
|||
import json
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
import requests
|
||||
|
||||
from lutris import settings
|
||||
from lutris.util import http, system
|
||||
from lutris.util.log import logger
|
||||
|
@ -20,7 +21,7 @@ def read_api_key():
|
|||
"""Read the API token from disk"""
|
||||
if not system.path_exists(API_KEY_FILE_PATH):
|
||||
return None
|
||||
with open(API_KEY_FILE_PATH, "r") as token_file:
|
||||
with open(API_KEY_FILE_PATH, "r", encoding='utf-8') as token_file:
|
||||
api_string = token_file.read()
|
||||
try:
|
||||
username, token = api_string.split(":")
|
||||
|
@ -32,21 +33,22 @@ def read_api_key():
|
|||
|
||||
def connect(username, password):
|
||||
"""Connect to the Lutris API"""
|
||||
credentials = urllib.parse.urlencode({"username": username, "password": password}).encode("utf-8")
|
||||
login_url = settings.SITE_URL + "/api/accounts/token"
|
||||
credentials = {"username": username, "password": password}
|
||||
try:
|
||||
request = urllib.request.urlopen(login_url, credentials, 10)
|
||||
except (socket.timeout, urllib.error.URLError) as ex:
|
||||
response = requests.post(url=login_url, data=credentials, timeout=10)
|
||||
response.raise_for_status()
|
||||
json_dict = response.json()
|
||||
if "token" in json_dict:
|
||||
token = json_dict["token"]
|
||||
with open(API_KEY_FILE_PATH, "w", encoding='utf-8') as token_file:
|
||||
token_file.write(f"{username}:{token}")
|
||||
get_user_info()
|
||||
return token
|
||||
except (requests.RequestException, requests.ConnectionError, requests.HTTPError, requests.TooManyRedirects,
|
||||
requests.Timeout) as ex:
|
||||
logger.error("Unable to connect to server (%s): %s", login_url, ex)
|
||||
return False
|
||||
response = json.loads(request.read().decode())
|
||||
if "token" in response:
|
||||
token = response["token"]
|
||||
with open(API_KEY_FILE_PATH, "w") as token_file:
|
||||
token_file.write(":".join((username, token)))
|
||||
get_user_info()
|
||||
return response["token"]
|
||||
return False
|
||||
|
||||
|
||||
def disconnect():
|
||||
|
@ -67,7 +69,7 @@ def get_user_info():
|
|||
account_info = response.json
|
||||
if not account_info:
|
||||
logger.warning("Unable to fetch user info for %s", credentials["username"])
|
||||
with open(USER_INFO_FILE_PATH, "w") as token_file:
|
||||
with open(USER_INFO_FILE_PATH, "w", encoding='utf-8') as token_file:
|
||||
json.dump(account_info, token_file, indent=2)
|
||||
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ class MonitoredCommand:
|
|||
"""Get the return code from the file written by the wrapper"""
|
||||
return_code_path = "/tmp/lutris-%s" % self.env["LUTRIS_GAME_UUID"]
|
||||
if os.path.exists(return_code_path):
|
||||
with open(return_code_path) as return_code_file:
|
||||
with open(return_code_path, encoding='utf-8') as return_code_file:
|
||||
return_code = return_code_file.read()
|
||||
os.unlink(return_code_path)
|
||||
else:
|
||||
|
|
|
@ -22,7 +22,7 @@ def write_game_config(game_slug, config):
|
|||
configpath = make_game_config_id(game_slug)
|
||||
config_filename = os.path.join(settings.CONFIG_DIR, "games/%s.yml" % configpath)
|
||||
yaml_config = yaml.safe_dump(config, default_flow_style=False)
|
||||
with open(config_filename, "w") as config_file:
|
||||
with open(config_filename, "w", encoding='utf-8') as config_file:
|
||||
logger.debug("Writing game config to %s", config_filename)
|
||||
config_file.write(yaml_config)
|
||||
return configpath
|
||||
|
|
|
@ -222,5 +222,5 @@ def migrate(table, schema):
|
|||
def syncdb():
|
||||
"""Update the database to the current version, making necessary changes
|
||||
for backwards compatibility."""
|
||||
for table in DATABASE:
|
||||
migrate(table, DATABASE[table])
|
||||
for table_name, table_data in DATABASE.items():
|
||||
migrate(table_name, table_data)
|
||||
|
|
|
@ -694,13 +694,13 @@ class Game(GObject.Object):
|
|||
logger.info("Previous location wasn't set. Cannot continue moving")
|
||||
return target_directory
|
||||
|
||||
with open(self.config.game_config_path) as config_file:
|
||||
with open(self.config.game_config_path, encoding='utf-8') as config_file:
|
||||
for line in config_file.readlines():
|
||||
if target_directory in line:
|
||||
new_config += line
|
||||
else:
|
||||
new_config += line.replace(old_location, target_directory)
|
||||
with open(self.config.game_config_path, "w") as config_file:
|
||||
with open(self.config.game_config_path, "w", encoding='utf-8') as config_file:
|
||||
config_file.write(new_config)
|
||||
|
||||
if not system.path_exists(old_location):
|
||||
|
|
|
@ -84,7 +84,7 @@ class IssueReportWindow(BaseApplicationWindow):
|
|||
return
|
||||
issue_path = os.path.join(target_path, "lutris-issue-report.json")
|
||||
issue_info = self.get_issue_info()
|
||||
with open(issue_path, "w") as issue_file:
|
||||
with open(issue_path, "w", encoding='utf-8') as issue_file:
|
||||
json.dump(issue_info, issue_file, indent=2)
|
||||
dialog.destroy()
|
||||
NoticeDialog(_("Issue saved in %s") % issue_path)
|
||||
|
|
|
@ -64,5 +64,5 @@ class LogWindow(GObject.Object):
|
|||
self.buffer.get_end_iter(),
|
||||
True
|
||||
)
|
||||
with open(log_path, "w") as log_file:
|
||||
with open(log_path, "w", encoding='utf-8') as log_file:
|
||||
log_file.write(text)
|
||||
|
|
|
@ -85,7 +85,7 @@ class WebPopupDialog(Dialog):
|
|||
def __init__(self, webview, parent=None):
|
||||
# pylint: disable=no-member
|
||||
self.parent = parent
|
||||
super(WebPopupDialog, self).__init__(title=_('Loading...'), parent=parent)
|
||||
super().__init__(title=_('Loading...'), parent=parent)
|
||||
self.webview = webview
|
||||
self.webview.connect("ready-to-show", self.on_ready_webview)
|
||||
self.webview.connect("notify::title", self.on_available_webview_title)
|
||||
|
|
|
@ -39,15 +39,15 @@ class InstallerFilesBox(Gtk.ListBox):
|
|||
"""Iterates through installer files while keeping the number
|
||||
of simultaneously downloaded files down to a maximum number"""
|
||||
started_downloads = 0
|
||||
for file_id in self.installer_files_boxes:
|
||||
if self.installer_files_boxes[file_id].provider == "download":
|
||||
for file_id, file_entry in self.installer_files_boxes.items():
|
||||
if file_entry.provider == "download":
|
||||
started_downloads += 1
|
||||
if started_downloads <= self.max_downloads:
|
||||
self.installer_files_boxes[file_id].start()
|
||||
file_entry.start()
|
||||
else:
|
||||
self._file_queue.append(file_id)
|
||||
else:
|
||||
self.installer_files_boxes[file_id].start()
|
||||
file_entry.start()
|
||||
|
||||
def stop_all(self):
|
||||
"""Stops all ongoing files gathering.
|
||||
|
|
|
@ -293,7 +293,7 @@ class InstallerWindow(BaseApplicationWindow): # pylint: disable=too-many-public
|
|||
try:
|
||||
self.interpreter.installer.prepare_game_files()
|
||||
except UnavailableGame as ex:
|
||||
raise ScriptingError(str(ex))
|
||||
raise ScriptingError(str(ex)) from ex
|
||||
|
||||
if not self.interpreter.installer.files:
|
||||
logger.debug("Installer doesn't require files")
|
||||
|
@ -407,7 +407,7 @@ class InstallerWindow(BaseApplicationWindow): # pylint: disable=too-many-public
|
|||
self.continue_button.disconnect(self.continue_handler)
|
||||
except PermissionError as ex:
|
||||
self.continue_button.set_sensitive(True)
|
||||
raise ScriptingError("Unable to get files: %s" % ex)
|
||||
raise ScriptingError("Unable to get files: %s" % ex) from ex
|
||||
|
||||
def on_files_available(self, widget):
|
||||
"""All files are available, continue the install"""
|
||||
|
|
|
@ -5,7 +5,7 @@ class GridViewCellRendererText(Gtk.CellRendererText):
|
|||
"""CellRendererText adjusted for grid view display, removes extra padding"""
|
||||
|
||||
def __init__(self, width, *args, **kwargs):
|
||||
super(GridViewCellRendererText, self).__init__(*args, **kwargs)
|
||||
super().__init__(*args, **kwargs)
|
||||
self.props.alignment = Pango.Alignment.CENTER
|
||||
self.props.wrap_mode = Pango.WrapMode.WORD
|
||||
self.props.xalign = 0.5
|
||||
|
|
|
@ -35,7 +35,7 @@ def fetch_script(game_slug, revision=None):
|
|||
def read_script(filename):
|
||||
"""Return scripts from a local file"""
|
||||
logger.debug("Loading script(s) from %s", filename)
|
||||
script = yaml.safe_load(open(filename, "r").read())
|
||||
script = yaml.safe_load(open(filename, "r", encoding='utf-8').read())
|
||||
if isinstance(script, list):
|
||||
return script
|
||||
if "results" in script:
|
||||
|
|
|
@ -297,8 +297,8 @@ class CommandsMixin:
|
|||
else:
|
||||
action = shutil.move
|
||||
self._killable_process(action, src, dst)
|
||||
except shutil.Error:
|
||||
raise ScriptingError("Can't move %s \nto destination %s" % (src, dst))
|
||||
except shutil.Error as err:
|
||||
raise ScriptingError("Can't move %s \nto destination %s" % (src, dst)) from err
|
||||
|
||||
def rename(self, params):
|
||||
"""Rename file or folder."""
|
||||
|
@ -327,8 +327,8 @@ class CommandsMixin:
|
|||
"""Process raw 'src' and 'dst' data."""
|
||||
try:
|
||||
src_ref = params["src"]
|
||||
except KeyError:
|
||||
raise ScriptingError("Missing parameter src")
|
||||
except KeyError as err:
|
||||
raise ScriptingError("Missing parameter src") from err
|
||||
src = self.game_files.get(src_ref) or self._substitute(src_ref)
|
||||
if not src:
|
||||
raise ScriptingError("Wrong value for 'src' param", src_ref)
|
||||
|
@ -344,8 +344,8 @@ class CommandsMixin:
|
|||
filename = self._substitute(data["file"])
|
||||
logger.debug("Substituting variables for file %s", filename)
|
||||
tmp_filename = filename + ".tmp"
|
||||
with open(filename, "r") as source_file:
|
||||
with open(tmp_filename, "w") as dest_file:
|
||||
with open(filename, "r", encoding='utf-8') as source_file:
|
||||
with open(tmp_filename, "w", encoding='utf-8') as dest_file:
|
||||
line = "."
|
||||
while line:
|
||||
line = source_file.readline()
|
||||
|
@ -438,7 +438,7 @@ class CommandsMixin:
|
|||
if not mode.startswith(("a", "w")):
|
||||
raise ScriptingError("Wrong value for write_file mode: '%s'" % mode)
|
||||
|
||||
with open(dest_file_path, mode) as dest_file:
|
||||
with open(dest_file_path, mode, encoding='utf-8') as dest_file:
|
||||
dest_file.write(self._substitute(params["content"]))
|
||||
|
||||
def write_json(self, params):
|
||||
|
@ -457,10 +457,10 @@ class CommandsMixin:
|
|||
|
||||
if not os.path.exists(filename):
|
||||
# create an empty file
|
||||
with open(filename, "a+"):
|
||||
with open(filename, "a+", encoding='utf-8'):
|
||||
pass
|
||||
|
||||
with open(filename, "r+" if merge else "w") as json_file:
|
||||
with open(filename, "r+" if merge else "w", encoding='utf-8') as json_file:
|
||||
json_data = {}
|
||||
if merge:
|
||||
try:
|
||||
|
@ -546,7 +546,7 @@ class CommandsMixin:
|
|||
|
||||
def _get_scummvm_arguments(self, gog_config_path):
|
||||
"""Return a ScummVM configuration from the GOG config files"""
|
||||
with open(gog_config_path) as gog_config_file:
|
||||
with open(gog_config_path, encoding='utf-8') as gog_config_file:
|
||||
gog_config = json.loads(gog_config_file.read())
|
||||
game_tasks = [task for task in gog_config["playTasks"] if task["category"] == "game"]
|
||||
arguments = game_tasks[0]["arguments"]
|
||||
|
|
|
@ -14,7 +14,7 @@ class ScriptingError(Exception):
|
|||
def __init__(self, message, faulty_data=None):
|
||||
self.message = message
|
||||
self.faulty_data = faulty_data
|
||||
super(ScriptingError, self).__init__()
|
||||
super().__init__()
|
||||
logger.error(self.__str__())
|
||||
|
||||
def __str__(self):
|
||||
|
|
|
@ -202,8 +202,8 @@ class LutrisInstaller: # pylint: disable=too-many-instance-attributes
|
|||
if "game" in self.script:
|
||||
try:
|
||||
config["game"].update(self.script["game"])
|
||||
except ValueError:
|
||||
raise ScriptingError("Invalid 'game' section", self.script["game"])
|
||||
except ValueError as err:
|
||||
raise ScriptingError("Invalid 'game' section", self.script["game"]) from err
|
||||
config["game"] = self._substitute_config(config["game"])
|
||||
if AUTO_ELF_EXE in config["game"].get("exe", ""):
|
||||
config["game"]["exe"] = find_linux_game_executable(self.interpreter.target_path,
|
||||
|
|
|
@ -173,8 +173,8 @@ class InstallerFile:
|
|||
return
|
||||
try:
|
||||
hash_type, expected_hash = self.checksum.split(':', 1)
|
||||
except ValueError:
|
||||
raise ScriptingError("Invalid checksum, expected format (type:hash) ", self.checksum)
|
||||
except ValueError as err:
|
||||
raise ScriptingError("Invalid checksum, expected format (type:hash) ", self.checksum) from err
|
||||
|
||||
if system.get_file_checksum(self.dest_file, hash_type) != expected_hash:
|
||||
raise ScriptingError(hash_type.capitalize() + " checksum mismatch ", self.checksum)
|
||||
|
|
|
@ -173,11 +173,11 @@ class ScriptInterpreter(GObject.Object, CommandsMixin):
|
|||
logger.debug("Creating destination path %s", self.target_path)
|
||||
os.makedirs(self.target_path)
|
||||
self.game_dir_created = True
|
||||
except PermissionError:
|
||||
except PermissionError as err:
|
||||
raise ScriptingError(
|
||||
"Lutris does not have the necessary permissions to install to path:",
|
||||
self.target_path,
|
||||
)
|
||||
) from err
|
||||
|
||||
def get_runners_to_install(self):
|
||||
"""Check if the runner is installed before starting the installation
|
||||
|
@ -251,15 +251,15 @@ class ScriptInterpreter(GObject.Object, CommandsMixin):
|
|||
)
|
||||
except (NonInstallableRunnerError, RunnerInstallationError) as ex:
|
||||
logger.error(ex.message)
|
||||
raise ScriptingError(ex.message)
|
||||
raise ScriptingError(ex.message) from ex
|
||||
|
||||
def get_runner_class(self, runner_name):
|
||||
"""Runner the runner class from its name"""
|
||||
try:
|
||||
runner = import_runner(runner_name)
|
||||
except InvalidRunner:
|
||||
except InvalidRunner as err:
|
||||
GLib.idle_add(self.parent.cancel_button.set_sensitive, True)
|
||||
raise ScriptingError("Invalid runner provided %s" % runner_name)
|
||||
raise ScriptingError("Invalid runner provided %s" % runner_name) from err
|
||||
return runner
|
||||
|
||||
def launch_installer_commands(self):
|
||||
|
@ -290,8 +290,8 @@ class ScriptInterpreter(GObject.Object, CommandsMixin):
|
|||
elif self.current_command < len(commands):
|
||||
try:
|
||||
command = commands[self.current_command]
|
||||
except KeyError:
|
||||
raise ScriptingError("Installer commands are not formatted correctly")
|
||||
except KeyError as err:
|
||||
raise ScriptingError("Installer commands are not formatted correctly") from err
|
||||
self.current_command += 1
|
||||
method, params = self._map_command(command)
|
||||
if isinstance(params, dict):
|
||||
|
|
|
@ -42,8 +42,8 @@ class SteamInstaller(GObject.Object):
|
|||
self.file_id = file_id
|
||||
try:
|
||||
_steam, appid, path = self.steam_uri.split(":", 2)
|
||||
except ValueError:
|
||||
raise ScriptingError("Malformed steam path: %s" % self.steam_uri)
|
||||
except ValueError as err:
|
||||
raise ScriptingError("Malformed steam path: %s" % self.steam_uri) from err
|
||||
|
||||
self.appid = appid
|
||||
self.path = path
|
||||
|
|
|
@ -132,11 +132,11 @@ def export_bash_script(runner, gameplay_info, script_path):
|
|||
env["TERM"] = "xterm"
|
||||
script_content = "#!/bin/bash\n\n\n"
|
||||
script_content += "# Environment variables\n"
|
||||
for env_var in env:
|
||||
script_content += "export %s=\"%s\"\n" % (env_var, env[env_var])
|
||||
for name, value in env.items():
|
||||
script_content += f'export {name}="{value}"\n'
|
||||
script_content += "\n# Command\n"
|
||||
script_content += " ".join([shlex.quote(c) for c in command])
|
||||
with open(script_path, "w") as script_file:
|
||||
with open(script_path, "w", encoding='utf-8') as script_file:
|
||||
script_file.write(script_content)
|
||||
|
||||
os.chmod(script_path, os.stat(script_path).st_mode | stat.S_IEXEC)
|
||||
|
|
|
@ -111,7 +111,7 @@ class atari800(Runner):
|
|||
if callback:
|
||||
callback()
|
||||
|
||||
super(atari800, self).install(version, downloader, on_runner_installed)
|
||||
super().install(version, downloader, on_runner_installed)
|
||||
|
||||
def find_good_bioses(self, bios_path):
|
||||
""" Check for correct bios files """
|
||||
|
|
|
@ -41,7 +41,7 @@ def dosexec(config_file=None, executable=None, args=None, close_on_exit=True, wo
|
|||
|
||||
def makeconfig(path, drives, commands):
|
||||
system.create_folder(os.path.dirname(path))
|
||||
with open(path, "w") as config_file:
|
||||
with open(path, "w", encoding='utf-8') as config_file:
|
||||
config_file.write("[autoexec]\n")
|
||||
for drive in drives:
|
||||
config_file.write('mount {} "{}"\n'.format(drive, drives[drive]))
|
||||
|
|
|
@ -42,7 +42,7 @@ def set_regedit(
|
|||
}
|
||||
# Make temporary reg file
|
||||
reg_path = os.path.join(settings.CACHE_DIR, "winekeys.reg")
|
||||
with open(reg_path, "w") as reg_file:
|
||||
with open(reg_path, "w", encoding='utf-8') as reg_file:
|
||||
reg_file.write('REGEDIT4\n\n[%s]\n"%s"=%s\n' % (path, key, formatted_value[type]))
|
||||
logger.debug("Setting [%s]:%s=%s", path, key, formatted_value[type])
|
||||
set_regedit_file(reg_path, wine_path=wine_path, prefix=prefix, arch=arch)
|
||||
|
|
|
@ -131,7 +131,7 @@ class dosbox(Runner):
|
|||
return os.path.expanduser(option)
|
||||
if self.main_file:
|
||||
return os.path.dirname(self.main_file)
|
||||
return super(dosbox, self).working_dir
|
||||
return super().working_dir
|
||||
|
||||
def play(self):
|
||||
main_file = self.main_file
|
||||
|
|
|
@ -151,7 +151,7 @@ class hatari(Runner):
|
|||
if callback:
|
||||
callback()
|
||||
|
||||
super(hatari, self).install(version=version, downloader=downloader, callback=on_runner_installed)
|
||||
super().install(version=version, downloader=downloader, callback=on_runner_installed)
|
||||
|
||||
def play(self): # pylint: disable=too-many-branches
|
||||
params = [self.get_executable()]
|
||||
|
|
|
@ -19,7 +19,7 @@ class JsonRunner(Runner):
|
|||
super().__init__(config)
|
||||
if not self.json_path:
|
||||
raise RuntimeError("Create subclasses of JsonRunner with the json_path attribute set")
|
||||
with open(self.json_path) as json_file:
|
||||
with open(self.json_path, encoding='utf-8') as json_file:
|
||||
self._json_data = json.load(json_file)
|
||||
|
||||
self.game_options = self._json_data["game_options"]
|
||||
|
|
|
@ -140,12 +140,12 @@ class libretro(Runner):
|
|||
if callback:
|
||||
callback()
|
||||
else:
|
||||
super(libretro, self).install(version, downloader, callback)
|
||||
super().install(version, downloader, callback)
|
||||
|
||||
if not self.is_retroarch_installed():
|
||||
super(libretro, self).install(version=None, downloader=downloader, callback=install_core)
|
||||
super().install(version=None, downloader=downloader, callback=install_core)
|
||||
else:
|
||||
super(libretro, self).install(version, downloader, callback)
|
||||
super().install(version, downloader, callback)
|
||||
|
||||
def get_run_data(self):
|
||||
return {
|
||||
|
@ -170,7 +170,7 @@ class libretro(Runner):
|
|||
# TODO: review later
|
||||
# Create retroarch.cfg if it doesn't exist.
|
||||
if not system.path_exists(config_file):
|
||||
f = open(config_file, "w")
|
||||
f = open(config_file, "w", encoding='utf-8')
|
||||
f.write("# Lutris RetroArch Configuration")
|
||||
f.close()
|
||||
|
||||
|
@ -281,11 +281,11 @@ class libretro(Runner):
|
|||
# Checks whether the retroarch or libretro directories can be uninstalled.
|
||||
def can_uninstall(self):
|
||||
retroarch_path = os.path.join(settings.RUNNER_DIR, 'retroarch')
|
||||
return os.path.isdir(retroarch_path) or super(libretro, self).can_uninstall()
|
||||
return os.path.isdir(retroarch_path) or super().can_uninstall()
|
||||
|
||||
# Remove the `retroarch` directory.
|
||||
def uninstall(self):
|
||||
retroarch_path = os.path.join(settings.RUNNER_DIR, 'retroarch')
|
||||
if os.path.isdir(retroarch_path):
|
||||
system.remove_folder(retroarch_path)
|
||||
super(libretro, self).uninstall()
|
||||
super().uninstall()
|
||||
|
|
|
@ -69,7 +69,7 @@ class linux(Runner):
|
|||
]
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(linux, self).__init__(config)
|
||||
super().__init__(config)
|
||||
self.ld_preload = None
|
||||
|
||||
@property
|
||||
|
@ -104,7 +104,7 @@ class linux(Runner):
|
|||
return os.path.expanduser(option)
|
||||
if self.game_exe:
|
||||
return os.path.dirname(self.game_exe)
|
||||
return super(linux, self).working_dir
|
||||
return super().working_dir
|
||||
|
||||
def is_installed(self):
|
||||
"""Well of course Linux is installed, you're using Linux right ?"""
|
||||
|
|
|
@ -247,7 +247,7 @@ class mame(Runner): # pylint: disable=invalid-name
|
|||
env=runtime.get_env()
|
||||
)
|
||||
if output:
|
||||
with open(self.xml_path, "w") as xml_file:
|
||||
with open(self.xml_path, "w", encoding='utf-8') as xml_file:
|
||||
xml_file.write(output)
|
||||
logger.info("MAME XML list written to %s", self.xml_path)
|
||||
else:
|
||||
|
|
|
@ -101,7 +101,7 @@ class o2em(Runner):
|
|||
if callback:
|
||||
callback()
|
||||
|
||||
super(o2em, self).install(version, downloader, on_runner_installed)
|
||||
super().install(version, downloader, on_runner_installed)
|
||||
|
||||
def play(self):
|
||||
arguments = ["-biosdir=%s" % self.bios_path]
|
||||
|
|
|
@ -74,7 +74,7 @@ class pico8(Runner):
|
|||
runner_executable = "pico8/web.py"
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(pico8, self).__init__(config)
|
||||
super().__init__(config)
|
||||
|
||||
self.runnable_alone = self.is_native
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ class redream(Runner):
|
|||
license_filename, os.path.join(settings.RUNNER_DIR, "redream")
|
||||
)
|
||||
|
||||
super(redream, self).install(
|
||||
super().install(
|
||||
version=version, downloader=downloader, callback=on_runner_installed
|
||||
)
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class reicast(Runner):
|
|||
]
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(reicast, self).__init__(config)
|
||||
super().__init__(config)
|
||||
|
||||
self.runner_options = [
|
||||
{
|
||||
|
@ -83,7 +83,7 @@ class reicast(Runner):
|
|||
system.create_folder("~/.reicast/data")
|
||||
NoticeDialog(_("You have to copy valid BIOS files to ~/.reicast/data before playing"))
|
||||
|
||||
super(reicast, self).install(version, downloader, on_runner_installed)
|
||||
super().install(version, downloader, on_runner_installed)
|
||||
|
||||
def get_joypads(self):
|
||||
"""Return list of joypad in a format usable in the options"""
|
||||
|
@ -119,7 +119,7 @@ class reicast(Runner):
|
|||
|
||||
config_path = os.path.expanduser("~/.reicast/emu.cfg")
|
||||
if system.path_exists(config_path):
|
||||
with open(config_path, "r") as config_file:
|
||||
with open(config_path, "r", encoding='utf-8') as config_file:
|
||||
parser.read_file(config_file)
|
||||
|
||||
for section in config:
|
||||
|
@ -128,7 +128,7 @@ class reicast(Runner):
|
|||
for (key, value) in config[section].items():
|
||||
parser.set(section, key, str(value))
|
||||
|
||||
with open(config_path, "w") as config_file:
|
||||
with open(config_path, "w", encoding='utf-8') as config_file:
|
||||
parser.write(config_file)
|
||||
|
||||
def play(self):
|
||||
|
|
|
@ -152,7 +152,7 @@ class Runner: # pylint: disable=too-many-public-methods
|
|||
if sdl_gamecontrollerconfig:
|
||||
path = os.path.expanduser(sdl_gamecontrollerconfig)
|
||||
if system.path_exists(path):
|
||||
with open(path, "r") as controllerdb_file:
|
||||
with open(path, "r", encoding='utf-8') as controllerdb_file:
|
||||
sdl_gamecontrollerconfig = controllerdb_file.read()
|
||||
env["SDL_GAMECONTROLLERCONFIG"] = sdl_gamecontrollerconfig
|
||||
|
||||
|
@ -389,7 +389,7 @@ class Runner: # pylint: disable=too-many-public-methods
|
|||
extract_archive(archive, dest, merge_single=merge_single)
|
||||
except ExtractFailure as ex:
|
||||
logger.error("Failed to extract the archive %s file may be corrupt", archive)
|
||||
raise RunnerInstallationError("Failed to extract {}: {}".format(archive, ex))
|
||||
raise RunnerInstallationError("Failed to extract {}: {}".format(archive, ex)) from ex
|
||||
os.remove(archive)
|
||||
|
||||
if self.name == "wine":
|
||||
|
|
|
@ -127,7 +127,7 @@ class steam(Runner):
|
|||
system_options_override = [{"option": "disable_runtime", "default": True}]
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(steam, self).__init__(config)
|
||||
super().__init__(config)
|
||||
self.own_game_remove_method = _("Remove game data (through Steam)")
|
||||
self.no_game_remove_warning = True
|
||||
self.original_steampid = None
|
||||
|
@ -278,7 +278,7 @@ class steam(Runner):
|
|||
if not steamapps_path:
|
||||
raise RuntimeError("Could not find Steam path, is Steam installed?")
|
||||
acf_path = os.path.join(steamapps_path, "appmanifest_%s.acf" % appid)
|
||||
with open(acf_path, "w") as acf_file:
|
||||
with open(acf_path, "w", encoding='utf-8') as acf_file:
|
||||
acf_file.write(acf_content)
|
||||
if is_running():
|
||||
shutdown()
|
||||
|
|
|
@ -112,8 +112,8 @@ class vice(Runner):
|
|||
}
|
||||
try:
|
||||
executable = executables[machine]
|
||||
except KeyError:
|
||||
raise ValueError("Invalid machine '%s'" % machine)
|
||||
except KeyError as ex:
|
||||
raise ValueError("Invalid machine '%s'" % machine) from ex
|
||||
return os.path.join(settings.RUNNER_DIR, "vice/bin/%s" % executable)
|
||||
|
||||
def install(self, version=None, downloader=None, callback=None):
|
||||
|
@ -130,7 +130,7 @@ class vice(Runner):
|
|||
if callback:
|
||||
callback()
|
||||
|
||||
super(vice, self).install(version, downloader, on_runner_installed)
|
||||
super().install(version, downloader, on_runner_installed)
|
||||
|
||||
def get_roms_path(self, machine=None):
|
||||
if not machine:
|
||||
|
|
|
@ -176,7 +176,7 @@ class web(Runner):
|
|||
runner_executable = "web/electron/electron"
|
||||
|
||||
def get_env(self, os_env=True):
|
||||
env = super(web, self).get_env(os_env)
|
||||
env = super().get_env(os_env)
|
||||
|
||||
enable_flash_player = self.runner_config.get("enable_flash")
|
||||
env["ENABLE_FLASH_PLAYER"] = "1" if enable_flash_player else "0"
|
||||
|
|
|
@ -104,7 +104,7 @@ class wine(Runner):
|
|||
)
|
||||
|
||||
def __init__(self, config=None): # noqa: C901
|
||||
super(wine, self).__init__(config)
|
||||
super().__init__(config)
|
||||
self.dll_overrides = DEFAULT_DLL_OVERRIDES
|
||||
|
||||
def get_wine_version_choices():
|
||||
|
@ -117,7 +117,7 @@ class wine(Runner):
|
|||
}
|
||||
versions = get_wine_versions()
|
||||
for version in versions:
|
||||
if version in labels.keys():
|
||||
if version in labels:
|
||||
version_number = get_wine_version(WINE_PATHS[version])
|
||||
label = labels[version].format(version_number)
|
||||
else:
|
||||
|
@ -506,7 +506,7 @@ class wine(Runner):
|
|||
return option
|
||||
if self.game_exe:
|
||||
return os.path.dirname(self.game_exe)
|
||||
return super(wine, self).working_dir
|
||||
return super().working_dir
|
||||
|
||||
@property
|
||||
def wine_arch(self):
|
||||
|
@ -530,7 +530,7 @@ class wine(Runner):
|
|||
def get_path_for_version(self, version):
|
||||
"""Return the absolute path of a wine executable for a given version"""
|
||||
# logger.debug("Getting path for Wine %s", version)
|
||||
if version in WINE_PATHS.keys():
|
||||
if version in WINE_PATHS:
|
||||
return system.find_executable(WINE_PATHS[version])
|
||||
if "Proton" in version:
|
||||
for proton_path in get_proton_paths():
|
||||
|
@ -695,10 +695,10 @@ class wine(Runner):
|
|||
|
||||
for key, path in self.reg_keys.items():
|
||||
value = self.runner_config.get(key) or "auto"
|
||||
if not value or value == "auto" and key not in managed_keys.keys():
|
||||
if not value or value == "auto" and key not in managed_keys:
|
||||
prefix_manager.clear_registry_subkeys(path, key)
|
||||
elif key in self.runner_config:
|
||||
if key in managed_keys.keys():
|
||||
if key in managed_keys:
|
||||
# Do not pass fallback 'auto' value to managed keys
|
||||
if value == "auto":
|
||||
value = None
|
||||
|
@ -782,7 +782,7 @@ class wine(Runner):
|
|||
# Always false to runner.get_env, the default value
|
||||
# of os_env is inverted in the wine class,
|
||||
# the OS env is read later.
|
||||
env = super(wine, self).get_env(False)
|
||||
env = super().get_env(False)
|
||||
if os_env:
|
||||
env.update(os.environ.copy())
|
||||
show_debug = self.runner_config.get("show_debug", "-all")
|
||||
|
|
|
@ -123,7 +123,7 @@ class winesteam(wine.wine):
|
|||
]
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(winesteam, self).__init__(config)
|
||||
super().__init__(config)
|
||||
self.own_game_remove_method = _("Remove game data (through Wine Steam)")
|
||||
self.no_game_remove_warning = True
|
||||
winesteam_options = [
|
||||
|
|
|
@ -95,7 +95,7 @@ class zdoom(Runner):
|
|||
]
|
||||
|
||||
def get_executable(self):
|
||||
executable = super(zdoom, self).get_executable()
|
||||
executable = super().get_executable()
|
||||
executable_dir = os.path.dirname(executable)
|
||||
if not system.path_exists(executable_dir):
|
||||
return executable
|
||||
|
|
|
@ -46,11 +46,11 @@ def clean_rom_name(name):
|
|||
def scan_directory(dirname):
|
||||
"""Add a directory of ROMs as Lutris games"""
|
||||
files = os.listdir(dirname)
|
||||
folder_extentions = {os.path.splitext(filename)[1] for filename in files}
|
||||
folder_extensions = {os.path.splitext(filename)[1] for filename in files}
|
||||
core_matches = {}
|
||||
for core in RECOMMENDED_CORES:
|
||||
for ext in RECOMMENDED_CORES[core].get("extensions", []):
|
||||
if ext in folder_extentions:
|
||||
for core, core_data in RECOMMENDED_CORES.items():
|
||||
for ext in core_data.get("extensions", []):
|
||||
if ext in folder_extensions:
|
||||
core_matches[ext] = core
|
||||
added_games = []
|
||||
for filename in files:
|
||||
|
|
|
@ -170,7 +170,7 @@ class EpicGamesStoreService(OnlineService):
|
|||
self.session = requests.session()
|
||||
self.session.headers['User-Agent'] = self.user_agent
|
||||
if os.path.exists(self.token_path):
|
||||
with open(self.token_path) as token_file:
|
||||
with open(self.token_path, encoding='utf-8') as token_file:
|
||||
self.session_data = json.loads(token_file.read())
|
||||
else:
|
||||
self.session_data = {}
|
||||
|
@ -250,7 +250,7 @@ class EpicGamesStoreService(OnlineService):
|
|||
response_content = response.json()
|
||||
if 'error' in response_content:
|
||||
raise RuntimeError(response_content)
|
||||
with open(self.token_path, "w") as auth_file:
|
||||
with open(self.token_path, "w", encoding='utf-8') as auth_file:
|
||||
auth_file.write(json.dumps(response_content, indent=2))
|
||||
self.session_data = response_content
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ class GOGService(OnlineService):
|
|||
return
|
||||
|
||||
token = request.json
|
||||
with open(self.token_path, "w") as token_file:
|
||||
with open(self.token_path, "w", encoding='utf-8') as token_file:
|
||||
token_file.write(json.dumps(token))
|
||||
if not refresh_token:
|
||||
self.emit("service-login")
|
||||
|
@ -194,7 +194,7 @@ class GOGService(OnlineService):
|
|||
"""Load token from disk"""
|
||||
if not os.path.exists(self.token_path):
|
||||
raise AuthenticationError("No GOG token available")
|
||||
with open(self.token_path) as token_file:
|
||||
with open(self.token_path, encoding='utf-8') as token_file:
|
||||
token_content = json.loads(token_file.read())
|
||||
return token_content
|
||||
|
||||
|
@ -246,7 +246,7 @@ class GOGService(OnlineService):
|
|||
"""Return the user's library of GOG games"""
|
||||
if system.path_exists(self.cache_path):
|
||||
logger.debug("Returning cached GOG library")
|
||||
with open(self.cache_path, "r") as gog_cache:
|
||||
with open(self.cache_path, "r", encoding='utf-8') as gog_cache:
|
||||
return json.load(gog_cache)
|
||||
|
||||
total_pages = 1
|
||||
|
@ -257,7 +257,7 @@ class GOGService(OnlineService):
|
|||
page += 1
|
||||
total_pages = products_response["totalPages"]
|
||||
games += products_response["products"]
|
||||
with open(self.cache_path, "w") as gog_cache:
|
||||
with open(self.cache_path, "w", encoding='utf-8') as gog_cache:
|
||||
json.dump(games, gog_cache)
|
||||
return games
|
||||
|
||||
|
@ -291,7 +291,7 @@ class GOGService(OnlineService):
|
|||
response = self.make_api_request(downlink)
|
||||
except HTTPError as ex:
|
||||
logger.error("HTTP error: %s", ex)
|
||||
raise UnavailableGame
|
||||
raise UnavailableGame from ex
|
||||
if not response:
|
||||
raise UnavailableGame
|
||||
for field in ("checksum", "downlink"):
|
||||
|
@ -398,8 +398,8 @@ class GOGService(OnlineService):
|
|||
logger.warning("More than 1 GOG installer found, picking first.")
|
||||
_installer = gog_installers[0]
|
||||
links = self.query_download_links(_installer)
|
||||
except HTTPError:
|
||||
raise UnavailableGame("Couldn't load the download links for this game")
|
||||
except HTTPError as err:
|
||||
raise UnavailableGame("Couldn't load the download links for this game") from err
|
||||
if not links:
|
||||
raise UnavailableGame("Could not fing GOG game")
|
||||
_installer_files = defaultdict(dict) # keyed by filename
|
||||
|
@ -445,7 +445,7 @@ class GOGService(OnlineService):
|
|||
"""
|
||||
if not file_path.endswith(".xml"):
|
||||
raise ValueError("Pass a XML file to return the checksum")
|
||||
with open(file_path) as checksum_file:
|
||||
with open(file_path, encoding='utf-8') as checksum_file:
|
||||
checksum_content = checksum_file.read()
|
||||
root_elem = etree.fromstring(checksum_content)
|
||||
return (root_elem.attrib["name"], root_elem.attrib["md5"])
|
||||
|
|
|
@ -132,12 +132,12 @@ class HumbleBundleService(OnlineService):
|
|||
# logger.debug("Getting Humble Bundle order %s", gamekey)
|
||||
cache_filename = self.order_path(gamekey)
|
||||
if os.path.exists(cache_filename):
|
||||
with open(cache_filename) as cache_file:
|
||||
with open(cache_filename, encoding='utf-8') as cache_file:
|
||||
return json.load(cache_file)
|
||||
response = self.make_api_request(self.api_url + "api/v1/order/%s?all_tpkds=true" % gamekey)
|
||||
if not os.path.exists(self.cache_path):
|
||||
os.makedirs(self.cache_path)
|
||||
with open(cache_filename, "w") as cache_file:
|
||||
with open(cache_filename, "w", encoding='utf-8') as cache_file:
|
||||
json.dump(response, cache_file)
|
||||
return response
|
||||
|
||||
|
@ -221,7 +221,7 @@ class HumbleBundleService(OnlineService):
|
|||
link = get_humble_download_link(installer.service_appid, installer.runner)
|
||||
except Exception as ex:
|
||||
logger.exception("Failed to get Humble Bundle game: %s", ex)
|
||||
raise UnavailableGame
|
||||
raise UnavailableGame from ex
|
||||
if not link:
|
||||
raise UnavailableGame("No game found on Humble Bundle")
|
||||
filename = link.split("?")[0].split("/")[-1]
|
||||
|
|
|
@ -57,7 +57,7 @@ class OriginService(OnlineService):
|
|||
token = self.get_access_token()
|
||||
if not token:
|
||||
raise RuntimeError("Failed to get access token")
|
||||
with open(self.token_path, "w") as token_file:
|
||||
with open(self.token_path, "w", encoding='utf-8') as token_file:
|
||||
token_file.write(json.dumps(token, indent=2))
|
||||
self.emit("service-login")
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ class ServiceMedia:
|
|||
return download_file(url, cache_path, raise_errors=True)
|
||||
except HTTPError as ex:
|
||||
if ex.code == 404:
|
||||
open(cache_path, "a").close()
|
||||
open(cache_path, "a", encoding='utf-8').close()
|
||||
else:
|
||||
logger.error(ex.code)
|
||||
return None
|
||||
|
|
|
@ -166,11 +166,11 @@ def init_lutris():
|
|||
init_dirs()
|
||||
try:
|
||||
syncdb()
|
||||
except sqlite3.DatabaseError:
|
||||
except sqlite3.DatabaseError as err:
|
||||
raise RuntimeError(
|
||||
"Failed to open database file in %s. Try renaming this file and relaunch Lutris" %
|
||||
settings.PGA_DB
|
||||
)
|
||||
) from err
|
||||
for service in DEFAULT_SERVICES:
|
||||
if not settings.read_setting(service, section="services"):
|
||||
settings.write_setting(service, True, section="services")
|
||||
|
|
|
@ -75,6 +75,6 @@ class WebkitCookieJar(MozillaCookieJar):
|
|||
|
||||
except OSError:
|
||||
raise
|
||||
except Exception:
|
||||
except Exception as err:
|
||||
_warn_unhandled_exception()
|
||||
raise OSError("invalid Netscape format cookies file %r: %r" % (filename, line))
|
||||
raise OSError("invalid Netscape format cookies file %r: %r" % (filename, line)) from err
|
||||
|
|
|
@ -30,7 +30,7 @@ def rom_read_data(location):
|
|||
return a dict with "data" and "config", to be applied to a game in Lutris """
|
||||
# TODO: extract the image of the rom
|
||||
data = {}
|
||||
with open(location, "r+") as rom:
|
||||
with open(location, "r+", encoding='utf-8') as rom:
|
||||
mm = mmap(rom.fileno(), 0)
|
||||
# the most of the scan of the game
|
||||
if mm[0:4] == b"WBFS": # wii WBFS file
|
||||
|
|
|
@ -19,7 +19,7 @@ class EGSLauncher:
|
|||
for manifest in os.listdir(manifests_path):
|
||||
if not manifest.endswith(".item"):
|
||||
continue
|
||||
with open(os.path.join(manifests_path, manifest)) as manifest_file:
|
||||
with open(os.path.join(manifests_path, manifest), encoding='utf-8') as manifest_file:
|
||||
manifest_content = json.loads(manifest_file.read())
|
||||
if manifest_content["MainGameAppName"] != manifest_content["AppName"]:
|
||||
continue
|
||||
|
|
|
@ -128,7 +128,7 @@ def extract_archive(path, to_directory=".", merge_single=True, extractor=None):
|
|||
_do_extract(path, temp_path, opener, mode, extractor)
|
||||
except (OSError, zlib.error, tarfile.ReadError, EOFError) as ex:
|
||||
logger.error("Extraction failed: %s", ex)
|
||||
raise ExtractFailure(str(ex))
|
||||
raise ExtractFailure(str(ex)) from ex
|
||||
if merge_single:
|
||||
extracted = os.listdir(temp_path)
|
||||
if len(extracted) == 1:
|
||||
|
@ -164,7 +164,7 @@ def extract_archive(path, to_directory=".", merge_single=True, extractor=None):
|
|||
destination_path,
|
||||
ex,
|
||||
)
|
||||
raise ExtractFailure(str(ex))
|
||||
raise ExtractFailure(str(ex)) from ex
|
||||
else:
|
||||
shutil.move(source_path, destination_path)
|
||||
system.remove_folder(temp_dir)
|
||||
|
|
|
@ -56,4 +56,4 @@ class MultiOrderedDict(OrderedDict):
|
|||
if isinstance(value, list) and key in self:
|
||||
self[key].extend(value)
|
||||
else:
|
||||
super(MultiOrderedDict, self).__setitem__(key, value)
|
||||
super().__setitem__(key, value)
|
||||
|
|
|
@ -57,8 +57,8 @@ def find_linux_game_executable(path, make_executable=False):
|
|||
candidates["32bit"] = abspath
|
||||
if candidates:
|
||||
if make_executable:
|
||||
for file_type in candidates:
|
||||
system.make_executable(candidates[file_type])
|
||||
for candidate in candidates.values():
|
||||
system.make_executable(candidate)
|
||||
return (
|
||||
candidates.get("shell")
|
||||
or candidates.get("bash")
|
||||
|
|
|
@ -71,7 +71,7 @@ class GameControllerDB:
|
|||
return self.controllers[value]
|
||||
|
||||
def parsedb(self):
|
||||
with open(self.db_path, "r") as db:
|
||||
with open(self.db_path, "r", encoding='utf-8') as db:
|
||||
for line in db.readlines():
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
|
|
|
@ -17,7 +17,7 @@ def get_nvidia_driver_info():
|
|||
version_file_path = "/proc/driver/nvidia/version"
|
||||
if not os.path.exists(version_file_path):
|
||||
return
|
||||
with open(version_file_path) as version_file:
|
||||
with open(version_file_path, encoding='utf-8') as version_file:
|
||||
content = version_file.readlines()
|
||||
nvrm_version = content[0].split(': ')[1].strip().split()
|
||||
return {
|
||||
|
@ -39,7 +39,7 @@ def get_nvidia_gpu_ids():
|
|||
|
||||
def get_nvidia_gpu_info(gpu_id):
|
||||
"""Return details about a GPU"""
|
||||
with open("/proc/driver/nvidia/gpus/%s/information" % gpu_id) as info_file:
|
||||
with open("/proc/driver/nvidia/gpus/%s/information" % gpu_id, encoding='utf-8') as info_file:
|
||||
content = info_file.readlines()
|
||||
infos = {}
|
||||
for line in content:
|
||||
|
@ -67,7 +67,7 @@ def get_gpu_info(card):
|
|||
"""Return information about a GPU"""
|
||||
infos = {"DRIVER": "", "PCI_ID": "", "PCI_SUBSYS_ID": ""}
|
||||
try:
|
||||
with open("/sys/class/drm/%s/device/uevent" % card) as card_uevent:
|
||||
with open("/sys/class/drm/%s/device/uevent" % card, encoding='utf-8') as card_uevent:
|
||||
content = card_uevent.readlines()
|
||||
except FileNotFoundError:
|
||||
logger.error("Unable to read driver information for card %s", card)
|
||||
|
|
|
@ -82,7 +82,7 @@ class Request:
|
|||
try:
|
||||
req = urllib.request.Request(url=self.url, data=data, headers=self.headers)
|
||||
except ValueError as ex:
|
||||
raise HTTPError("Failed to create HTTP request to %s: %s" % (self.url, ex))
|
||||
raise HTTPError("Failed to create HTTP request to %s: %s" % (self.url, ex)) from ex
|
||||
try:
|
||||
if self.opener:
|
||||
request = self.opener.open(req, timeout=self.timeout)
|
||||
|
@ -90,10 +90,10 @@ class Request:
|
|||
request = urllib.request.urlopen(req, timeout=self.timeout)
|
||||
except (urllib.error.HTTPError, CertificateError) as error:
|
||||
if error.code == 401:
|
||||
raise UnauthorizedAccess("Access to %s denied" % self.url)
|
||||
raise HTTPError("%s" % error, code=error.code)
|
||||
raise UnauthorizedAccess("Access to %s denied" % self.url) from error
|
||||
raise HTTPError("%s" % error, code=error.code) from error
|
||||
except (socket.timeout, urllib.error.URLError) as error:
|
||||
raise HTTPError("Unable to connect to server %s: %s" % (self.url, error))
|
||||
raise HTTPError("Unable to connect to server %s: %s" % (self.url, error)) from error
|
||||
try:
|
||||
self.total_size = int(request.info().get("Content-Length").strip())
|
||||
except AttributeError:
|
||||
|
@ -116,8 +116,8 @@ class Request:
|
|||
return self
|
||||
try:
|
||||
chunk = request.read(self.buffer_size)
|
||||
except (socket.timeout, ConnectionResetError):
|
||||
raise HTTPError("Request timed out")
|
||||
except (socket.timeout, ConnectionResetError) as err:
|
||||
raise HTTPError("Request timed out") from err
|
||||
self.downloaded_size += len(chunk)
|
||||
if not chunk:
|
||||
return
|
||||
|
@ -144,8 +144,8 @@ class Request:
|
|||
if _raw_json:
|
||||
try:
|
||||
return json.loads(_raw_json)
|
||||
except json.decoder.JSONDecodeError:
|
||||
raise ValueError("JSON response from %s could not be decoded: '%s'" % (self.url, _raw_json[:80]))
|
||||
except json.decoder.JSONDecodeError as err:
|
||||
raise ValueError(f"JSON response from {self.url} could not be decoded: '{_raw_json[:80]}'") from err
|
||||
return {}
|
||||
|
||||
@property
|
||||
|
|
|
@ -19,7 +19,7 @@ class AsyncCall(threading.Thread):
|
|||
self.source_id = None
|
||||
self.stop_request = threading.Event()
|
||||
|
||||
super(AsyncCall, self).__init__(target=self.target, args=args, kwargs=kwargs)
|
||||
super().__init__(target=self.target, args=args, kwargs=kwargs)
|
||||
self.function = func
|
||||
self.callback = callback if callback else lambda r, e: None
|
||||
self.daemon = kwargs.pop("daemon", True)
|
||||
|
|
|
@ -33,7 +33,7 @@ class RetroConfig:
|
|||
self._config = []
|
||||
if not os.path.isfile(self.config_path):
|
||||
raise OSError("Specified config file {} does not exist".format(self.config_path))
|
||||
with open(self.config_path, "r") as config_file:
|
||||
with open(self.config_path, "r", encoding='utf-8') as config_file:
|
||||
for line in config_file.readlines():
|
||||
if not line:
|
||||
continue
|
||||
|
@ -49,7 +49,7 @@ class RetroConfig:
|
|||
self._config.append((key, value))
|
||||
|
||||
def save(self):
|
||||
with open(self.config_path, "w") as config_file:
|
||||
with open(self.config_path, "w", encoding='utf-8') as config_file:
|
||||
for (key, value) in self.config:
|
||||
config_file.write('{} = "{}"\n'.format(key, value))
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ class LinuxSystem: # pylint: disable=too-many-public-methods
|
|||
"""Parse the output of /proc/cpuinfo"""
|
||||
cpus = [{}]
|
||||
cpu_index = 0
|
||||
with open("/proc/cpuinfo") as cpuinfo:
|
||||
with open("/proc/cpuinfo", encoding='utf-8') as cpuinfo:
|
||||
for line in cpuinfo.readlines():
|
||||
if not line.strip():
|
||||
cpu_index += 1
|
||||
|
@ -170,7 +170,7 @@ class LinuxSystem: # pylint: disable=too-many-public-methods
|
|||
def get_ram_info():
|
||||
"""Parse the output of /proc/meminfo and return RAM information in kB"""
|
||||
mem = {}
|
||||
with open("/proc/meminfo") as meminfo:
|
||||
with open("/proc/meminfo", encoding='utf-8') as meminfo:
|
||||
for line in meminfo.readlines():
|
||||
key, value = line.split(":", 1)
|
||||
mem[key.strip()] = value.strip('kB \n')
|
||||
|
@ -200,7 +200,7 @@ class LinuxSystem: # pylint: disable=too-many-public-methods
|
|||
@staticmethod
|
||||
def get_kernel_version():
|
||||
"""Get kernel info from /proc/version"""
|
||||
with open("/proc/version") as kernel_info:
|
||||
with open("/proc/version", encoding='utf-8') as kernel_info:
|
||||
info = kernel_info.readlines()[0]
|
||||
version = info.split(" ")[2]
|
||||
return version
|
||||
|
@ -476,12 +476,11 @@ def gather_system_info_str():
|
|||
system_info_readable["Graphics"] = graphics_dict
|
||||
|
||||
output = ''
|
||||
for section in system_info_readable:
|
||||
output += '[{}]\n'.format(section)
|
||||
dictionary = system_info_readable[section]
|
||||
for key in dictionary:
|
||||
for section, dictionary in system_info_readable.items():
|
||||
output += f'[{section}]\n'
|
||||
for key, value in dictionary.items():
|
||||
tabs = " " * (16 - len(key))
|
||||
output += '{}{}{}\n'.format(key + ":", tabs, dictionary[key])
|
||||
output += f'{key}:{tabs}{value}\n'
|
||||
output += '\n'
|
||||
return output
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ def get_supported_systems(xml_path, force=False):
|
|||
"""
|
||||
systems_cache_path = os.path.join(CACHE_DIR, "systems.json")
|
||||
if os.path.exists(systems_cache_path) and not force:
|
||||
with open(systems_cache_path, "r") as systems_cache_file:
|
||||
with open(systems_cache_path, "r", encoding='utf-8') as systems_cache_file:
|
||||
try:
|
||||
systems = json.load(systems_cache_file)
|
||||
except json.JSONDecodeError:
|
||||
|
@ -123,7 +123,7 @@ def get_supported_systems(xml_path, force=False):
|
|||
}
|
||||
if not systems:
|
||||
return {}
|
||||
with open(systems_cache_path, "w") as systems_cache_file:
|
||||
with open(systems_cache_path, "w", encoding='utf-8') as systems_cache_file:
|
||||
json.dump(systems, systems_cache_file, indent=2)
|
||||
return systems
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class MameIni:
|
|||
|
||||
def read(self):
|
||||
"""Reads the content of the ini file"""
|
||||
with open(self.ini_path, "r") as ini_file:
|
||||
with open(self.ini_path, "r", encoding='utf-8') as ini_file:
|
||||
for line in ini_file.readlines():
|
||||
self.lines.append(line)
|
||||
print(line)
|
||||
|
@ -36,7 +36,7 @@ class MameIni:
|
|||
|
||||
def write(self):
|
||||
"""Writes the file to disk"""
|
||||
with open(self.ini_path, "w") as ini_file:
|
||||
with open(self.ini_path, "w", encoding='utf-8') as ini_file:
|
||||
for line in self.lines:
|
||||
config_key, _value = self.parse(line)
|
||||
if config_key and self.config[config_key]:
|
||||
|
|
|
@ -22,8 +22,8 @@ class Process:
|
|||
def __init__(self, pid):
|
||||
try:
|
||||
self.pid = int(pid)
|
||||
except ValueError:
|
||||
raise InvalidPid("'%s' is not a valid pid" % pid)
|
||||
except ValueError as err:
|
||||
raise InvalidPid("'%s' is not a valid pid" % pid) from err
|
||||
|
||||
def __repr__(self):
|
||||
return "Process {}".format(self.pid)
|
||||
|
@ -34,7 +34,7 @@ class Process:
|
|||
def _read_content(self, file_path):
|
||||
"""Return the contents from a file in /proc"""
|
||||
try:
|
||||
with open(file_path) as proc_file:
|
||||
with open(file_path, encoding='utf-8') as proc_file:
|
||||
content = proc_file.read()
|
||||
except (ProcessLookupError, FileNotFoundError, PermissionError):
|
||||
return ""
|
||||
|
@ -43,7 +43,7 @@ class Process:
|
|||
def get_stat(self, parsed=True):
|
||||
stat_filename = "/proc/{}/stat".format(self.pid)
|
||||
try:
|
||||
with open(stat_filename) as stat_file:
|
||||
with open(stat_filename, encoding='utf-8') as stat_file:
|
||||
_stat = stat_file.readline()
|
||||
except (ProcessLookupError, FileNotFoundError):
|
||||
return None
|
||||
|
@ -66,7 +66,7 @@ class Process:
|
|||
"""Return pids of child processes opened by thread `tid` of process."""
|
||||
children_path = "/proc/{}/task/{}/children".format(self.pid, tid)
|
||||
try:
|
||||
with open(children_path) as children_file:
|
||||
with open(children_path, encoding='utf-8') as children_file:
|
||||
children_content = children_file.read()
|
||||
except (FileNotFoundError, ProcessLookupError):
|
||||
children_content = ""
|
||||
|
|
|
@ -39,5 +39,5 @@ class SettingsIO:
|
|||
self.config.add_section(section)
|
||||
self.config.set(section, key, str(value))
|
||||
|
||||
with open(self.config_file, "w") as config_file:
|
||||
with open(self.config_file, "w", encoding='utf-8') as config_file:
|
||||
self.config.write(config_file)
|
||||
|
|
|
@ -17,7 +17,7 @@ def get_terminal_script(command, cwd, env):
|
|||
env["TERM"] = "xterm"
|
||||
exported_environment = "\n".join('export %s="%s" ' % (key, value) for key, value in env.items())
|
||||
command = " ".join(['"%s"' % token for token in command])
|
||||
with open(script_path, "w") as script_file:
|
||||
with open(script_path, "w", encoding='utf-8') as script_file:
|
||||
script_file.write(
|
||||
dedent(
|
||||
"""#!/bin/sh
|
||||
|
@ -40,7 +40,7 @@ def get_bash_rc_file(cwd, env, aliases=None):
|
|||
aliases = aliases or {}
|
||||
alias_commands = "\n".join('alias %s="%s"' % (key, value) for key, value in aliases.items())
|
||||
current_bashrc = os.path.expanduser("~/.bashrc")
|
||||
with open(script_path, "w") as script_file:
|
||||
with open(script_path, "w", encoding='utf-8') as script_file:
|
||||
script_file.write(
|
||||
dedent(
|
||||
"""
|
||||
|
|
|
@ -46,7 +46,7 @@ class AppManifest:
|
|||
self.appmanifest_data = {}
|
||||
|
||||
if path_exists(appmanifest_path):
|
||||
with open(appmanifest_path, "r") as appmanifest_file:
|
||||
with open(appmanifest_path, "r", encoding='utf-8') as appmanifest_file:
|
||||
self.appmanifest_data = vdf_parse(appmanifest_file, {})
|
||||
else:
|
||||
logger.error("Path to AppManifest file %s doesn't exist", appmanifest_path)
|
||||
|
|
|
@ -59,7 +59,7 @@ def read_user_config():
|
|||
config_filename = search_in_steam_dirs("config/loginusers.vdf")
|
||||
if not system.path_exists(config_filename):
|
||||
return None
|
||||
with open(config_filename, "r") as steam_config_file:
|
||||
with open(config_filename, "r", encoding='utf-8') as steam_config_file:
|
||||
config = vdf_parse(steam_config_file, {})
|
||||
return config
|
||||
|
||||
|
@ -133,7 +133,7 @@ def read_config(steam_data_dir):
|
|||
config_filename = os.path.join(steam_data_dir, "config/config.vdf")
|
||||
if not system.path_exists(config_filename):
|
||||
return None
|
||||
with open(config_filename, "r") as steam_config_file:
|
||||
with open(config_filename, "r", encoding='utf-8') as steam_config_file:
|
||||
config = vdf_parse(steam_config_file, {})
|
||||
try:
|
||||
return get_entry_case_insensitive(config, ["InstallConfigStore", "Software", "Valve", "Steam"])
|
||||
|
@ -155,7 +155,7 @@ def read_library_folders(steam_data_dir):
|
|||
library_filename = os.path.join(steam_data_dir, "config/libraryfolders.vdf")
|
||||
if not system.path_exists(library_filename):
|
||||
return None
|
||||
with open(library_filename, "r") as steam_library_file:
|
||||
with open(library_filename, "r", encoding='utf-8') as steam_library_file:
|
||||
library = vdf_parse(steam_library_file, {})
|
||||
# The contentstatsid key is unused and causes problems when looking for library paths.
|
||||
library["libraryfolders"].pop("contentstatsid")
|
||||
|
|
|
@ -11,7 +11,7 @@ def _get_last_content_log(steam_data_dir):
|
|||
path = os.path.join(steam_data_dir, "logs/content_log.txt")
|
||||
log = []
|
||||
try:
|
||||
with open(path, "r") as logfile:
|
||||
with open(path, "r", encoding='utf-8') as logfile:
|
||||
line = logfile.readline()
|
||||
while line:
|
||||
# Strip old logs
|
||||
|
|
|
@ -55,5 +55,5 @@ def to_vdf(dict_data, level=0):
|
|||
def vdf_write(vdf_path, config):
|
||||
"""Write a Steam configuration to a vdf file"""
|
||||
vdf_data = to_vdf(config)
|
||||
with open(vdf_path, "w") as vdf_file:
|
||||
with open(vdf_path, "w", encoding='utf-8') as vdf_file:
|
||||
vdf_file.write(vdf_data)
|
||||
|
|
|
@ -132,7 +132,7 @@ class CabInstaller:
|
|||
return (out, arch)
|
||||
|
||||
def get_wineprefix_arch(self):
|
||||
with open(os.path.join(self.prefix, "system.reg")) as reg_file:
|
||||
with open(os.path.join(self.prefix, "system.reg"), encoding='utf-8') as reg_file:
|
||||
for line in reg_file.readlines():
|
||||
if line.startswith("#arch=win32"):
|
||||
return "win32"
|
||||
|
@ -173,7 +173,7 @@ class CabInstaller:
|
|||
outdata, arch = self.get_registry_from_manifest(file_path)
|
||||
if outdata:
|
||||
out += outdata
|
||||
with open(os.path.join(self.tmpdir, file_path + ".reg"), "w") as reg_file:
|
||||
with open(os.path.join(self.tmpdir, file_path + ".reg"), "w", encoding='utf-8') as reg_file:
|
||||
reg_file.write(out)
|
||||
reg_files.append((file_path + ".reg", arch))
|
||||
if file_path.endswith(".dll"):
|
||||
|
|
|
@ -64,7 +64,7 @@ class DLLManager:
|
|||
def load_versions(self):
|
||||
if not system.path_exists(self.versions_path):
|
||||
return []
|
||||
with open(self.versions_path, "r") as version_file:
|
||||
with open(self.versions_path, "r", encoding='utf-8') as version_file:
|
||||
try:
|
||||
versions = [v["tag_name"] for v in json.load(version_file)]
|
||||
except (KeyError, json.decoder.JSONDecodeError):
|
||||
|
@ -99,7 +99,7 @@ class DLLManager:
|
|||
|
||||
def get_download_url(self):
|
||||
"""Fetch the download URL from the JSON version file"""
|
||||
with open(self.versions_path, "r") as version_file:
|
||||
with open(self.versions_path, "r", encoding='utf-8') as version_file:
|
||||
releases = json.load(version_file)
|
||||
for release in releases:
|
||||
if release["tag_name"] != self.version:
|
||||
|
|
|
@ -155,11 +155,11 @@ class WinePrefixManager:
|
|||
if desktop_dir != user_dir:
|
||||
try:
|
||||
src_path = os.path.join(desktop_dir, item)
|
||||
except TypeError:
|
||||
except TypeError as ex:
|
||||
# There is supposedly a None value in there
|
||||
# The current code shouldn't allow that
|
||||
# Just raise a exception with the values
|
||||
raise RuntimeError("Missing value desktop_dir=%s or item=%s" % (desktop_dir, item))
|
||||
raise RuntimeError("Missing value desktop_dir=%s or item=%s" % (desktop_dir, item)) from ex
|
||||
|
||||
os.makedirs(src_path, exist_ok=True)
|
||||
os.symlink(src_path, path)
|
||||
|
|
|
@ -97,7 +97,7 @@ class WineRegistry:
|
|||
"""Return an array of the unprocessed contents of a registry file"""
|
||||
if not system.path_exists(reg_filename):
|
||||
return []
|
||||
with open(reg_filename, "r") as reg_file:
|
||||
with open(reg_filename, "r", encoding='utf-8') as reg_file:
|
||||
|
||||
try:
|
||||
registry_content = reg_file.readlines()
|
||||
|
@ -158,7 +158,7 @@ class WineRegistry:
|
|||
"Invalid Wine prefix path %s, make sure to "
|
||||
"create the prefix before saving to a registry" % prefix_path
|
||||
)
|
||||
with open(path, "w") as registry_file:
|
||||
with open(path, "w", encoding='utf-8') as registry_file:
|
||||
registry_file.write(self.render())
|
||||
|
||||
def query(self, path, subkey):
|
||||
|
|
|
@ -80,7 +80,7 @@ def detect_prefix_arch(prefix_path=None):
|
|||
# No prefix_path exists or invalid prefix
|
||||
logger.debug("Prefix not found: %s", prefix_path)
|
||||
return None
|
||||
with open(registry_path, "r") as registry:
|
||||
with open(registry_path, "r", encoding='utf-8') as registry:
|
||||
for _line_no in range(5):
|
||||
line = registry.readline()
|
||||
if "win64" in line:
|
||||
|
|
|
@ -61,7 +61,7 @@ def create_launcher(game_slug, game_id, game_name, desktop=False, menu=False):
|
|||
|
||||
launcher_filename = get_xdg_basename(game_slug, game_id)
|
||||
tmp_launcher_path = os.path.join(CACHE_DIR, launcher_filename)
|
||||
tmp_launcher = open(tmp_launcher_path, "w")
|
||||
tmp_launcher = open(tmp_launcher_path, "w", encoding='utf-8')
|
||||
tmp_launcher.write(launcher_content)
|
||||
tmp_launcher.close()
|
||||
os.chmod(
|
||||
|
|
|
@ -13,7 +13,7 @@ def read_yaml_from_file(filename):
|
|||
if not path_exists(filename):
|
||||
return {}
|
||||
|
||||
with open(filename, "r") as yaml_file:
|
||||
with open(filename, "r", encoding='utf-8') as yaml_file:
|
||||
try:
|
||||
yaml_content = yaml.safe_load(yaml_file) or {}
|
||||
except (yaml.scanner.ScannerError, yaml.parser.ParserError):
|
||||
|
@ -25,5 +25,5 @@ def read_yaml_from_file(filename):
|
|||
|
||||
def write_yaml_to_file(config, filepath):
|
||||
yaml_config = yaml.dump(config, default_flow_style=False)
|
||||
with open(filepath, "w") as filehandler:
|
||||
with open(filepath, "w", encoding='utf-8') as filehandler:
|
||||
filehandler.write(yaml_config)
|
||||
|
|
Loading…
Reference in a new issue