Task 3.3: Update ProgressService to use key as identifier

- Added optional 'key' and 'folder' fields to ProgressUpdate dataclass
- key: Primary series identifier (provider key, e.g., 'attack-on-titan')
- folder: Optional series folder name for display (e.g., 'Attack on Titan (2013)')
- Updated start_progress() and update_progress() methods to accept key/folder parameters
- Enhanced to_dict() serialization to include key/folder when present
- Updated all docstrings to clarify identifier usage
- Added 5 new comprehensive unit tests for key/folder functionality
- All 25 ProgressService tests passing
- Updated infrastructure.md with series identifier documentation
- Maintains backward compatibility - fields are optional
- Completed Phase 3, Task 3.3 of identifier standardization initiative
This commit is contained in:
2025-11-27 18:36:35 +01:00
parent dda999fb98
commit fb2cdd4bb6
4 changed files with 179 additions and 9 deletions

View File

@@ -51,6 +51,10 @@ class ProgressUpdate:
percent: Completion percentage (0-100)
current: Current progress value
total: Total progress value
key: Optional series identifier (provider key, e.g., 'attack-on-titan')
Used as the primary identifier for series-related operations
folder: Optional series folder name (e.g., 'Attack on Titan (2013)')
Used for display and filesystem operations only
metadata: Additional metadata
started_at: When operation started
updated_at: When last updated
@@ -64,13 +68,20 @@ class ProgressUpdate:
percent: float = 0.0
current: int = 0
total: int = 0
key: Optional[str] = None
folder: Optional[str] = None
metadata: Dict[str, Any] = field(default_factory=dict)
started_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
updated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
def to_dict(self) -> Dict[str, Any]:
"""Convert progress update to dictionary."""
return {
"""Convert progress update to dictionary.
Returns:
Dictionary representation with all fields including optional
key (series identifier) and folder (display metadata).
"""
result = {
"id": self.id,
"type": self.type.value,
"status": self.status.value,
@@ -84,6 +95,14 @@ class ProgressUpdate:
"started_at": self.started_at.isoformat(),
"updated_at": self.updated_at.isoformat(),
}
# Include optional series identifier fields
if self.key is not None:
result["key"] = self.key
if self.folder is not None:
result["folder"] = self.folder
return result
@dataclass
@@ -220,6 +239,8 @@ class ProgressService:
title: str,
total: int = 0,
message: str = "",
key: Optional[str] = None,
folder: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None,
) -> ProgressUpdate:
"""Start a new progress operation.
@@ -230,6 +251,10 @@ class ProgressService:
title: Human-readable title
total: Total items/bytes to process
message: Initial message
key: Optional series identifier (provider key)
Used as primary identifier for series-related operations
folder: Optional series folder name
Used for display and filesystem operations only
metadata: Additional metadata
Returns:
@@ -251,6 +276,8 @@ class ProgressService:
title=title,
message=message,
total=total,
key=key,
folder=folder,
metadata=metadata or {},
)
@@ -261,6 +288,8 @@ class ProgressService:
progress_id=progress_id,
type=progress_type.value,
title=title,
key=key,
folder=folder,
)
# Emit event to subscribers
@@ -281,6 +310,8 @@ class ProgressService:
current: Optional[int] = None,
total: Optional[int] = None,
message: Optional[str] = None,
key: Optional[str] = None,
folder: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None,
force_broadcast: bool = False,
) -> ProgressUpdate:
@@ -291,6 +322,8 @@ class ProgressService:
current: Current progress value
total: Updated total value
message: Updated message
key: Optional series identifier (provider key)
folder: Optional series folder name
metadata: Additional metadata to merge
force_broadcast: Force broadcasting even for small changes
@@ -316,6 +349,10 @@ class ProgressService:
update.total = total
if message is not None:
update.message = message
if key is not None:
update.key = key
if folder is not None:
update.folder = folder
if metadata:
update.metadata.update(metadata)