1
0
Fork 0
mirror of synced 2024-06-29 11:40:37 +12:00
Rare/rare/utils/wine.py

109 lines
3.8 KiB
Python
Raw Normal View History

import os
import shutil
import subprocess
from configparser import ConfigParser
from logging import getLogger
from typing import Mapping, Dict, List, Tuple
from rare.lgndr.core import LegendaryCore
logger = getLogger("Wine")
# this is a copied function from legendary.utils.wine_helpers, but registry file can be specified
def read_registry(registry: str, wine_pfx: str) -> ConfigParser:
accepted = ["system.reg", "user.reg"]
if registry not in accepted:
raise RuntimeError(f'Unknown target "{registry}" not in {accepted}')
reg = ConfigParser(comment_prefixes=(';', '#', '/', 'WINE'), allow_no_value=True,
strict=False)
reg.optionxform = str
reg.read(os.path.join(wine_pfx, 'system.reg'))
return reg
def execute(cmd: List, wine_env: Mapping) -> Tuple[str, str]:
if os.environ.get("container") == "flatpak":
flatpak_cmd = ["flatpak-spawn", "--host"]
for name, value in wine_env.items():
flatpak_cmd.append(f"--env={name}={value}")
cmd = flatpak_cmd + cmd
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
# Use the current environment if we are in flatpak or our own if we are on host
# In flatpak our environment is passed through `flatpak-spawn` arguments
env=os.environ.copy() if os.environ.get("container") == "flatpak" else wine_env,
shell=False,
text=True,
)
res = proc.communicate()
return res
def resolve_path(wine_exec: str, wine_env: Mapping, path: str) -> str:
path = path.strip().replace("/", "\\")
# lk: if path does not exist form
cmd = [wine_exec, "cmd", "/c", "echo", path]
# lk: if path exists and needs a case-sensitive interpretation form
# cmd = [wine_cmd, 'cmd', '/c', f'cd {path} & cd']
out, err = execute(cmd, wine_env)
return out.strip().strip('"')
def query_reg_path(wine_exec: str, wine_env: Mapping, reg_path: str):
raise NotImplementedError
def query_reg_key(wine_exec: str, wine_env: Mapping, reg_path: str, reg_key) -> str:
cmd = [wine_exec, "reg", "query", reg_path, "/v", reg_key]
out, err = execute(cmd, wine_env)
lines = out.split("\n")
keys: Dict = {}
for line in lines:
if line.startswith(" "*4):
key = [x for x in line.split(" "*4, 3) if bool(x)]
keys.update({key[0]: key[2]})
return keys.get(reg_key, "")
def convert_to_windows_path(wine_exec: str, wine_env: Mapping, path: str) -> str:
raise NotImplementedError
def convert_to_unix_path(wine_exec: str, wine_env: Mapping, path: str) -> str:
path = path.strip().strip('"')
cmd = [wine_exec, "winepath.exe", "-u", path]
out, err = execute(cmd, wine_env)
return os.path.realpath(out.strip())
def wine(core: LegendaryCore, app_name: str = "default") -> str:
_wine = core.lgd.config.get(
app_name, "wine_executable", fallback=core.lgd.config.get(
"default", "wine_executable", fallback=shutil.which("wine")
)
)
return _wine
def environ(core: LegendaryCore, app_name: str = "default") -> Dict:
# Get a clean environment if we are in flatpak, this environment will be pass
# to `flatpak-spawn`, otherwise use the system's.
_environ = {} if os.environ.get("container") == "flatpak" else os.environ.copy()
_environ.update(core.get_app_environment(app_name))
_environ["WINEDEBUG"] = "-all"
_environ["WINEDLLOVERRIDES"] = "winemenubuilder=d;mscoree=d;mshtml=d;"
_environ["DISPLAY"] = ""
return _environ
def prefix(core: LegendaryCore, app_name: str = "default") -> str:
_prefix = core.lgd.config.get(
app_name, "wine_prefix", fallback=core.lgd.config.get(
"default", "wine_prefix", fallback=os.path.expanduser("~/.wine")
)
)
return _prefix if os.path.isdir(_prefix) else ""