Initial public release v0.1.0 - Linux Wabbajack Modlist Application

Jackify provides native Linux support for Wabbajack modlist installation
   and management with automated Steam integration and Proton configuration.

   Key Features:
   - Almost Native Linux implementation (texconv.exe run via proton)
   - Automated Steam shortcut creation and Proton prefix management
   - Both CLI and GUI interfaces, with Steam Deck optimization

   Supported Games:
   - Skyrim Special Edition
   - Fallout 4
   - Fallout New Vegas
   - Oblivion, Starfield, Enderal, and diverse other games

   Technical Architecture:
   - Clean separation between frontend and backend services
   - Powered by jackify-engine 0.3.x for Wabbajack-matching modlist installation
This commit is contained in:
Omni
2025-09-05 20:46:24 +01:00
commit cd591c14e3
445 changed files with 40398 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
"""
Modlist Data Models
Data structures for passing modlist context between frontend and backend.
"""
from pathlib import Path
from typing import Optional, Dict, Any
from dataclasses import dataclass
@dataclass
class ModlistContext:
"""Context object for modlist operations."""
name: str
install_dir: Path
download_dir: Path
game_type: str
nexus_api_key: str
modlist_value: Optional[str] = None
modlist_source: Optional[str] = None # 'identifier' or 'file'
resolution: Optional[str] = None
mo2_exe_path: Optional[Path] = None
skip_confirmation: bool = False
engine_installed: bool = False # True if installed via jackify-engine
def __post_init__(self):
"""Convert string paths to Path objects."""
if isinstance(self.install_dir, str):
self.install_dir = Path(self.install_dir)
if isinstance(self.download_dir, str):
self.download_dir = Path(self.download_dir)
if isinstance(self.mo2_exe_path, str):
self.mo2_exe_path = Path(self.mo2_exe_path)
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary for legacy compatibility."""
return {
'modlist_name': self.name,
'install_dir': str(self.install_dir),
'download_dir': str(self.download_dir),
'game_type': self.game_type,
'nexus_api_key': self.nexus_api_key,
'modlist_value': self.modlist_value,
'modlist_source': self.modlist_source,
'resolution': self.resolution,
'mo2_exe_path': str(self.mo2_exe_path) if self.mo2_exe_path else None,
'skip_confirmation': self.skip_confirmation,
'engine_installed': self.engine_installed,
}
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> 'ModlistContext':
"""Create from dictionary for legacy compatibility."""
return cls(
name=data.get('modlist_name', ''),
install_dir=Path(data.get('install_dir', '')),
download_dir=Path(data.get('download_dir', '')),
game_type=data.get('game_type', ''),
nexus_api_key=data.get('nexus_api_key', ''),
modlist_value=data.get('modlist_value'),
modlist_source=data.get('modlist_source'),
resolution=data.get('resolution'),
mo2_exe_path=Path(data['mo2_exe_path']) if data.get('mo2_exe_path') else None,
skip_confirmation=data.get('skip_confirmation', False),
engine_installed=data.get('engine_installed', False),
)
@dataclass
class ModlistInfo:
"""Information about a modlist from the engine."""
id: str
name: str
game: str
description: Optional[str] = None
version: Optional[str] = None
size: Optional[str] = None
def to_dict(self) -> Dict[str, Any]:
"""Convert to dictionary."""
result = {
'id': self.id,
'name': self.name,
'game': self.game,
'description': self.description,
'version': self.version,
'size': self.size,
}
# Include any dynamically added attributes
if hasattr(self, 'machine_url'):
result['machine_url'] = self.machine_url
if hasattr(self, 'download_size'):
result['download_size'] = self.download_size
if hasattr(self, 'install_size'):
result['install_size'] = self.install_size
if hasattr(self, 'total_size'):
result['total_size'] = self.total_size
if hasattr(self, 'status_down'):
result['status_down'] = self.status_down
if hasattr(self, 'status_nsfw'):
result['status_nsfw'] = self.status_nsfw
return result