mirror of
https://github.com/derrod/legendary.git
synced 2024-12-22 17:55:27 +00:00
[core/utils] Attempt to find save path case-insensitively
This commit is contained in:
parent
106ed16a49
commit
aaf7e0934f
|
@ -37,7 +37,7 @@ from legendary.utils.game_workarounds import is_opt_enabled, update_workarounds
|
||||||
from legendary.utils.savegame_helper import SaveGameHelper
|
from legendary.utils.savegame_helper import SaveGameHelper
|
||||||
from legendary.utils.selective_dl import games as sdl_games
|
from legendary.utils.selective_dl import games as sdl_games
|
||||||
from legendary.utils.manifests import combine_manifests
|
from legendary.utils.manifests import combine_manifests
|
||||||
from legendary.utils.wine_helpers import read_registry, get_shell_folders
|
from legendary.utils.wine_helpers import read_registry, get_shell_folders, case_insensitive_path_search
|
||||||
|
|
||||||
|
|
||||||
# ToDo: instead of true/false return values for success/failure actually raise an exception that the CLI/GUI
|
# ToDo: instead of true/false return values for success/failure actually raise an exception that the CLI/GUI
|
||||||
|
@ -696,7 +696,12 @@ class LegendaryCore:
|
||||||
|
|
||||||
# these paths should always use a forward slash
|
# these paths should always use a forward slash
|
||||||
new_save_path = [path_vars.get(p.lower(), p) for p in save_path.split('/')]
|
new_save_path = [path_vars.get(p.lower(), p) for p in save_path.split('/')]
|
||||||
return os.path.realpath(os.path.join(*new_save_path))
|
absolute_path = os.path.realpath(os.path.join(*new_save_path))
|
||||||
|
# attempt to resolve as much as possible on case-insensitive file-systems
|
||||||
|
if os.name != 'nt':
|
||||||
|
absolute_path = case_insensitive_path_search(absolute_path)
|
||||||
|
|
||||||
|
return absolute_path
|
||||||
|
|
||||||
def check_savegame_state(self, path: str, save: SaveGameFile) -> (SaveGameStatus, (datetime, datetime)):
|
def check_savegame_state(self, path: str, save: SaveGameFile) -> (SaveGameStatus, (datetime, datetime)):
|
||||||
latest = 0
|
latest = 0
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import os
|
|
||||||
import configparser
|
import configparser
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
logger = logging.getLogger('WineHelpers')
|
||||||
|
|
||||||
|
|
||||||
def read_registry(wine_pfx):
|
def read_registry(wine_pfx):
|
||||||
|
@ -15,3 +18,45 @@ def get_shell_folders(registry, wine_pfx):
|
||||||
path_cleaned = v.strip('"').strip().replace('\\\\', '/').replace('C:/', '')
|
path_cleaned = v.strip('"').strip().replace('\\\\', '/').replace('C:/', '')
|
||||||
folders[k.strip('"').strip()] = os.path.join(wine_pfx, 'drive_c', path_cleaned)
|
folders[k.strip('"').strip()] = os.path.join(wine_pfx, 'drive_c', path_cleaned)
|
||||||
return folders
|
return folders
|
||||||
|
|
||||||
|
|
||||||
|
def case_insensitive_path_search(path):
|
||||||
|
"""
|
||||||
|
Attempts to find a path case-insensitively
|
||||||
|
"""
|
||||||
|
# Legendary's save path resolver always returns absolute paths, so this is not as horrible as it looks
|
||||||
|
path_parts = path.replace('\\', '/').split('/')
|
||||||
|
path_parts[0] = '/'
|
||||||
|
# filter out empty parts
|
||||||
|
path_parts = [i for i in path_parts if i]
|
||||||
|
|
||||||
|
# attempt to find lowest level directory that exists case-sensitively
|
||||||
|
longest_path = ''
|
||||||
|
remaining_parts = []
|
||||||
|
for i in range(len(path_parts), 0, -1):
|
||||||
|
if os.path.exists(os.path.join(*path_parts[:i])):
|
||||||
|
longest_path = path_parts[:i]
|
||||||
|
remaining_parts = path_parts[i:]
|
||||||
|
break
|
||||||
|
logger.debug(f'Longest valid path: {longest_path}')
|
||||||
|
logger.debug(f'Remaining parts: {remaining_parts}')
|
||||||
|
|
||||||
|
# Iterate over remaining parts, find matching directories case-insensitively
|
||||||
|
still_remaining = []
|
||||||
|
for idx, part in enumerate(remaining_parts):
|
||||||
|
for item in os.listdir(os.path.join(*longest_path)):
|
||||||
|
if not os.path.isdir(os.path.join(*longest_path, item)):
|
||||||
|
continue
|
||||||
|
if item.lower() == part.lower():
|
||||||
|
longest_path.append(item)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# once we stop finding parts break
|
||||||
|
still_remaining = remaining_parts[idx-1:]
|
||||||
|
break
|
||||||
|
|
||||||
|
logger.debug(f'New longest path: {longest_path}')
|
||||||
|
logger.debug(f'Still unresolved: {still_remaining}')
|
||||||
|
final_path = os.path.join(*longest_path, *still_remaining)
|
||||||
|
logger.debug('Final path:', final_path)
|
||||||
|
return os.path.realpath(final_path)
|
||||||
|
|
Loading…
Reference in a new issue