mirror of
https://github.com/shadoll/moma.git
synced 2026-08-28 11:33:25 +00:00
Add decorators for formatting various media attributes
- Introduced `DurationDecorators` for full and short duration formatting. - Added `ExtensionDecorators` for formatting extension information. - Created `ResolutionDecorators` for formatting resolution dimensions. - Implemented `SizeDecorators` for full and short size formatting. - Enhanced `TextDecorators` with additional formatting options including blue and grey text, URL formatting, and escaping rich markup. - Developed `TrackDecorators` for formatting video, audio, and subtitle track data. - Refactored `MediaPanelView` to utilize a new `MediaPanelProperties` class for cleaner property management and formatting. - Updated `media_panel_properties.py` to include formatted properties for file info, TMDB data, metadata extraction, media info extraction, and filename extraction. - Bumped version to 0.6.5 in `uv.lock`.
This commit is contained in:
@@ -28,6 +28,11 @@ from .date_decorators import date_decorators, DateDecorators
|
||||
from .special_info_decorators import special_info_decorators, SpecialInfoDecorators
|
||||
from .text_decorators import text_decorators, TextDecorators
|
||||
from .conditional_decorators import conditional_decorators, ConditionalDecorators
|
||||
from .size_decorators import size_decorators, SizeDecorators
|
||||
from .extension_decorators import extension_decorators, ExtensionDecorators
|
||||
from .duration_decorators import duration_decorators, DurationDecorators
|
||||
from .resolution_decorators import resolution_decorators, ResolutionDecorators
|
||||
from .track_decorators import track_decorators, TrackDecorators
|
||||
|
||||
__all__ = [
|
||||
# Base classes
|
||||
@@ -57,4 +62,14 @@ __all__ = [
|
||||
'TextDecorators',
|
||||
'conditional_decorators',
|
||||
'ConditionalDecorators',
|
||||
'size_decorators',
|
||||
'SizeDecorators',
|
||||
'extension_decorators',
|
||||
'ExtensionDecorators',
|
||||
'duration_decorators',
|
||||
'DurationDecorators',
|
||||
'resolution_decorators',
|
||||
'ResolutionDecorators',
|
||||
'track_decorators',
|
||||
'TrackDecorators',
|
||||
]
|
||||
@@ -19,6 +19,7 @@ class ConditionalDecorators:
|
||||
"""Decorator to wrap value with delimiters if it exists.
|
||||
|
||||
Can be used for prefix-only (right=""), suffix-only (left=""), or both.
|
||||
Supports format string placeholders that will be filled from function arguments.
|
||||
|
||||
Usage:
|
||||
@conditional_decorators.wrap("[", "]")
|
||||
@@ -34,12 +35,40 @@ class ConditionalDecorators:
|
||||
@conditional_decorators.wrap("", ",")
|
||||
def get_hdr(self):
|
||||
return self.extractor.get('hdr')
|
||||
|
||||
# With placeholders
|
||||
@conditional_decorators.wrap("Track {index}: ")
|
||||
def get_track(self, data, index):
|
||||
return data
|
||||
"""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
return f"{left}{result}{right}" if result else ""
|
||||
if not result:
|
||||
return ""
|
||||
|
||||
# Extract format arguments from function signature
|
||||
# Skip 'self' (args[0]) and the main data argument
|
||||
format_kwargs = {}
|
||||
if len(args) > 2: # self, data, index, ...
|
||||
# Try to detect named parameters from function signature
|
||||
import inspect
|
||||
sig = inspect.signature(func)
|
||||
param_names = list(sig.parameters.keys())
|
||||
# Skip first two params (self, data/track/value)
|
||||
for i, param_name in enumerate(param_names[2:], start=2):
|
||||
if i < len(args):
|
||||
format_kwargs[param_name] = args[i]
|
||||
|
||||
# Also add explicit kwargs
|
||||
format_kwargs.update(kwargs)
|
||||
|
||||
# Format left and right with available arguments
|
||||
formatted_left = left.format(**format_kwargs) if format_kwargs else left
|
||||
formatted_right = right.format(**format_kwargs) if format_kwargs else right
|
||||
|
||||
return f"{formatted_left}{result}{formatted_right}"
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
"""Duration formatting decorators.
|
||||
|
||||
Provides decorator versions of DurationFormatter methods.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
from .duration_formatter import DurationFormatter
|
||||
|
||||
|
||||
class DurationDecorators:
|
||||
"""Duration formatting decorators."""
|
||||
|
||||
@staticmethod
|
||||
def duration_full() -> Callable:
|
||||
"""Decorator to format duration in full format (HH:MM:SS)."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return DurationFormatter.format_full(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def duration_short() -> Callable:
|
||||
"""Decorator to format duration in short format."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return DurationFormatter.format_short(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
duration_decorators = DurationDecorators()
|
||||
@@ -0,0 +1,29 @@
|
||||
"""Extension formatting decorators.
|
||||
|
||||
Provides decorator versions of ExtensionFormatter methods.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
from .extension_formatter import ExtensionFormatter
|
||||
|
||||
|
||||
class ExtensionDecorators:
|
||||
"""Extension formatting decorators."""
|
||||
|
||||
@staticmethod
|
||||
def extension_info() -> Callable:
|
||||
"""Decorator to format extension information."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return ExtensionFormatter.format_extension_info(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
extension_decorators = ExtensionDecorators()
|
||||
@@ -0,0 +1,29 @@
|
||||
"""Resolution formatting decorators.
|
||||
|
||||
Provides decorator versions of ResolutionFormatter methods.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
from .resolution_formatter import ResolutionFormatter
|
||||
|
||||
|
||||
class ResolutionDecorators:
|
||||
"""Resolution formatting decorators."""
|
||||
|
||||
@staticmethod
|
||||
def resolution_dimensions() -> Callable:
|
||||
"""Decorator to format resolution as dimensions (WxH)."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return ResolutionFormatter.format_resolution_dimensions(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
resolution_decorators = ResolutionDecorators()
|
||||
@@ -0,0 +1,42 @@
|
||||
"""Size formatting decorators.
|
||||
|
||||
Provides decorator versions of SizeFormatter methods.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
from .size_formatter import SizeFormatter
|
||||
|
||||
|
||||
class SizeDecorators:
|
||||
"""Size formatting decorators."""
|
||||
|
||||
@staticmethod
|
||||
def size_full() -> Callable:
|
||||
"""Decorator to format file size in full format."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if result is None:
|
||||
return ""
|
||||
return SizeFormatter.format_size_full(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def size_short() -> Callable:
|
||||
"""Decorator to format file size in short format."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if result is None:
|
||||
return ""
|
||||
return SizeFormatter.format_size_short(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
size_decorators = SizeDecorators()
|
||||
@@ -22,6 +22,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if result == "":
|
||||
return ""
|
||||
return TextFormatter.bold(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -33,6 +35,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if result == "":
|
||||
return ""
|
||||
return TextFormatter.italic(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -44,6 +48,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if result == "":
|
||||
return ""
|
||||
return TextFormatter.green(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -55,6 +61,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.yellow(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -66,6 +74,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.cyan(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -77,6 +87,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.magenta(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -88,10 +100,12 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.red(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
@staticmethod
|
||||
def orange() -> Callable:
|
||||
"""Decorator to color text orange."""
|
||||
@@ -99,10 +113,38 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.orange(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def blue() -> Callable:
|
||||
"""Decorator to color text blue."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.blue(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def grey() -> Callable:
|
||||
"""Decorator to color text grey."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.grey(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def uppercase() -> Callable:
|
||||
"""Decorator to convert text to uppercase."""
|
||||
@@ -110,6 +152,8 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.uppercase(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
@@ -121,10 +165,39 @@ class TextDecorators:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.lowercase(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def url() -> Callable:
|
||||
"""Decorator to format text as a clickable URL."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TextFormatter.format_url(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def escape() -> Callable:
|
||||
"""Decorator to escape rich markup in text."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs) -> str:
|
||||
from rich.markup import escape
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return escape(str(result))
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
text_decorators = TextDecorators()
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Track formatting decorators.
|
||||
|
||||
Provides decorator versions of TrackFormatter methods.
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
from typing import Callable
|
||||
from .track_formatter import TrackFormatter
|
||||
|
||||
|
||||
class TrackDecorators:
|
||||
"""Track formatting decorators."""
|
||||
|
||||
@staticmethod
|
||||
def video_track() -> Callable:
|
||||
"""Decorator to format video track data."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TrackFormatter.format_video_track(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def audio_track() -> Callable:
|
||||
"""Decorator to format audio track data."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TrackFormatter.format_audio_track(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
@staticmethod
|
||||
def subtitle_track() -> Callable:
|
||||
"""Decorator to format subtitle track data."""
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
if not result:
|
||||
return ""
|
||||
return TrackFormatter.format_subtitle_track(result)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
# Singleton instance
|
||||
track_decorators = TrackDecorators()
|
||||
Reference in New Issue
Block a user