-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpath_manager.py
More file actions
executable file
·115 lines (93 loc) · 3.38 KB
/
path_manager.py
File metadata and controls
executable file
·115 lines (93 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# Game Chooser - A desktop game library manager
# Copyright (C) 2025 Alec Olson
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
import stat
import platform
from pathlib import Path
class PathManager:
"""Centralized path operations and normalization."""
@staticmethod
def normalize(path):
"""
Normalize a path to use forward slashes.
Args:
path: Path string or Path object
Returns:
String with forward slashes
"""
if isinstance(path, Path):
path = str(path)
return path.replace('\\', '/').strip()
@staticmethod
def to_library_relative(full_path, library_paths):
"""
Convert an absolute path to library-relative.
Args:
full_path: Absolute path to convert
library_paths: List of library path dictionaries
Returns:
Library-relative path string or None if not in any library
"""
full_path = Path(full_path).resolve()
for lib in library_paths:
lib_path = Path(lib["path"]).resolve()
try:
rel_path = full_path.relative_to(lib_path)
return PathManager.normalize(rel_path)
except ValueError:
continue
return None
@staticmethod
def get_full_path(launch_path, library_paths, library_name):
"""
Convert a library-relative path to absolute.
Args:
launch_path: Library-relative path
library_paths: List of library path dictionaries
library_name: Name of the library containing the game
Returns:
Absolute path as string or None if library not found
"""
# Handle special cases
if launch_path.startswith("http"):
return launch_path
if library_name == "manual" or library_name == "":
return launch_path
# Find library
for lib in library_paths:
if lib["name"] == library_name:
lib_path = Path(lib["path"])
full_path = lib_path / launch_path
return str(full_path)
return None
@staticmethod
def is_executable(path):
"""
Check if a path is an executable game file.
Only detects Windows (.exe, .bat) and macOS (.app) games.
Linux support has been removed for simplicity.
Args:
path: Path object to check
Returns:
bool: True if file is a game executable
"""
# macOS .app bundles (directories)
if path.suffix.lower() == '.app' and path.is_dir():
return True
# Windows executables and batch files only
if path.is_file() and path.suffix.lower() in ['.exe', '.bat']:
return True
return False