2 Commits

Author SHA1 Message Date
Tickbase
fc4466048e Added logging incase script fails and additional search directories 2024-07-13 16:27:27 +02:00
Tickbase
917b787a72 Update README.md 2024-07-13 04:35:18 +02:00
2 changed files with 59 additions and 43 deletions

View File

@@ -26,7 +26,7 @@ https://www.youtube.com/watch?v=22LDDUoBvus&ab_channel=Nova
- Navigate to the directory containing the script. - Navigate to the directory containing the script.
- Run the script using python. - Run the script using python.
```bash ```bash
python steam_dlc_fetcher.py python dlc_fetcher.py
``` ```
# Issues? # Issues?

View File

@@ -5,6 +5,8 @@ import zipfile
import time import time
import stat import stat
LOG_FILE = 'script.log'
def clear_screen(): def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear') os.system('cls' if os.name == 'nt' else 'clear')
@@ -14,6 +16,7 @@ def fetch_latest_version():
data = response.json() data = response.json()
return data['tag_name'] return data['tag_name']
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
log_message(f"Failed to fetch latest version: {str(e)}")
return "Unknown" return "Unknown"
def show_header(app_version): def show_header(app_version):
@@ -39,6 +42,11 @@ def show_header(app_version):
app_version = fetch_latest_version() app_version = fetch_latest_version()
def log_message(message):
with open(LOG_FILE, 'a') as log_file:
log_file.write(f"{message}\n")
print(message)
def parse_vdf(file_path): def parse_vdf(file_path):
library_paths = [] library_paths = []
try: try:
@@ -47,7 +55,7 @@ def parse_vdf(file_path):
paths = re.findall(r'"path"\s*"(.*?)"', content, re.IGNORECASE) paths = re.findall(r'"path"\s*"(.*?)"', content, re.IGNORECASE)
library_paths.extend([os.path.normpath(path) for path in paths]) library_paths.extend([os.path.normpath(path) for path in paths])
except Exception as e: except Exception as e:
print(f"Failed to read {file_path}: {str(e)}") log_message(f"Failed to read {file_path}: {str(e)}")
return library_paths return library_paths
def find_steam_library_folders(): def find_steam_library_folders():
@@ -56,41 +64,52 @@ def find_steam_library_folders():
os.path.expanduser('~/.local/share/Steam'), os.path.expanduser('~/.local/share/Steam'),
os.path.expanduser('~/home/deck/.steam/steam'), os.path.expanduser('~/home/deck/.steam/steam'),
os.path.expanduser('~/home/deck/.local/share/Steam'), os.path.expanduser('~/home/deck/.local/share/Steam'),
'/mnt', '/media' '/mnt', '/media',
'/run/media/mmcblk0p1/steamapps'
] ]
library_folders = [] library_folders = []
for base_path in base_paths: try:
if os.path.exists(base_path): for base_path in base_paths:
for root, dirs, files in os.walk(base_path, topdown=True): if os.path.exists(base_path):
if 'steamapps' in dirs: for root, dirs, files in os.walk(base_path, topdown=True):
steamapps_path = os.path.join(root, 'steamapps') if 'steamapps' in dirs:
library_folders.append(steamapps_path) steamapps_path = os.path.join(root, 'steamapps')
vdf_path = os.path.join(steamapps_path, 'libraryfolders.vdf') library_folders.append(steamapps_path)
if os.path.exists(vdf_path): vdf_path = os.path.join(steamapps_path, 'libraryfolders.vdf')
additional_paths = parse_vdf(vdf_path) if os.path.exists(vdf_path):
for path in additional_paths: additional_paths = parse_vdf(vdf_path)
new_steamapps_path = os.path.join(path, 'steamapps') for path in additional_paths:
if os.path.exists(new_steamapps_path): new_steamapps_path = os.path.join(path, 'steamapps')
library_folders.append(new_steamapps_path) if os.path.exists(new_steamapps_path):
dirs[:] = [] # Prevent further scanning into subdirectories library_folders.append(new_steamapps_path)
dirs[:] = [] # Prevent further scanning into subdirectories
if not library_folders:
raise FileNotFoundError("No Steam library folders found.")
except Exception as e:
log_message(f"Error finding Steam library folders: {e}")
return library_folders return library_folders
def find_steam_apps(library_folders): def find_steam_apps(library_folders):
acf_pattern = re.compile(r'^appmanifest_(\d+)\.acf$') acf_pattern = re.compile(r'^appmanifest_(\d+)\.acf$')
games = {} games = {}
for folder in library_folders: try:
if os.path.exists(folder): for folder in library_folders:
for item in os.listdir(folder): if os.path.exists(folder):
if acf_pattern.match(item): for item in os.listdir(folder):
try: if acf_pattern.match(item):
app_id, game_name, install_dir = parse_acf(os.path.join(folder, item)) try:
if app_id and game_name: app_id, game_name, install_dir = parse_acf(os.path.join(folder, item))
install_path = os.path.join(folder, 'common', install_dir) if app_id and game_name:
if os.path.exists(install_path): install_path = os.path.join(folder, 'common', install_dir)
cream_installed = 'Cream installed' if 'cream.sh' in os.listdir(install_path) else '' if os.path.exists(install_path):
games[app_id] = (game_name, cream_installed, install_path) cream_installed = 'Cream installed' if 'cream.sh' in os.listdir(install_path) else ''
except Exception as e: games[app_id] = (game_name, cream_installed, install_path)
print(f"Error parsing {item}: {e}") except Exception as e:
log_message(f"Error parsing {item}: {e}")
if not games:
raise FileNotFoundError("No Steam games found.")
except Exception as e:
log_message(f"Error finding Steam apps: {e}")
return games return games
def parse_acf(file_path): def parse_acf(file_path):
@@ -102,7 +121,7 @@ def parse_acf(file_path):
install_dir = re.search(r'"installdir"\s+"([^"]+)"', data) install_dir = re.search(r'"installdir"\s+"([^"]+)"', data)
return app_id.group(1), name.group(1), install_dir.group(1) return app_id.group(1), name.group(1), install_dir.group(1)
except Exception as e: except Exception as e:
print(f"Error reading ACF file {file_path}: {e}") log_message(f"Error reading ACF file {file_path}: {e}")
return None, None, None return None, None, None
def fetch_dlc_details(app_id): def fetch_dlc_details(app_id):
@@ -111,7 +130,7 @@ def fetch_dlc_details(app_id):
response = requests.get(base_url) response = requests.get(base_url)
data = response.json() data = response.json()
if app_id not in data or "data" not in data[app_id]: if app_id not in data or "data" not in data[app_id]:
print("Error: Unable to fetch game details.") log_message("Error: Unable to fetch game details.")
return [] return []
game_data = data[app_id]["data"] game_data = data[app_id]["data"]
dlcs = game_data.get("dlc", []) dlcs = game_data.get("dlc", [])
@@ -127,17 +146,17 @@ def fetch_dlc_details(app_id):
dlc_name = dlc_data[str(dlc_id)]["data"].get("name", "Unknown DLC") dlc_name = dlc_data[str(dlc_id)]["data"].get("name", "Unknown DLC")
dlc_details.append({"appid": dlc_id, "name": dlc_name}) dlc_details.append({"appid": dlc_id, "name": dlc_name})
else: else:
print(f"Data missing for DLC {dlc_id}") log_message(f"Data missing for DLC {dlc_id}")
elif dlc_response.status_code == 429: elif dlc_response.status_code == 429:
print("Rate limited! Please wait before trying again.") log_message("Rate limited! Please wait before trying again.")
time.sleep(10) time.sleep(10)
else: else:
print(f"Failed to fetch details for DLC {dlc_id}, Status Code: {dlc_response.status_code}") log_message(f"Failed to fetch details for DLC {dlc_id}, Status Code: {dlc_response.status_code}")
except Exception as e: except Exception as e:
print(f"Exception for DLC {dlc_id}: {str(e)}") log_message(f"Exception for DLC {dlc_id}: {str(e)}")
return dlc_details return dlc_details
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
print(f"Failed to fetch DLC details for {app_id}: {e}") log_message(f"Failed to fetch DLC details for {app_id}: {e}")
return [] return []
def install_files(app_id, game_install_dir, dlcs, game_name): def install_files(app_id, game_install_dir, dlcs, game_name):
@@ -162,16 +181,14 @@ def install_files(app_id, game_install_dir, dlcs, game_name):
print(f"Custom cream_api.ini has been written to {game_install_dir}.") print(f"Custom cream_api.ini has been written to {game_install_dir}.")
print(f"Installation complete. Set launch options in Steam: 'sh ./cream.sh %command%' for {game_name}.") print(f"Installation complete. Set launch options in Steam: 'sh ./cream.sh %command%' for {game_name}.")
else: else:
print("Failed to download the files needed for installation.") log_message("Failed to download the files needed for installation.")
except Exception as e: except Exception as e:
print(f"Failed to install files for {game_name}: {e}") log_message(f"Failed to install files for {game_name}: {e}")
def main(): def main():
show_header(app_version) show_header(app_version)
try: try:
library_folders = find_steam_library_folders() library_folders = find_steam_library_folders()
if not library_folders:
raise FileNotFoundError("No Steam library folders found.")
games = find_steam_apps(library_folders) games = find_steam_apps(library_folders)
if games: if games:
print("Select the game for which you want to fetch DLCs:") print("Select the game for which you want to fetch DLCs:")
@@ -199,8 +216,7 @@ def main():
else: else:
print("No Steam games found on this computer or connected drives.") print("No Steam games found on this computer or connected drives.")
except Exception as e: except Exception as e:
print(f"An error occurred: {e}") log_message(f"An error occurred: {e}")
if __name__ == "__main__": if __name__ == "__main__":
main() main()