mirror of
https://github.com/Omni-guides/Jackify.git
synced 2026-06-17 11:37:45 +02:00
Sync from development - prepare for v0.3.0
This commit is contained in:
239
jackify/backend/handlers/progress_state_processing.py
Normal file
239
jackify/backend/handlers/progress_state_processing.py
Normal file
@@ -0,0 +1,239 @@
|
||||
"""Line processing methods for ProgressStateManager (Mixin)."""
|
||||
|
||||
import logging
|
||||
import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from jackify.shared.progress_models import (
|
||||
InstallationPhase,
|
||||
InstallationProgress,
|
||||
FileProgress,
|
||||
OperationType,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from jackify.backend.handlers.progress_parser import ParsedLine
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ProgressStateProcessingMixin:
|
||||
"""Mixin providing line processing methods."""
|
||||
|
||||
def process_line(self, line: str) -> bool:
|
||||
"""
|
||||
Process a line of output and update state.
|
||||
|
||||
Returns:
|
||||
True if state was updated, False otherwise
|
||||
"""
|
||||
parsed = self.parser.parse_line(line)
|
||||
|
||||
if not parsed.has_progress:
|
||||
return False
|
||||
|
||||
updated = False
|
||||
|
||||
phase_changed = False
|
||||
if parsed.phase and parsed.phase != self.state.phase:
|
||||
previous_phase = self.state.phase
|
||||
|
||||
if previous_phase == InstallationPhase.DOWNLOAD:
|
||||
self._download_files_seen = {}
|
||||
self._download_total_bytes = 0
|
||||
self._download_processed_bytes = 0
|
||||
|
||||
if previous_phase == InstallationPhase.VALIDATE and not parsed.data_info:
|
||||
if self.state.data_total > 0:
|
||||
self.state.data_processed = 0
|
||||
self.state.data_total = 0
|
||||
updated = True
|
||||
|
||||
if previous_phase == InstallationPhase.VALIDATE:
|
||||
if self.state.phase_name and 'validat' in self.state.phase_name.lower():
|
||||
self.state.phase_name = ""
|
||||
updated = True
|
||||
|
||||
phase_changed = True
|
||||
self._previous_phase = self.state.phase
|
||||
self.state.phase = parsed.phase
|
||||
updated = True
|
||||
elif parsed.phase:
|
||||
self.state.phase = parsed.phase
|
||||
updated = True
|
||||
|
||||
if parsed.phase_name:
|
||||
self.state.phase_name = parsed.phase_name
|
||||
updated = True
|
||||
elif phase_changed:
|
||||
if self.state.phase_name and self.state.phase != InstallationPhase.VALIDATE:
|
||||
self.state.phase_name = ""
|
||||
updated = True
|
||||
|
||||
if self.state.phase == InstallationPhase.DOWNLOAD:
|
||||
if self.state.phase_name and 'validat' in self.state.phase_name.lower():
|
||||
self.state.phase_name = ""
|
||||
updated = True
|
||||
|
||||
if parsed.overall_percent is not None:
|
||||
self.state.overall_percent = parsed.overall_percent
|
||||
updated = True
|
||||
|
||||
if parsed.step_info:
|
||||
self.state.phase_step, self.state.phase_max_steps = parsed.step_info
|
||||
updated = True
|
||||
|
||||
if parsed.data_info:
|
||||
self.state.data_processed, self.state.data_total = parsed.data_info
|
||||
if self.state.data_total > 0 and self.state.overall_percent == 0.0:
|
||||
self.state.overall_percent = (self.state.data_processed / self.state.data_total) * 100.0
|
||||
updated = True
|
||||
|
||||
if parsed.file_counter:
|
||||
self.state.phase_step, self.state.phase_max_steps = parsed.file_counter
|
||||
updated = True
|
||||
|
||||
if parsed.file_progress:
|
||||
if hasattr(parsed.file_progress, '_hidden') and parsed.file_progress._hidden:
|
||||
return updated
|
||||
|
||||
if hasattr(parsed.file_progress, '_texture_counter'):
|
||||
tex_current, tex_total = parsed.file_progress._texture_counter
|
||||
self.state.texture_conversion_current = tex_current
|
||||
self.state.texture_conversion_total = tex_total
|
||||
updated = True
|
||||
|
||||
if hasattr(parsed.file_progress, '_bsa_counter'):
|
||||
bsa_current, bsa_total = parsed.file_progress._bsa_counter
|
||||
self.state.bsa_building_current = bsa_current
|
||||
self.state.bsa_building_total = bsa_total
|
||||
updated = True
|
||||
|
||||
if parsed.file_progress.filename.lower().endswith('.wabbajack'):
|
||||
self._wabbajack_entry_name = parsed.file_progress.filename
|
||||
self._remove_synthetic_wabbajack()
|
||||
self._has_real_wabbajack = True
|
||||
else:
|
||||
if parsed.file_progress.operation == OperationType.DOWNLOAD:
|
||||
self._remove_all_wabbajack_entries()
|
||||
self._has_real_wabbajack = True
|
||||
|
||||
if self.state.phase == InstallationPhase.DOWNLOAD and parsed.file_progress.operation == OperationType.DOWNLOAD:
|
||||
filename = parsed.file_progress.filename
|
||||
total_size = parsed.file_progress.total_size or 0
|
||||
current_size = parsed.file_progress.current_size or 0
|
||||
|
||||
if filename not in self._download_files_seen:
|
||||
if total_size > 0:
|
||||
self._download_total_bytes += total_size
|
||||
self._download_files_seen[filename] = (total_size, current_size)
|
||||
self._download_processed_bytes += current_size
|
||||
else:
|
||||
old_total, old_current = self._download_files_seen[filename]
|
||||
if total_size > old_total:
|
||||
self._download_total_bytes += (total_size - old_total)
|
||||
if current_size > old_current:
|
||||
self._download_processed_bytes += (current_size - old_current)
|
||||
self._download_files_seen[filename] = (max(old_total, total_size), current_size)
|
||||
|
||||
if self.state.data_total == 0 and self._download_total_bytes > 0:
|
||||
self.state.data_total = self._download_total_bytes
|
||||
self.state.data_processed = self._download_processed_bytes
|
||||
updated = True
|
||||
|
||||
self._augment_file_metrics(parsed.file_progress)
|
||||
existing_file = None
|
||||
for f in self.state.active_files:
|
||||
if f.filename == parsed.file_progress.filename:
|
||||
existing_file = f
|
||||
break
|
||||
|
||||
if parsed.file_progress.percent >= 100.0 and not existing_file:
|
||||
updated = True
|
||||
elif parsed.file_progress.percent >= 100.0:
|
||||
parsed.file_progress.percent = 100.0
|
||||
parsed.file_progress.last_update = time.time()
|
||||
self.state.add_file(parsed.file_progress)
|
||||
updated = True
|
||||
else:
|
||||
self.state.add_file(parsed.file_progress)
|
||||
updated = True
|
||||
elif parsed.data_info:
|
||||
phase_name_lower = (parsed.phase_name or "").lower()
|
||||
message_lower = (parsed.message or "").lower()
|
||||
is_archive_phase = (
|
||||
'mod archives' in phase_name_lower or
|
||||
'downloading mod archives' in message_lower or
|
||||
(parsed.phase == InstallationPhase.DOWNLOAD and self._has_real_download_activity())
|
||||
)
|
||||
|
||||
if is_archive_phase:
|
||||
self._remove_all_wabbajack_entries()
|
||||
self._has_real_wabbajack = True
|
||||
|
||||
if not getattr(self, '_has_real_wabbajack', False):
|
||||
if self._maybe_add_wabbajack_progress(parsed):
|
||||
updated = True
|
||||
|
||||
if parsed.completed_filename:
|
||||
if not self.parser.should_display_file(parsed.completed_filename):
|
||||
parsed.completed_filename = None
|
||||
|
||||
if parsed.completed_filename:
|
||||
if self.state.phase == InstallationPhase.DOWNLOAD:
|
||||
filename = parsed.completed_filename
|
||||
if filename in self._download_files_seen:
|
||||
old_total, old_current = self._download_files_seen[filename]
|
||||
if old_current < old_total:
|
||||
self._download_processed_bytes += (old_total - old_current)
|
||||
self._download_files_seen[filename] = (old_total, old_total)
|
||||
if self.state.data_total == 0 and self._download_total_bytes > 0:
|
||||
self.state.data_total = self._download_total_bytes
|
||||
self.state.data_processed = self._download_processed_bytes
|
||||
updated = True
|
||||
|
||||
found_existing = False
|
||||
for file_prog in self.state.active_files:
|
||||
filename_match = (
|
||||
file_prog.filename == parsed.completed_filename or
|
||||
file_prog.filename.endswith(parsed.completed_filename) or
|
||||
parsed.completed_filename in file_prog.filename
|
||||
)
|
||||
if filename_match:
|
||||
file_prog.percent = 100.0
|
||||
file_prog.last_update = time.time()
|
||||
updated = True
|
||||
found_existing = True
|
||||
break
|
||||
|
||||
if not found_existing:
|
||||
operation = OperationType.DOWNLOAD
|
||||
if parsed.file_progress:
|
||||
operation = parsed.file_progress.operation
|
||||
|
||||
completed_file = FileProgress(
|
||||
filename=parsed.completed_filename,
|
||||
operation=operation,
|
||||
percent=100.0,
|
||||
current_size=0,
|
||||
total_size=0
|
||||
)
|
||||
completed_file.last_update = time.time()
|
||||
self.state.add_file(completed_file)
|
||||
updated = True
|
||||
|
||||
if parsed.speed_info:
|
||||
operation, speed = parsed.speed_info
|
||||
self.state.update_speed(operation, speed)
|
||||
updated = True
|
||||
|
||||
if parsed.message:
|
||||
self.state.message = parsed.message
|
||||
|
||||
if updated:
|
||||
self.state.timestamp = time.time()
|
||||
|
||||
if updated:
|
||||
self.state.remove_completed_files()
|
||||
|
||||
return updated
|
||||
Reference in New Issue
Block a user