Add TOSEC scanner/renamer

This commit is contained in:
Mathieu Comandon 2023-01-18 18:38:00 -08:00
parent d7e365b250
commit 1d3519f405
4 changed files with 100 additions and 2 deletions

View file

@ -76,7 +76,8 @@ disable=
wrong-import-position,
import-outside-toplevel,
duplicate-code,
consider-using-f-string
consider-using-f-string,
no-self-use
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option

View file

@ -970,6 +970,7 @@ Also, check that the version specified is in the correct format.
class CommandLineUIDelegate(Game.LaunchUIDelegate):
"""This delegate can provide user selections that were provided on the command line."""
def __init__(self, launch_config_name):
self.launch_config_name = launch_config_name

View file

@ -12,6 +12,7 @@ from lutris.gui import dialogs
from lutris.gui.config import DIALOG_HEIGHT, DIALOG_WIDTH
from lutris.gui.config.boxes import GameBox, RunnerBox, SystemBox
from lutris.gui.dialogs import DirectoryDialog, ErrorDialog, ModelessDialog, QuestionDialog
from lutris.gui.dialogs.delegates import DialogInstallUIDelegate
from lutris.gui.widgets.common import Label, NumberEntry, SlugEntry, VBox
from lutris.gui.widgets.notifications import send_notification
from lutris.gui.widgets.utils import get_pixbuf
@ -19,7 +20,6 @@ from lutris.runners import import_runner
from lutris.services.lutris import LutrisBanner, LutrisCoverart, LutrisIcon, download_lutris_media
from lutris.util.log import logger
from lutris.util.strings import slugify
from lutris.gui.dialogs.delegates import DialogInstallUIDelegate
# pylint: disable=too-many-instance-attributes, no-member

96
lutris/scanners/tosec.py Normal file
View file

@ -0,0 +1,96 @@
import os
from lutris import settings
from lutris.util import http
from lutris.util.extract import extract_archive
from lutris.util.log import logger
from lutris.util.system import get_md5_hash
archive_formats = [".zip", ".7z", ".rar", ".gz"]
save_formats = [".srm"]
def search_tosec_by_md5(md5sum):
"""Retrieve a lutris bundle from the API"""
if not md5sum:
return []
url = settings.SITE_URL + "/api/tosec/games?md5=" + md5sum
response = http.Request(url, headers={"Content-Type": "application/json"})
try:
response.get()
except http.HTTPError as ex:
logger.error("Unable to get bundle from API: %s", ex)
return None
response_data = response.json
return response_data["results"]
def scan_folder(folder, extract_archives=False):
roms = {}
archives = []
saves = {}
checksums = {}
archive_contents = []
if extract_archives:
for filename in os.listdir(folder):
basename, ext = os.path.splitext(filename)
if ext not in archive_formats:
continue
extract_archive(
os.path.join(folder, filename),
os.path.join(folder, basename),
merge_single=False
)
for archive_file in os.listdir(os.path.join(folder, basename)):
archive_contents.append("%s/%s" % (basename, archive_file))
for filename in os.listdir(folder) + archive_contents:
basename, ext = os.path.splitext(filename)
if ext in archive_formats:
archives.append(filename)
continue
if ext in save_formats:
saves[basename] = filename
continue
if os.path.isdir(os.path.join(folder, filename)):
continue
md5sum = get_md5_hash(os.path.join(folder, filename))
roms[filename] = search_tosec_by_md5(md5sum)
checksums[md5sum] = filename
print(archives)
for rom, result in roms.items():
if not result:
print("no result for %s" % rom)
continue
if len(result) > 1:
print("More than 1 match for %s", rom)
continue
print("Found: %s" % result[0]["name"])
roms_matched = 0
renames = {}
for game_rom in result[0]["roms"]:
source_file = checksums[game_rom["md5"]]
dest_file = game_rom["name"]
renames[source_file] = dest_file
roms_matched += 1
if roms_matched == len(result[0]["roms"]):
for source, dest in renames.items():
base_name, _ext = os.path.splitext(source)
dest_base_name, _ext = os.path.splitext(dest)
if base_name in saves:
save_file = saves[base_name]
_base_name, ext = os.path.splitext(save_file)
os.rename(
os.path.join(folder, save_file),
os.path.join(folder, dest_base_name + ext)
)
try:
os.rename(
os.path.join(folder, source),
os.path.join(folder, dest)
)
except FileNotFoundError:
logger.error("Failed to rename %s to %s", source, dest)