Coverage for pyPhotoAlbum/mixins/asset_path.py: 100%
25 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-20 12:55 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-20 12:55 +0000
1"""
2Asset path resolution mixin for components that need to resolve asset paths.
3"""
5import os
6from typing import Optional
9class AssetPathMixin:
10 """
11 Mixin providing asset path resolution functionality.
13 Requires access to self.project (typically via ApplicationStateMixin).
14 """
16 def resolve_asset_path(self, asset_path: str) -> Optional[str]:
17 """
18 Resolve a relative asset path to an absolute path.
20 Args:
21 asset_path: Relative path (e.g., "assets/photo.jpg") or absolute path
23 Returns:
24 Absolute path if the asset exists, None otherwise
25 """
26 if not asset_path:
27 return None
29 # Handle absolute paths
30 if os.path.isabs(asset_path):
31 if os.path.exists(asset_path):
32 return asset_path
33 return None
35 # Resolve relative path using project folder
36 project_folder = self._get_project_folder()
37 if project_folder:
38 full_path = os.path.join(project_folder, asset_path)
39 if os.path.exists(full_path):
40 return full_path
42 return None
44 def get_asset_full_path(self, relative_path: str) -> Optional[str]:
45 """
46 Get the full path for a relative asset path (without existence check).
48 Args:
49 relative_path: Relative path from project folder
51 Returns:
52 Full absolute path, or None if no project folder
53 """
54 project_folder = self._get_project_folder()
55 if project_folder and relative_path:
56 return os.path.join(project_folder, relative_path)
57 return None
59 def _get_project_folder(self) -> Optional[str]:
60 """
61 Get the current project folder.
63 Override this method if the project is accessed differently.
64 Default implementation uses self.project.folder_path.
65 """
66 if hasattr(self, "project") and self.project:
67 return getattr(self.project, "folder_path", None)
68 return None