mirror of
https://github.com/Omni-guides/Jackify.git
synced 2026-06-08 01:47:45 +02:00
175 lines
7.7 KiB
Python
175 lines
7.7 KiB
Python
"""
|
|
modlist_install_cli.py
|
|
Discovery phase for Jackify's modlist install CLI feature.
|
|
"""
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Optional, Dict, List, Any, Union
|
|
from .protontricks_handler import ProtontricksHandler
|
|
from .shortcut_handler import ShortcutHandler
|
|
from .menu_handler import MenuHandler, ModlistMenuHandler
|
|
from .ui_colors import COLOR_PROMPT, COLOR_INFO, COLOR_ERROR, COLOR_RESET, COLOR_SUCCESS, COLOR_WARNING, COLOR_SELECTION
|
|
# Standard logging (no file handler) - LoggingHandler import removed
|
|
import re
|
|
import subprocess
|
|
import logging
|
|
import sys
|
|
import json
|
|
import shlex
|
|
import time
|
|
import pty
|
|
|
|
# Import UI Colors first - these should always be available
|
|
from .ui_colors import COLOR_PROMPT, COLOR_RESET, COLOR_INFO, COLOR_ERROR, COLOR_SELECTION, COLOR_WARNING
|
|
|
|
# Standard logging (no file handler) - LoggingHandler import removed
|
|
|
|
# Attempt to import readline for tab completion
|
|
READLINE_AVAILABLE = False
|
|
try:
|
|
import readline
|
|
READLINE_AVAILABLE = True
|
|
# Check if running in a non-interactive environment (e.g., some CI)
|
|
if 'libedit' in readline.__doc__:
|
|
# libedit doesn't support set_completion_display_matches_hook
|
|
pass
|
|
# Add other potential checks if needed
|
|
except ImportError:
|
|
# readline not available on Windows or potentially minimal environments
|
|
pass
|
|
except Exception as e:
|
|
# Catch other potential errors during readline import/setup
|
|
logging.warning(f"Readline import failed: {e}") # Use standard logging before our handler
|
|
pass
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
from .modlist_install_cli_discovery import ModlistInstallCLIDiscoveryMixin
|
|
from .modlist_install_cli_configuration import ModlistInstallCLIConfigurationMixin
|
|
from .modlist_install_cli_ttw import ModlistInstallCLITTWMixin
|
|
from .modlist_install_cli_nexus import ModlistInstallCLINexusMixin
|
|
|
|
|
|
def get_jackify_engine_path():
|
|
appdir = os.environ.get('APPDIR')
|
|
if appdir:
|
|
# Running inside AppImage
|
|
# Engine is expected at <appdir>/opt/jackify/engine/jackify-engine
|
|
return os.path.join(appdir, 'opt', 'jackify', 'engine', 'jackify-engine')
|
|
else:
|
|
# Running in a normal Python environment from source
|
|
# Current file is in src/jackify/backend/handlers/modlist_install_cli.py
|
|
# Engine is at src/jackify/engine/jackify-engine
|
|
current_file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
# Navigate up from src/jackify/backend/handlers/ to src/jackify/
|
|
jackify_dir = os.path.dirname(os.path.dirname(current_file_dir))
|
|
return os.path.join(jackify_dir, 'engine', 'jackify-engine')
|
|
|
|
class ModlistInstallCLI(
|
|
ModlistInstallCLIDiscoveryMixin,
|
|
ModlistInstallCLIConfigurationMixin,
|
|
ModlistInstallCLITTWMixin,
|
|
ModlistInstallCLINexusMixin,
|
|
):
|
|
"""
|
|
Handles the discovery phase for installing a Wabbajack modlist via CLI.
|
|
"""
|
|
def __init__(self, menu_handler: MenuHandler, steamdeck: bool = False):
|
|
self.menu_handler = menu_handler
|
|
self.steamdeck = steamdeck
|
|
self.protontricks_handler = ProtontricksHandler(steamdeck)
|
|
self.shortcut_handler = ShortcutHandler(steamdeck=steamdeck)
|
|
self.context = {}
|
|
# Use standard logging (no file handler)
|
|
self.logger = logging.getLogger(__name__)
|
|
self.logger.propagate = False # Prevent duplicate logs if root logger is also configured
|
|
|
|
def _display_summary(self):
|
|
"""
|
|
Display a summary of the collected context (excluding API key).
|
|
"""
|
|
print(f"\n{COLOR_INFO}--- Summary of Collected Information ---{COLOR_RESET}")
|
|
if self.context.get('modlist_source_type') == 'online_list':
|
|
print(f"Modlist Source: Selected from online list")
|
|
print(f"Modlist Identifier: {self.context.get('modlist_value')}")
|
|
print(f"Detected Game: {self.context.get('modlist_game', 'N/A')}")
|
|
elif self.context.get('modlist_source_type') == 'local_file':
|
|
print(f"Modlist Source: Local .wabbajack file")
|
|
print(f"File Path: {self.context.get('modlist_value')}")
|
|
elif 'machineid' in self.context: # For Tuxborn/override flow
|
|
print(f"Modlist Identifier (Tuxborn/MachineID): {self.context.get('machineid')}")
|
|
|
|
print(f"Steam Shortcut Name: {self.context.get('modlist_name', 'N/A')}")
|
|
|
|
install_dir_display = self.context.get('install_dir')
|
|
if isinstance(install_dir_display, tuple):
|
|
install_dir_display = install_dir_display[0] # Get the Path object from (Path, bool)
|
|
print(f"Install Directory: {install_dir_display}")
|
|
|
|
download_dir_display = self.context.get('download_dir')
|
|
if isinstance(download_dir_display, tuple):
|
|
download_dir_display = download_dir_display[0] # Get the Path object from (Path, bool)
|
|
print(f"Download Directory: {download_dir_display}")
|
|
|
|
# Show authentication method
|
|
from jackify.backend.services.nexus_auth_service import NexusAuthService
|
|
auth_service = NexusAuthService()
|
|
authenticated, method, username = auth_service.get_auth_status()
|
|
|
|
if method == 'oauth':
|
|
auth_display = f"Nexus Authentication: OAuth"
|
|
if username:
|
|
auth_display += f" ({username})"
|
|
elif method == 'api_key':
|
|
auth_display = "Nexus Authentication: API Key (Legacy)"
|
|
else:
|
|
# Should never reach here since we validate auth before getting to summary
|
|
auth_display = "Nexus Authentication: Unknown"
|
|
|
|
print(auth_display)
|
|
print(f"{COLOR_INFO}----------------------------------------{COLOR_RESET}")
|
|
|
|
def _display_summary(self):
|
|
# REMOVE pass AND RESTORE THE METHOD BODY
|
|
print(f"\n{COLOR_INFO}--- Summary of Collected Information ---{COLOR_RESET}")
|
|
if self.context.get('modlist_source_type') == 'online_list':
|
|
print(f"Modlist Source: Selected from online list")
|
|
print(f"Modlist Identifier: {self.context.get('modlist_value')}")
|
|
print(f"Detected Game: {self.context.get('modlist_game', 'N/A')}")
|
|
elif self.context.get('modlist_source_type') == 'local_file':
|
|
print(f"Modlist Source: Local .wabbajack file")
|
|
print(f"File Path: {self.context.get('modlist_value')}")
|
|
elif 'machineid' in self.context: # For Tuxborn/override flow
|
|
print(f"Modlist Identifier (Tuxborn/MachineID): {self.context.get('machineid')}")
|
|
|
|
print(f"Steam Shortcut Name: {self.context.get('modlist_name', 'N/A')}")
|
|
|
|
install_dir_display = self.context.get('install_dir')
|
|
if isinstance(install_dir_display, tuple):
|
|
install_dir_display = install_dir_display[0] # Get the Path object from (Path, bool)
|
|
print(f"Install Directory: {install_dir_display}")
|
|
|
|
download_dir_display = self.context.get('download_dir')
|
|
if isinstance(download_dir_display, tuple):
|
|
download_dir_display = download_dir_display[0] # Get the Path object from (Path, bool)
|
|
print(f"Download Directory: {download_dir_display}")
|
|
|
|
# Show authentication method
|
|
from jackify.backend.services.nexus_auth_service import NexusAuthService
|
|
auth_service = NexusAuthService()
|
|
authenticated, method, username = auth_service.get_auth_status()
|
|
|
|
if method == 'oauth':
|
|
auth_display = f"Nexus Authentication: OAuth"
|
|
if username:
|
|
auth_display += f" ({username})"
|
|
elif method == 'api_key':
|
|
auth_display = "Nexus Authentication: API Key (Legacy)"
|
|
else:
|
|
# Should never reach here since we validate auth before getting to summary
|
|
auth_display = "Nexus Authentication: Unknown"
|
|
|
|
print(auth_display)
|
|
print(f"{COLOR_INFO}----------------------------------------{COLOR_RESET}")
|
|
|