mirror of
https://github.com/Omni-guides/Jackify.git
synced 2026-01-17 11:37:01 +01:00
Sync from development - prepare for v0.2.0.6
This commit is contained in:
@@ -5,4 +5,4 @@ This package provides both CLI and GUI interfaces for managing
|
||||
Wabbajack modlists natively on Linux systems.
|
||||
"""
|
||||
|
||||
__version__ = "0.2.0.5"
|
||||
__version__ = "0.2.0.6"
|
||||
|
||||
@@ -142,6 +142,11 @@ class OAuthTokenHandler:
|
||||
"""
|
||||
try:
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
# Check if MODE_GCM is available (pycryptodome has it, old pycrypto doesn't)
|
||||
if not hasattr(AES, 'MODE_GCM'):
|
||||
logger.error("pycryptodome required for token decryption (pycrypto doesn't support MODE_GCM)")
|
||||
return None
|
||||
|
||||
# Derive 32-byte AES key from encryption_key
|
||||
key = base64.urlsafe_b64decode(self._encryption_key)
|
||||
@@ -163,6 +168,9 @@ class OAuthTokenHandler:
|
||||
except ImportError:
|
||||
logger.error("pycryptodome package not available for token decryption")
|
||||
return None
|
||||
except AttributeError:
|
||||
logger.error("pycryptodome required for token decryption (pycrypto doesn't support MODE_GCM)")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to decrypt data: {e}")
|
||||
return None
|
||||
|
||||
@@ -48,6 +48,9 @@ def get_clean_subprocess_env(extra_env=None):
|
||||
|
||||
env = os.environ.copy()
|
||||
|
||||
# Save APPDIR before removing it (we need it to find bundled tools)
|
||||
appdir = env.get('APPDIR')
|
||||
|
||||
# Remove AppImage-specific variables that can confuse subprocess calls
|
||||
# These variables cause subprocesses to be interpreted as new AppImage launches
|
||||
for key in ['APPIMAGE', 'APPDIR', 'ARGV0', 'OWD']:
|
||||
@@ -57,10 +60,10 @@ def get_clean_subprocess_env(extra_env=None):
|
||||
for k in list(env):
|
||||
if k.startswith('_MEIPASS'):
|
||||
del env[k]
|
||||
|
||||
|
||||
# Get current PATH - ensure we preserve system paths
|
||||
current_path = env.get('PATH', '')
|
||||
|
||||
|
||||
# Ensure common system directories are in PATH if not already present
|
||||
# This is critical for tools like lz4 that might be in /usr/bin, /usr/local/bin, etc.
|
||||
system_paths = ['/usr/bin', '/usr/local/bin', '/bin', '/sbin', '/usr/sbin']
|
||||
@@ -68,10 +71,10 @@ def get_clean_subprocess_env(extra_env=None):
|
||||
for sys_path in system_paths:
|
||||
if sys_path not in path_parts and os.path.isdir(sys_path):
|
||||
path_parts.append(sys_path)
|
||||
|
||||
|
||||
# Add bundled tools directory to PATH if running as AppImage
|
||||
# This ensures lz4, unzip, xz, etc. are available to subprocesses
|
||||
appdir = env.get('APPDIR')
|
||||
# Note: appdir was saved before env cleanup above
|
||||
tools_dir = None
|
||||
|
||||
if appdir:
|
||||
|
||||
@@ -34,9 +34,6 @@ def is_non_premium_indicator(line: str) -> bool:
|
||||
if phrase in normalized:
|
||||
return True
|
||||
|
||||
if "nexus" in normalized and "premium" in normalized:
|
||||
return True
|
||||
|
||||
# Manual download + Nexus URL implies premium requirement in current workflows.
|
||||
if "manual download" in normalized and ("nexusmods.com" in normalized or "nexus mods" in normalized):
|
||||
return True
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,7 +7,7 @@
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {},
|
||||
".NETCoreApp,Version=v8.0/linux-x64": {
|
||||
"jackify-engine/0.4.3": {
|
||||
"jackify-engine/0.4.4": {
|
||||
"dependencies": {
|
||||
"Markdig": "0.40.0",
|
||||
"Microsoft.Extensions.Configuration.Json": "9.0.1",
|
||||
@@ -22,16 +22,16 @@
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"System.CommandLine": "2.0.0-beta4.22272.1",
|
||||
"System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1",
|
||||
"Wabbajack.CLI.Builder": "0.4.3",
|
||||
"Wabbajack.Downloaders.Bethesda": "0.4.3",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.3",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Networking.Discord": "0.4.3",
|
||||
"Wabbajack.Networking.GitHub": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3",
|
||||
"Wabbajack.Server.Lib": "0.4.3",
|
||||
"Wabbajack.Services.OSIntegrated": "0.4.3",
|
||||
"Wabbajack.VFS": "0.4.3",
|
||||
"Wabbajack.CLI.Builder": "0.4.4",
|
||||
"Wabbajack.Downloaders.Bethesda": "0.4.4",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.4",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Networking.Discord": "0.4.4",
|
||||
"Wabbajack.Networking.GitHub": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4",
|
||||
"Wabbajack.Server.Lib": "0.4.4",
|
||||
"Wabbajack.Services.OSIntegrated": "0.4.4",
|
||||
"Wabbajack.VFS": "0.4.4",
|
||||
"MegaApiClient": "1.0.0.0",
|
||||
"runtimepack.Microsoft.NETCore.App.Runtime.linux-x64": "8.0.22"
|
||||
},
|
||||
@@ -1781,7 +1781,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Wabbajack.CLI.Builder/0.4.3": {
|
||||
"Wabbajack.CLI.Builder/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Json": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
@@ -1791,109 +1791,109 @@
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"System.CommandLine": "2.0.0-beta4.22272.1",
|
||||
"System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1",
|
||||
"Wabbajack.Paths": "0.4.3"
|
||||
"Wabbajack.Paths": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.CLI.Builder.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Common/0.4.3": {
|
||||
"Wabbajack.Common/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"System.Reactive": "6.0.1",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Common.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Compiler/0.4.3": {
|
||||
"Wabbajack.Compiler/0.4.4": {
|
||||
"dependencies": {
|
||||
"F23.StringSimilarity": "6.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.3",
|
||||
"Wabbajack.Installer": "0.4.3",
|
||||
"Wabbajack.VFS": "0.4.3",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.4",
|
||||
"Wabbajack.Installer": "0.4.4",
|
||||
"Wabbajack.VFS": "0.4.4",
|
||||
"ini-parser-netstandard": "2.5.2"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Compiler.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Compression.BSA/0.4.3": {
|
||||
"Wabbajack.Compression.BSA/0.4.4": {
|
||||
"dependencies": {
|
||||
"K4os.Compression.LZ4.Streams": "1.3.8",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"SharpZipLib": "1.4.2",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Compression.BSA.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Compression.Zip/0.4.3": {
|
||||
"Wabbajack.Compression.Zip/0.4.4": {
|
||||
"dependencies": {
|
||||
"Wabbajack.IO.Async": "0.4.3"
|
||||
"Wabbajack.IO.Async": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Compression.Zip.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Configuration/0.4.3": {
|
||||
"Wabbajack.Configuration/0.4.4": {
|
||||
"runtime": {
|
||||
"Wabbajack.Configuration.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Bethesda/0.4.3": {
|
||||
"Wabbajack.Downloaders.Bethesda/0.4.4": {
|
||||
"dependencies": {
|
||||
"LibAES-CTR": "1.1.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"SharpZipLib": "1.4.2",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Bethesda.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Dispatcher/0.4.3": {
|
||||
"Wabbajack.Downloaders.Dispatcher/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Downloaders.Bethesda": "0.4.3",
|
||||
"Wabbajack.Downloaders.GameFile": "0.4.3",
|
||||
"Wabbajack.Downloaders.GoogleDrive": "0.4.3",
|
||||
"Wabbajack.Downloaders.Http": "0.4.3",
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Downloaders.Manual": "0.4.3",
|
||||
"Wabbajack.Downloaders.MediaFire": "0.4.3",
|
||||
"Wabbajack.Downloaders.Mega": "0.4.3",
|
||||
"Wabbajack.Downloaders.ModDB": "0.4.3",
|
||||
"Wabbajack.Downloaders.Nexus": "0.4.3",
|
||||
"Wabbajack.Downloaders.VerificationCache": "0.4.3",
|
||||
"Wabbajack.Downloaders.WabbajackCDN": "0.4.3",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.3"
|
||||
"Wabbajack.Downloaders.Bethesda": "0.4.4",
|
||||
"Wabbajack.Downloaders.GameFile": "0.4.4",
|
||||
"Wabbajack.Downloaders.GoogleDrive": "0.4.4",
|
||||
"Wabbajack.Downloaders.Http": "0.4.4",
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Downloaders.Manual": "0.4.4",
|
||||
"Wabbajack.Downloaders.MediaFire": "0.4.4",
|
||||
"Wabbajack.Downloaders.Mega": "0.4.4",
|
||||
"Wabbajack.Downloaders.ModDB": "0.4.4",
|
||||
"Wabbajack.Downloaders.Nexus": "0.4.4",
|
||||
"Wabbajack.Downloaders.VerificationCache": "0.4.4",
|
||||
"Wabbajack.Downloaders.WabbajackCDN": "0.4.4",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Dispatcher.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.GameFile/0.4.3": {
|
||||
"Wabbajack.Downloaders.GameFile/0.4.4": {
|
||||
"dependencies": {
|
||||
"GameFinder.StoreHandlers.EADesktop": "4.5.0",
|
||||
"GameFinder.StoreHandlers.EGS": "4.5.0",
|
||||
@@ -1903,360 +1903,360 @@
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.VFS": "0.4.3"
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.VFS": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.GameFile.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.GoogleDrive/0.4.3": {
|
||||
"Wabbajack.Downloaders.GoogleDrive/0.4.4": {
|
||||
"dependencies": {
|
||||
"HtmlAgilityPack": "1.11.72",
|
||||
"Microsoft.AspNetCore.Http.Extensions": "2.3.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.GoogleDrive.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Http/0.4.3": {
|
||||
"Wabbajack.Downloaders.Http/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Http.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Interfaces/0.4.3": {
|
||||
"Wabbajack.Downloaders.Interfaces/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Wabbajack.Compression.Zip": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.Compression.Zip": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Interfaces.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.4.3": {
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.4.4": {
|
||||
"dependencies": {
|
||||
"F23.StringSimilarity": "6.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Manual/0.4.3": {
|
||||
"Wabbajack.Downloaders.Manual/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Manual.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.MediaFire/0.4.3": {
|
||||
"Wabbajack.Downloaders.MediaFire/0.4.4": {
|
||||
"dependencies": {
|
||||
"HtmlAgilityPack": "1.11.72",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.MediaFire.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Mega/0.4.3": {
|
||||
"Wabbajack.Downloaders.Mega/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Mega.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.ModDB/0.4.3": {
|
||||
"Wabbajack.Downloaders.ModDB/0.4.4": {
|
||||
"dependencies": {
|
||||
"HtmlAgilityPack": "1.11.72",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.ModDB.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.Nexus/0.4.3": {
|
||||
"Wabbajack.Downloaders.Nexus/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.NexusApi": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.NexusApi": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.Nexus.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.VerificationCache/0.4.3": {
|
||||
"Wabbajack.Downloaders.VerificationCache/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Stub.System.Data.SQLite.Core.NetStandard": "1.0.119",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.VerificationCache.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Downloaders.WabbajackCDN/0.4.3": {
|
||||
"Wabbajack.Downloaders.WabbajackCDN/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Microsoft.Toolkit.HighPerformance": "7.1.2",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.RateLimiter": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.RateLimiter": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Downloaders.WabbajackCDN.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.DTOs/0.4.3": {
|
||||
"Wabbajack.DTOs/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3"
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.DTOs.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.FileExtractor/0.4.3": {
|
||||
"Wabbajack.FileExtractor/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"OMODFramework": "3.0.1",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Compression.BSA": "0.4.3",
|
||||
"Wabbajack.Hashing.PHash": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Compression.BSA": "0.4.4",
|
||||
"Wabbajack.Hashing.PHash": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.FileExtractor.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Hashing.PHash/0.4.3": {
|
||||
"Wabbajack.Hashing.PHash/0.4.4": {
|
||||
"dependencies": {
|
||||
"BCnEncoder.Net.ImageSharp": "1.1.1",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Shipwreck.Phash": "0.5.0",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Hashing.PHash.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Hashing.xxHash64/0.4.3": {
|
||||
"Wabbajack.Hashing.xxHash64/0.4.4": {
|
||||
"dependencies": {
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.RateLimiter": "0.4.3"
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"Wabbajack.RateLimiter": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Hashing.xxHash64.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Installer/0.4.3": {
|
||||
"Wabbajack.Installer/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"Octopus.Octodiff": "2.0.548",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.3",
|
||||
"Wabbajack.Downloaders.GameFile": "0.4.3",
|
||||
"Wabbajack.FileExtractor": "0.4.3",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3",
|
||||
"Wabbajack.VFS": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.4",
|
||||
"Wabbajack.Downloaders.GameFile": "0.4.4",
|
||||
"Wabbajack.FileExtractor": "0.4.4",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4",
|
||||
"Wabbajack.VFS": "0.4.4",
|
||||
"ini-parser-netstandard": "2.5.2"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Installer.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.IO.Async/0.4.3": {
|
||||
"Wabbajack.IO.Async/0.4.4": {
|
||||
"runtime": {
|
||||
"Wabbajack.IO.Async.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.BethesdaNet/0.4.3": {
|
||||
"Wabbajack.Networking.BethesdaNet/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.BethesdaNet.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.Discord/0.4.3": {
|
||||
"Wabbajack.Networking.Discord/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.Discord.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.GitHub/0.4.3": {
|
||||
"Wabbajack.Networking.GitHub/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Octokit": "14.0.0",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.GitHub.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.Http/0.4.3": {
|
||||
"Wabbajack.Networking.Http/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Http": "9.0.1",
|
||||
"Microsoft.Extensions.Logging": "9.0.1",
|
||||
"Wabbajack.Configuration": "0.4.3",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.3",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3"
|
||||
"Wabbajack.Configuration": "0.4.4",
|
||||
"Wabbajack.Downloaders.Interfaces": "0.4.4",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.Http.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.Http.Interfaces/0.4.3": {
|
||||
"Wabbajack.Networking.Http.Interfaces/0.4.4": {
|
||||
"dependencies": {
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3"
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.Http.Interfaces.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.NexusApi/0.4.3": {
|
||||
"Wabbajack.Networking.NexusApi/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Networking.Http": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Networking.Http": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4",
|
||||
"Wabbajack.Networking.WabbajackClientApi": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.NexusApi.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Networking.WabbajackClientApi/0.4.3": {
|
||||
"Wabbajack.Networking.WabbajackClientApi/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"Octokit": "14.0.0",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3",
|
||||
"Wabbajack.VFS.Interfaces": "0.4.3",
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4",
|
||||
"Wabbajack.VFS.Interfaces": "0.4.4",
|
||||
"YamlDotNet": "16.3.0"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Networking.WabbajackClientApi.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Paths/0.4.3": {
|
||||
"Wabbajack.Paths/0.4.4": {
|
||||
"runtime": {
|
||||
"Wabbajack.Paths.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Paths.IO/0.4.3": {
|
||||
"Wabbajack.Paths.IO/0.4.4": {
|
||||
"dependencies": {
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"shortid": "4.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Paths.IO.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.RateLimiter/0.4.3": {
|
||||
"Wabbajack.RateLimiter/0.4.4": {
|
||||
"runtime": {
|
||||
"Wabbajack.RateLimiter.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Server.Lib/0.4.3": {
|
||||
"Wabbajack.Server.Lib/0.4.4": {
|
||||
"dependencies": {
|
||||
"FluentFTP": "52.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
@@ -2264,58 +2264,58 @@
|
||||
"Nettle": "3.0.0",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.3",
|
||||
"Wabbajack.Services.OSIntegrated": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.Networking.Http.Interfaces": "0.4.4",
|
||||
"Wabbajack.Services.OSIntegrated": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Server.Lib.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.Services.OSIntegrated/0.4.3": {
|
||||
"Wabbajack.Services.OSIntegrated/0.4.4": {
|
||||
"dependencies": {
|
||||
"DeviceId": "6.8.0",
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Newtonsoft.Json": "13.0.3",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"Wabbajack.Compiler": "0.4.3",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.3",
|
||||
"Wabbajack.Installer": "0.4.3",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.3",
|
||||
"Wabbajack.Networking.Discord": "0.4.3",
|
||||
"Wabbajack.VFS": "0.4.3"
|
||||
"Wabbajack.Compiler": "0.4.4",
|
||||
"Wabbajack.Downloaders.Dispatcher": "0.4.4",
|
||||
"Wabbajack.Installer": "0.4.4",
|
||||
"Wabbajack.Networking.BethesdaNet": "0.4.4",
|
||||
"Wabbajack.Networking.Discord": "0.4.4",
|
||||
"Wabbajack.VFS": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.Services.OSIntegrated.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.VFS/0.4.3": {
|
||||
"Wabbajack.VFS/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
|
||||
"SixLabors.ImageSharp": "3.1.6",
|
||||
"System.Data.SQLite.Core": "1.0.119",
|
||||
"Wabbajack.Common": "0.4.3",
|
||||
"Wabbajack.FileExtractor": "0.4.3",
|
||||
"Wabbajack.Hashing.PHash": "0.4.3",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3",
|
||||
"Wabbajack.Paths.IO": "0.4.3",
|
||||
"Wabbajack.VFS.Interfaces": "0.4.3"
|
||||
"Wabbajack.Common": "0.4.4",
|
||||
"Wabbajack.FileExtractor": "0.4.4",
|
||||
"Wabbajack.Hashing.PHash": "0.4.4",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4",
|
||||
"Wabbajack.Paths.IO": "0.4.4",
|
||||
"Wabbajack.VFS.Interfaces": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.VFS.dll": {}
|
||||
}
|
||||
},
|
||||
"Wabbajack.VFS.Interfaces/0.4.3": {
|
||||
"Wabbajack.VFS.Interfaces/0.4.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection": "9.0.1",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
|
||||
"Wabbajack.DTOs": "0.4.3",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.3",
|
||||
"Wabbajack.Paths": "0.4.3"
|
||||
"Wabbajack.DTOs": "0.4.4",
|
||||
"Wabbajack.Hashing.xxHash64": "0.4.4",
|
||||
"Wabbajack.Paths": "0.4.4"
|
||||
},
|
||||
"runtime": {
|
||||
"Wabbajack.VFS.Interfaces.dll": {}
|
||||
@@ -2332,7 +2332,7 @@
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"jackify-engine/0.4.3": {
|
||||
"jackify-engine/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
@@ -3021,202 +3021,202 @@
|
||||
"path": "yamldotnet/16.3.0",
|
||||
"hashPath": "yamldotnet.16.3.0.nupkg.sha512"
|
||||
},
|
||||
"Wabbajack.CLI.Builder/0.4.3": {
|
||||
"Wabbajack.CLI.Builder/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Common/0.4.3": {
|
||||
"Wabbajack.Common/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Compiler/0.4.3": {
|
||||
"Wabbajack.Compiler/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Compression.BSA/0.4.3": {
|
||||
"Wabbajack.Compression.BSA/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Compression.Zip/0.4.3": {
|
||||
"Wabbajack.Compression.Zip/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Configuration/0.4.3": {
|
||||
"Wabbajack.Configuration/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Bethesda/0.4.3": {
|
||||
"Wabbajack.Downloaders.Bethesda/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Dispatcher/0.4.3": {
|
||||
"Wabbajack.Downloaders.Dispatcher/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.GameFile/0.4.3": {
|
||||
"Wabbajack.Downloaders.GameFile/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.GoogleDrive/0.4.3": {
|
||||
"Wabbajack.Downloaders.GoogleDrive/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Http/0.4.3": {
|
||||
"Wabbajack.Downloaders.Http/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Interfaces/0.4.3": {
|
||||
"Wabbajack.Downloaders.Interfaces/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.4.3": {
|
||||
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Manual/0.4.3": {
|
||||
"Wabbajack.Downloaders.Manual/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.MediaFire/0.4.3": {
|
||||
"Wabbajack.Downloaders.MediaFire/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Mega/0.4.3": {
|
||||
"Wabbajack.Downloaders.Mega/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.ModDB/0.4.3": {
|
||||
"Wabbajack.Downloaders.ModDB/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.Nexus/0.4.3": {
|
||||
"Wabbajack.Downloaders.Nexus/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.VerificationCache/0.4.3": {
|
||||
"Wabbajack.Downloaders.VerificationCache/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Downloaders.WabbajackCDN/0.4.3": {
|
||||
"Wabbajack.Downloaders.WabbajackCDN/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.DTOs/0.4.3": {
|
||||
"Wabbajack.DTOs/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.FileExtractor/0.4.3": {
|
||||
"Wabbajack.FileExtractor/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Hashing.PHash/0.4.3": {
|
||||
"Wabbajack.Hashing.PHash/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Hashing.xxHash64/0.4.3": {
|
||||
"Wabbajack.Hashing.xxHash64/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Installer/0.4.3": {
|
||||
"Wabbajack.Installer/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.IO.Async/0.4.3": {
|
||||
"Wabbajack.IO.Async/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.BethesdaNet/0.4.3": {
|
||||
"Wabbajack.Networking.BethesdaNet/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.Discord/0.4.3": {
|
||||
"Wabbajack.Networking.Discord/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.GitHub/0.4.3": {
|
||||
"Wabbajack.Networking.GitHub/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.Http/0.4.3": {
|
||||
"Wabbajack.Networking.Http/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.Http.Interfaces/0.4.3": {
|
||||
"Wabbajack.Networking.Http.Interfaces/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.NexusApi/0.4.3": {
|
||||
"Wabbajack.Networking.NexusApi/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Networking.WabbajackClientApi/0.4.3": {
|
||||
"Wabbajack.Networking.WabbajackClientApi/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Paths/0.4.3": {
|
||||
"Wabbajack.Paths/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Paths.IO/0.4.3": {
|
||||
"Wabbajack.Paths.IO/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.RateLimiter/0.4.3": {
|
||||
"Wabbajack.RateLimiter/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Server.Lib/0.4.3": {
|
||||
"Wabbajack.Server.Lib/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.Services.OSIntegrated/0.4.3": {
|
||||
"Wabbajack.Services.OSIntegrated/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.VFS/0.4.3": {
|
||||
"Wabbajack.VFS/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Wabbajack.VFS.Interfaces/0.4.3": {
|
||||
"Wabbajack.VFS.Interfaces/0.4.4": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
|
||||
Binary file not shown.
@@ -904,20 +904,22 @@ class SettingsDialog(QDialog):
|
||||
if best_proton:
|
||||
resolved_install_path = str(best_proton['path'])
|
||||
resolved_install_version = best_proton['name']
|
||||
self.config_handler.set("proton_path", resolved_install_path)
|
||||
self.config_handler.set("proton_version", resolved_install_version)
|
||||
else:
|
||||
resolved_install_path = "auto"
|
||||
resolved_install_version = "auto"
|
||||
except:
|
||||
resolved_install_path = "auto"
|
||||
resolved_install_version = "auto"
|
||||
# No Proton found - don't write anything, let engine auto-detect
|
||||
logger.warning("Auto Proton selection failed: No Proton versions found")
|
||||
# Don't modify existing config values
|
||||
except Exception as e:
|
||||
# Exception during detection - log it and don't write anything
|
||||
logger.error(f"Auto Proton selection failed with exception: {e}", exc_info=True)
|
||||
# Don't modify existing config values
|
||||
else:
|
||||
# User selected specific Proton version
|
||||
resolved_install_path = selected_install_proton_path
|
||||
# Extract version from dropdown text
|
||||
resolved_install_version = self.install_proton_dropdown.currentText()
|
||||
|
||||
self.config_handler.set("proton_path", resolved_install_path)
|
||||
self.config_handler.set("proton_version", resolved_install_version)
|
||||
self.config_handler.set("proton_path", resolved_install_path)
|
||||
self.config_handler.set("proton_version", resolved_install_version)
|
||||
|
||||
# Save Game Proton selection
|
||||
selected_game_proton_path = self.game_proton_dropdown.currentData()
|
||||
@@ -1038,6 +1040,10 @@ class JackifyMainWindow(QMainWindow):
|
||||
self._details_extra_height = 360
|
||||
self._initial_show_adjusted = False
|
||||
|
||||
# Track open dialogs to prevent duplicates
|
||||
self._settings_dialog = None
|
||||
self._about_dialog = None
|
||||
|
||||
# Ensure GNOME/Ubuntu exposes full set of window controls (avoid hidden buttons)
|
||||
self._apply_standard_window_flags()
|
||||
try:
|
||||
@@ -1606,23 +1612,74 @@ class JackifyMainWindow(QMainWindow):
|
||||
event.accept()
|
||||
|
||||
def open_settings_dialog(self):
|
||||
"""Open settings dialog, preventing duplicate instances"""
|
||||
try:
|
||||
# Check if dialog already exists and is visible
|
||||
if self._settings_dialog is not None:
|
||||
try:
|
||||
if self._settings_dialog.isVisible():
|
||||
# Dialog is already open - raise it to front
|
||||
self._settings_dialog.raise_()
|
||||
self._settings_dialog.activateWindow()
|
||||
return
|
||||
else:
|
||||
# Dialog exists but is closed - clean up reference
|
||||
self._settings_dialog = None
|
||||
except RuntimeError:
|
||||
# Dialog was deleted - clean up reference
|
||||
self._settings_dialog = None
|
||||
|
||||
# Create new dialog
|
||||
dlg = SettingsDialog(self)
|
||||
self._settings_dialog = dlg
|
||||
|
||||
# Clean up reference when dialog is closed
|
||||
def on_dialog_finished():
|
||||
self._settings_dialog = None
|
||||
|
||||
dlg.finished.connect(on_dialog_finished)
|
||||
dlg.exec()
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Exception in open_settings_dialog: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
self._settings_dialog = None
|
||||
|
||||
def open_about_dialog(self):
|
||||
"""Open about dialog, preventing duplicate instances"""
|
||||
try:
|
||||
from jackify.frontends.gui.dialogs.about_dialog import AboutDialog
|
||||
|
||||
# Check if dialog already exists and is visible
|
||||
if self._about_dialog is not None:
|
||||
try:
|
||||
if self._about_dialog.isVisible():
|
||||
# Dialog is already open - raise it to front
|
||||
self._about_dialog.raise_()
|
||||
self._about_dialog.activateWindow()
|
||||
return
|
||||
else:
|
||||
# Dialog exists but is closed - clean up reference
|
||||
self._about_dialog = None
|
||||
except RuntimeError:
|
||||
# Dialog was deleted - clean up reference
|
||||
self._about_dialog = None
|
||||
|
||||
# Create new dialog
|
||||
dlg = AboutDialog(self.system_info, self)
|
||||
self._about_dialog = dlg
|
||||
|
||||
# Clean up reference when dialog is closed
|
||||
def on_dialog_finished():
|
||||
self._about_dialog = None
|
||||
|
||||
dlg.finished.connect(on_dialog_finished)
|
||||
dlg.exec()
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Exception in open_about_dialog: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
self._about_dialog = None
|
||||
|
||||
def _open_url(self, url: str):
|
||||
"""Open URL with clean environment to avoid AppImage library conflicts."""
|
||||
|
||||
@@ -833,6 +833,8 @@ class ModlistGalleryDialog(QDialog):
|
||||
self._validation_update_timer = None # Timer for background validation updates
|
||||
|
||||
self._setup_ui()
|
||||
# Disable filter controls during initial load to prevent race conditions
|
||||
self._set_filter_controls_enabled(False)
|
||||
# Lazy load - fetch modlists when dialog is shown
|
||||
|
||||
def _apply_initial_size(self):
|
||||
@@ -1168,6 +1170,9 @@ class ModlistGalleryDialog(QDialog):
|
||||
# Reconnect filter handler
|
||||
self.game_combo.currentIndexChanged.connect(self._apply_filters)
|
||||
|
||||
# Enable filter controls now that data is loaded
|
||||
self._set_filter_controls_enabled(True)
|
||||
|
||||
# Apply filters (will show all modlists for selected game initially)
|
||||
self._apply_filters()
|
||||
|
||||
@@ -1389,8 +1394,23 @@ class ModlistGalleryDialog(QDialog):
|
||||
self._filter_mods_list() # Refresh mod list based on NSFW state
|
||||
self._apply_filters() # Apply all filters
|
||||
|
||||
def _set_filter_controls_enabled(self, enabled: bool):
|
||||
"""Enable or disable all filter controls"""
|
||||
self.search_box.setEnabled(enabled)
|
||||
self.game_combo.setEnabled(enabled)
|
||||
self.show_official_only.setEnabled(enabled)
|
||||
self.show_nsfw.setEnabled(enabled)
|
||||
self.hide_unavailable.setEnabled(enabled)
|
||||
self.tags_list.setEnabled(enabled)
|
||||
self.mod_search.setEnabled(enabled)
|
||||
self.mods_list.setEnabled(enabled)
|
||||
|
||||
def _apply_filters(self):
|
||||
"""Apply current filters to modlist display"""
|
||||
# CRITICAL: Guard against race condition - don't filter if modlists aren't loaded yet
|
||||
if not self.all_modlists:
|
||||
return
|
||||
|
||||
filtered = self.all_modlists
|
||||
|
||||
# Search filter
|
||||
@@ -1480,15 +1500,25 @@ class ModlistGalleryDialog(QDialog):
|
||||
|
||||
def _update_grid(self):
|
||||
"""Update grid by removing all cards and re-adding only visible ones"""
|
||||
# CRITICAL: Guard against race condition - don't update if cards aren't ready yet
|
||||
if not self.all_cards:
|
||||
return
|
||||
|
||||
# Disable updates during grid update
|
||||
self.grid_widget.setUpdatesEnabled(False)
|
||||
|
||||
try:
|
||||
# Remove all cards from layout
|
||||
# CRITICAL FIX: Properly remove widgets to prevent overlapping and orphaned windows
|
||||
# We need to explicitly remove widgets from the layout before taking items
|
||||
# to ensure they're fully cleaned up, but we don't setParent(None) because
|
||||
# widgets are immediately re-added to the grid (Qt will reparent them).
|
||||
while self.grid_layout.count():
|
||||
item = self.grid_layout.takeAt(0)
|
||||
if item.widget():
|
||||
item.widget().setParent(None)
|
||||
widget = item.widget() if item else None
|
||||
if widget:
|
||||
# Explicitly remove widget from layout to prevent overlapping
|
||||
self.grid_layout.removeWidget(widget)
|
||||
del item
|
||||
|
||||
# Calculate number of columns based on available width
|
||||
@@ -1528,6 +1558,16 @@ class ModlistGalleryDialog(QDialog):
|
||||
|
||||
card = self.all_cards.get(modlist.machineURL)
|
||||
if card:
|
||||
# Ensure widget is not already in the layout (prevent overlapping)
|
||||
# If it is, remove it first (shouldn't happen after takeAt, but safety check)
|
||||
if card.parent() == self.grid_widget:
|
||||
# Widget is already a child of grid_widget, check if it's in layout
|
||||
for i in range(self.grid_layout.count()):
|
||||
item = self.grid_layout.itemAt(i)
|
||||
if item and item.widget() == card:
|
||||
# Already in layout, remove it first
|
||||
self.grid_layout.removeWidget(card)
|
||||
break
|
||||
self.grid_layout.addWidget(card, row, col)
|
||||
|
||||
# Set column stretch - don't stretch card columns, but add a spacer column
|
||||
|
||||
@@ -20,6 +20,13 @@ from PySide6.QtGui import QFont
|
||||
from jackify.shared.progress_models import FileProgress, OperationType
|
||||
from ..shared_theme import JACKIFY_COLOR_BLUE
|
||||
|
||||
def _debug_log(message):
|
||||
"""Log message only if debug mode is enabled"""
|
||||
from jackify.backend.handlers.config_handler import ConfigHandler
|
||||
config_handler = ConfigHandler()
|
||||
if config_handler.get('debug_mode', False):
|
||||
print(message)
|
||||
|
||||
|
||||
class SummaryProgressWidget(QWidget):
|
||||
"""Widget showing summary progress for phases like Installing."""
|
||||
@@ -484,7 +491,28 @@ class FileProgressList(QWidget):
|
||||
return
|
||||
|
||||
# Widget doesn't exist - create it (only clear when creating new widget)
|
||||
# CRITICAL FIX: Remove all item widgets before clear() to prevent orphaned widgets
|
||||
_debug_log(f"[WIDGET_FIX] About to clear list_widget for summary widget - count={self.list_widget.count()}")
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item:
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing widget before clear (summary) - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget became top-level window after removeItemWidget() before clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.clear()
|
||||
# Check widgets in _file_items dict after clear
|
||||
for key, widget in list(self._file_items.items()):
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Widget in _file_items after clear - key={key}, widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget in _file_items is a top-level window after clear()! This is the bug!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._file_items.clear()
|
||||
|
||||
# Create new summary widget
|
||||
@@ -510,7 +538,22 @@ class FileProgressList(QWidget):
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item and item.data(Qt.UserRole) == "__summary__":
|
||||
# CRITICAL FIX: Call removeItemWidget() before takeItem() to prevent orphaned widgets
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing summary widget - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Summary widget became top-level window after removeItemWidget()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.takeItem(i)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] After takeItem (summary) - widget.parent()={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Summary widget is still a top-level window after takeItem()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
break
|
||||
self._summary_widget = None
|
||||
else:
|
||||
@@ -522,7 +565,22 @@ class FileProgressList(QWidget):
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item and item.data(Qt.UserRole) == "__transition__":
|
||||
# CRITICAL FIX: Call removeItemWidget() before takeItem() to prevent orphaned widgets
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing transition label - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Transition label became top-level window after removeItemWidget()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.takeItem(i)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] After takeItem (transition) - widget.parent()={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Transition label is still a top-level window after takeItem()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
break
|
||||
self._transition_label = None
|
||||
|
||||
@@ -533,7 +591,28 @@ class FileProgressList(QWidget):
|
||||
self._show_transition_message(current_phase)
|
||||
else:
|
||||
# Show empty state but keep header stable
|
||||
# CRITICAL FIX: Remove all item widgets before clear() to prevent orphaned widgets
|
||||
_debug_log(f"[WIDGET_FIX] About to clear list_widget (empty state) - count={self.list_widget.count()}")
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item:
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing widget before clear (empty) - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget became top-level window after removeItemWidget() before clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.clear()
|
||||
# Check widgets in _file_items dict after clear
|
||||
for key, widget in list(self._file_items.items()):
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Widget in _file_items after clear (empty) - key={key}, widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget in _file_items is a top-level window after clear()! This is the bug!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._file_items.clear()
|
||||
|
||||
# Update last phase tracker
|
||||
@@ -579,7 +658,24 @@ class FileProgressList(QWidget):
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item and item.data(Qt.UserRole) == item_key:
|
||||
# CRITICAL FIX: Call removeItemWidget() before takeItem() to prevent orphaned widgets
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing widget for item_key={item_key} - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
# Check if widget became orphaned after removal
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget became top-level window after removeItemWidget()! widget={widget}")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.takeItem(i)
|
||||
# Final check after takeItem
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] After takeItem - widget.parent()={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget is still a top-level window after takeItem()! This is the bug!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
break
|
||||
del self._file_items[item_key]
|
||||
|
||||
@@ -638,7 +734,28 @@ class FileProgressList(QWidget):
|
||||
|
||||
def _show_transition_message(self, new_phase: str):
|
||||
"""Show a brief 'Preparing...' message during phase transitions."""
|
||||
# CRITICAL FIX: Remove all item widgets before clear() to prevent orphaned widgets
|
||||
_debug_log(f"[WIDGET_FIX] About to clear list_widget (transition) - count={self.list_widget.count()}")
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item:
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing widget before clear (transition) - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget became top-level window after removeItemWidget() before clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.clear()
|
||||
# Check widgets in _file_items dict after clear
|
||||
for key, widget in list(self._file_items.items()):
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Widget in _file_items after clear (transition) - key={key}, widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget in _file_items is a top-level window after clear()! This is the bug!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._file_items.clear()
|
||||
|
||||
# Header removed - tab label provides context
|
||||
@@ -663,9 +780,42 @@ class FileProgressList(QWidget):
|
||||
|
||||
def clear(self):
|
||||
"""Clear all file items."""
|
||||
# CRITICAL FIX: Remove all item widgets before clear() to prevent orphaned widgets
|
||||
_debug_log(f"[WIDGET_FIX] clear() called - count={self.list_widget.count()}")
|
||||
for i in range(self.list_widget.count()):
|
||||
item = self.list_widget.item(i)
|
||||
if item:
|
||||
widget = self.list_widget.itemWidget(item)
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Removing widget before clear() - widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
self.list_widget.removeItemWidget(item)
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget became top-level window after removeItemWidget() before clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self.list_widget.clear()
|
||||
# Check widgets in _file_items dict after clear
|
||||
for key, widget in list(self._file_items.items()):
|
||||
if widget:
|
||||
_debug_log(f"[WIDGET_FIX] Widget in _file_items after clear() - key={key}, widget={widget}, parent={widget.parent()}, isWindow()={widget.isWindow()}")
|
||||
if widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Widget in _file_items is a top-level window after clear()! This is the bug!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._file_items.clear()
|
||||
if self._summary_widget:
|
||||
_debug_log(f"[WIDGET_FIX] Clearing summary_widget - widget={self._summary_widget}, parent={self._summary_widget.parent()}, isWindow()={self._summary_widget.isWindow()}")
|
||||
if self._summary_widget.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Summary widget is a top-level window in clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._summary_widget = None
|
||||
if self._transition_label:
|
||||
_debug_log(f"[WIDGET_FIX] Clearing transition_label - widget={self._transition_label}, parent={self._transition_label.parent()}, isWindow()={self._transition_label.isWindow()}")
|
||||
if self._transition_label.isWindow():
|
||||
print(f"[WIDGET_FIX] ERROR: Transition label is a top-level window in clear()!")
|
||||
import traceback
|
||||
traceback.print_stack()
|
||||
self._transition_label = None
|
||||
self._last_phase = None
|
||||
# Header removed - tab label provides context
|
||||
|
||||
Reference in New Issue
Block a user