Changes
- Add Windows support - Add Steam RetroArch support - Add support for custom playlist and thumbnail directories
This commit is contained in:
@@ -19,9 +19,10 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from json import JSONDecodeError
|
from json import JSONDecodeError
|
||||||
from re import sub
|
from pathlib import Path
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from src import shared
|
from src import shared
|
||||||
@@ -29,19 +30,39 @@ from src.errors.friendly_error import FriendlyError
|
|||||||
from src.game import Game
|
from src.game import Game
|
||||||
from src.importer.sources.location import Location
|
from src.importer.sources.location import Location
|
||||||
from src.importer.sources.source import Source, SourceIterationResult, SourceIterator
|
from src.importer.sources.source import Source, SourceIterationResult, SourceIterator
|
||||||
|
from src.importer.sources.steam_source import SteamSource
|
||||||
|
|
||||||
|
|
||||||
class RetroarchSourceIterator(SourceIterator):
|
class RetroarchSourceIterator(SourceIterator):
|
||||||
source: "RetroarchSource"
|
source: "RetroarchSource"
|
||||||
|
|
||||||
|
def get_config_value(self, key: str, config_data: str):
|
||||||
|
for item in re.findall(f'{key}\\s*=\\s*"(.*)"\n', config_data, re.IGNORECASE):
|
||||||
|
logging.debug(str(item))
|
||||||
|
return item
|
||||||
|
|
||||||
|
raise KeyError(f"Key not found in RetroArch config: {key}")
|
||||||
|
|
||||||
def generator_builder(self) -> SourceIterationResult:
|
def generator_builder(self) -> SourceIterationResult:
|
||||||
added_time = int(time())
|
added_time = int(time())
|
||||||
bad_playlists = set()
|
bad_playlists = set()
|
||||||
|
|
||||||
|
config_file = self.source.config_location["config"]
|
||||||
|
with config_file.open(encoding="utf-8") as open_file:
|
||||||
|
config_data = open_file.read()
|
||||||
|
|
||||||
|
playlist_folder = Path(
|
||||||
|
self.get_config_value("playlist_directory", config_data)
|
||||||
|
).expanduser()
|
||||||
|
thumbnail_folder = Path(
|
||||||
|
self.get_config_value("thumbnails_directory", config_data)
|
||||||
|
).expanduser()
|
||||||
|
|
||||||
# Get all playlist files, ending in .lpl
|
# Get all playlist files, ending in .lpl
|
||||||
playlist_files = self.source.config_location["playlists"].glob("*.lpl")
|
playlist_files = playlist_folder.glob("*.lpl")
|
||||||
|
|
||||||
for playlist_file in playlist_files:
|
for playlist_file in playlist_files:
|
||||||
|
logging.debug(playlist_file)
|
||||||
try:
|
try:
|
||||||
with playlist_file.open(
|
with playlist_file.open(
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
@@ -84,10 +105,10 @@ class RetroarchSourceIterator(SourceIterator):
|
|||||||
|
|
||||||
# Get boxart
|
# Get boxart
|
||||||
boxart_image_name = item["label"] + ".png"
|
boxart_image_name = item["label"] + ".png"
|
||||||
boxart_image_name = sub(r"[&\*\/:`<>\?\\\|]", "_", boxart_image_name)
|
boxart_image_name = re.sub(r"[&\*\/:`<>\?\\\|]", "_", boxart_image_name)
|
||||||
boxart_folder_name = playlist_file.stem
|
boxart_folder_name = playlist_file.stem
|
||||||
image_path = (
|
image_path = (
|
||||||
self.source.config_location["thumbnails"]
|
thumbnail_folder
|
||||||
/ boxart_folder_name
|
/ boxart_folder_name
|
||||||
/ "Named_Boxarts"
|
/ "Named_Boxarts"
|
||||||
/ boxart_image_name
|
/ boxart_image_name
|
||||||
@@ -107,20 +128,45 @@ class RetroarchSourceIterator(SourceIterator):
|
|||||||
|
|
||||||
|
|
||||||
class RetroarchSource(Source):
|
class RetroarchSource(Source):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
# Find steam location
|
||||||
|
libraryfolders = SteamSource().data_location["libraryfolders.vdf"]
|
||||||
|
library_path = ""
|
||||||
|
|
||||||
|
with open(libraryfolders, "r", encoding="utf-8") as open_file:
|
||||||
|
for line in open_file:
|
||||||
|
if '"path"' in line:
|
||||||
|
library_path = re.findall(
|
||||||
|
'"path"\\s+"(.*)"\n', line, re.IGNORECASE
|
||||||
|
)[0]
|
||||||
|
elif "1118310" in line:
|
||||||
|
break
|
||||||
|
|
||||||
|
if library_path:
|
||||||
|
self.config_location.candidates.append(
|
||||||
|
Path(f"{library_path}/steamapps/common/RetroArch")
|
||||||
|
)
|
||||||
|
|
||||||
name = _("RetroArch")
|
name = _("RetroArch")
|
||||||
available_on = {"linux"}
|
available_on = {"linux", "windows"}
|
||||||
iterator_class = RetroarchSourceIterator
|
iterator_class = RetroarchSourceIterator
|
||||||
|
|
||||||
config_location = Location(
|
config_location = Location(
|
||||||
schema_key="retroarch-location",
|
schema_key="retroarch-location",
|
||||||
candidates=(
|
candidates=[
|
||||||
shared.flatpak_dir / "org.libretro.RetroArch" / "config" / "retroarch",
|
shared.flatpak_dir / "org.libretro.RetroArch" / "config" / "retroarch",
|
||||||
shared.config_dir / "retroarch",
|
shared.config_dir / "retroarch",
|
||||||
shared.home / ".config" / "retroarch",
|
shared.home / ".config" / "retroarch",
|
||||||
),
|
Path("C:\\RetroArch-Win64"),
|
||||||
|
Path("C:\\RetroArch-Win32"),
|
||||||
|
shared.local_appdata_dir
|
||||||
|
/ "Packages"
|
||||||
|
/ "1e4cf179-f3c2-404f-b9f3-cb2070a5aad8_8ngdn9a6dx1ma"
|
||||||
|
/ "LocalState",
|
||||||
|
],
|
||||||
paths={
|
paths={
|
||||||
"playlists": (True, "playlists"),
|
"config": (False, "retroarch.cfg"),
|
||||||
"thumbnails": (True, "thumbnails"),
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ games_dir = data_dir / "cartridges" / "games"
|
|||||||
covers_dir = data_dir / "cartridges" / "covers"
|
covers_dir = data_dir / "cartridges" / "covers"
|
||||||
|
|
||||||
appdata_dir = Path(os.getenv("appdata") or "C:\\Users\\Default\\AppData\\Roaming")
|
appdata_dir = Path(os.getenv("appdata") or "C:\\Users\\Default\\AppData\\Roaming")
|
||||||
|
local_appdata_dir = Path(os.getenv("csidl_local_appdata") or "C:\\Users\\Default\\AppData\\Local")
|
||||||
programfiles32_dir = Path(os.getenv("programfiles(x86)") or "C:\\Program Files (x86)")
|
programfiles32_dir = Path(os.getenv("programfiles(x86)") or "C:\\Program Files (x86)")
|
||||||
|
|
||||||
scale_factor = max(
|
scale_factor = max(
|
||||||
|
|||||||
Reference in New Issue
Block a user