mirror of
https://github.com/Omni-guides/Jackify.git
synced 2026-06-08 00:07:45 +02:00
240 lines
9.5 KiB
Python
240 lines
9.5 KiB
Python
"""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
|