chore: snapshot current project updates
This commit is contained in:
+79
-26
@@ -19,6 +19,7 @@ from .config import Config
|
||||
from .utils import utc_now
|
||||
from .logging_config import get_logger, log_operation
|
||||
from .models import QuarantineEntry, QuarantineManifest, OperationResult, FileOperation
|
||||
from .scanner import categorize_file
|
||||
|
||||
|
||||
class QuarantineManager:
|
||||
@@ -127,9 +128,39 @@ class QuarantineManager:
|
||||
)
|
||||
raise ValueError(error_msg)
|
||||
|
||||
# Get category root directory
|
||||
category_root = self.config.library_root / category
|
||||
|
||||
# Get the actual category directory name from the file path
|
||||
# (not the category name, which may differ due to category mappings)
|
||||
try:
|
||||
relative_from_lib = file_path.relative_to(self.config.library_root)
|
||||
actual_category_dir = relative_from_lib.parts[0] if relative_from_lib.parts else None
|
||||
except ValueError:
|
||||
actual_category_dir = None
|
||||
|
||||
if not actual_category_dir:
|
||||
error_msg = f"File is not within library root {self.config.library_root}: {file_path}"
|
||||
log_operation(
|
||||
self.logger,
|
||||
logging.ERROR,
|
||||
error_msg,
|
||||
operation_type="quarantine",
|
||||
file_path=file_path
|
||||
)
|
||||
return OperationResult(
|
||||
operation=FileOperation(
|
||||
operation_type="quarantine",
|
||||
source_path=file_path,
|
||||
destination_path=None,
|
||||
reason=reason or "Invalid path",
|
||||
has_conflict=False
|
||||
),
|
||||
success=False,
|
||||
error_message=error_msg,
|
||||
executed_at=executed_at
|
||||
)
|
||||
|
||||
# Get category root directory using actual directory name
|
||||
category_root = self.config.library_root / actual_category_dir
|
||||
|
||||
# Determine relative path from category root
|
||||
try:
|
||||
relative_path = file_path.relative_to(category_root)
|
||||
@@ -319,31 +350,51 @@ class QuarantineManager:
|
||||
|
||||
def _determine_category(self, file_path: Path) -> str:
|
||||
"""Determine the category of a file based on its path.
|
||||
|
||||
|
||||
Uses the configured category mappings to support custom directory names.
|
||||
|
||||
Args:
|
||||
file_path: Path to the file
|
||||
|
||||
|
||||
Returns:
|
||||
Category name ("movie", "series", "anime", "other")
|
||||
"""
|
||||
# Get path relative to library root
|
||||
try:
|
||||
relative_path = file_path.relative_to(self.config.library_root)
|
||||
except ValueError:
|
||||
return "other"
|
||||
|
||||
# First component of relative path is the category
|
||||
parts = relative_path.parts
|
||||
if not parts:
|
||||
return "other"
|
||||
|
||||
category = parts[0].lower()
|
||||
|
||||
# Validate category
|
||||
if category in ("movie", "series", "anime", "other"):
|
||||
return category
|
||||
else:
|
||||
return "other"
|
||||
# Use the same categorization logic as the scanner
|
||||
categories_config = self.config.categories or {
|
||||
"movie": ["movie"],
|
||||
"series": ["series"],
|
||||
"anime": ["anime"]
|
||||
}
|
||||
return categorize_file(file_path, self.config.library_root, categories_config)
|
||||
|
||||
def _find_category_dir(self, category: str) -> Optional[str]:
|
||||
"""Find the actual directory name for a given category.
|
||||
|
||||
Scans the library root for directories that match the category mapping.
|
||||
|
||||
Args:
|
||||
category: Category name ("movie" or "series")
|
||||
|
||||
Returns:
|
||||
Actual directory name if found, or category name as fallback
|
||||
"""
|
||||
categories_config = self.config.categories or {
|
||||
"movie": ["movie"],
|
||||
"series": ["series"],
|
||||
"anime": ["anime"]
|
||||
}
|
||||
|
||||
# Get the list of possible directory names for this category
|
||||
dir_names = categories_config.get(category, [category])
|
||||
|
||||
# Check which one actually exists in the library root
|
||||
for dir_name in dir_names:
|
||||
candidate = self.config.library_root / dir_name
|
||||
if candidate.exists() and candidate.is_dir():
|
||||
return dir_name
|
||||
|
||||
# Fallback to category name itself
|
||||
return category
|
||||
|
||||
def _resolve_conflict(self, quarantine_path: Path) -> Path:
|
||||
"""Resolve destination conflicts by appending numeric suffix.
|
||||
@@ -387,14 +438,16 @@ class QuarantineManager:
|
||||
|
||||
def _get_manifest_path(self, category: str) -> Path:
|
||||
"""Get the path to the manifest file for a category.
|
||||
|
||||
|
||||
Args:
|
||||
category: Category name ("movie" or "series")
|
||||
|
||||
|
||||
Returns:
|
||||
Path to the manifest.json file
|
||||
"""
|
||||
category_root = self.config.library_root / category
|
||||
# Find the actual directory name for this category
|
||||
actual_dir = self._find_category_dir(category)
|
||||
category_root = self.config.library_root / actual_dir
|
||||
quarantine_root = category_root / self.config.quarantine_dir
|
||||
return quarantine_root / "manifest.json"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user