mirror of
https://github.com/lutris/lutris
synced 2024-10-04 14:59:37 +00:00
Add TOSEC scanner/renamer
This commit is contained in:
parent
d7e365b250
commit
1d3519f405
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
96
lutris/scanners/tosec.py
Normal 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)
|
Loading…
Reference in a new issue