mirror of
https://github.com/Benexl/FastAnime.git
synced 2025-12-12 15:50:01 -08:00
feat: duration
This commit is contained in:
@@ -9,6 +9,47 @@ from ...libs.api.types import AiringSchedule, MediaItem
|
||||
COMMA_REGEX = re.compile(r"([0-9]{3})(?=\d)")
|
||||
|
||||
|
||||
def format_media_duration(total_minutes: Optional[int]) -> str:
|
||||
"""
|
||||
Converts a duration in minutes into a more human-readable format
|
||||
(e.g., "1 hour 30 minutes", "45 minutes", "2 hours").
|
||||
|
||||
Args:
|
||||
total_minutes: The total duration in minutes (integer).
|
||||
|
||||
Returns:
|
||||
A string representing the formatted duration.
|
||||
"""
|
||||
if not total_minutes:
|
||||
return "N/A"
|
||||
|
||||
if not isinstance(total_minutes, int) or total_minutes < 0:
|
||||
raise ValueError("Input must be a non-negative integer representing minutes.")
|
||||
|
||||
if total_minutes == 0:
|
||||
return "0 minutes"
|
||||
|
||||
hours = total_minutes // 60
|
||||
minutes = total_minutes % 60
|
||||
|
||||
parts = []
|
||||
|
||||
if hours > 0:
|
||||
parts.append(f"{hours} hour{'s' if hours > 1 else ''}")
|
||||
|
||||
if minutes > 0:
|
||||
parts.append(f"{minutes} minute{'s' if minutes > 1 else ''}")
|
||||
|
||||
# Join the parts with " and " if both hours and minutes are present
|
||||
if len(parts) == 2:
|
||||
return f"{parts[0]} and {parts[1]}"
|
||||
elif len(parts) == 1:
|
||||
return parts[0]
|
||||
else:
|
||||
# This case should ideally not be reached if total_minutes > 0
|
||||
return "0 minutes" # Fallback for safety, though handled by initial check
|
||||
|
||||
|
||||
def format_date(dt: Optional[datetime], format_str: str = "%A, %d %B %Y") -> str:
|
||||
"""
|
||||
Formats a datetime object to a readable string.
|
||||
|
||||
@@ -82,6 +82,9 @@ def _populate_info_template(item: MediaItem, config: AppConfig) -> str:
|
||||
else "N/A"
|
||||
),
|
||||
"EPISODES": formatters.shell_safe(str(item.episodes)),
|
||||
"DURATION": formatters.shell_safe(
|
||||
formatters.format_media_duration(item.duration)
|
||||
),
|
||||
"SCORE": formatters.shell_safe(
|
||||
formatters.format_score_stars_full(item.average_score)
|
||||
),
|
||||
|
||||
@@ -5,10 +5,13 @@ from typing import List, Optional
|
||||
from ....core.utils.formatting import renumber_titles, strip_original_episode_prefix
|
||||
from ..types import (
|
||||
AiringSchedule,
|
||||
MediaFormat,
|
||||
MediaGenre,
|
||||
MediaImage,
|
||||
MediaItem,
|
||||
MediaSearchResult,
|
||||
MediaStatus,
|
||||
MediaTag,
|
||||
MediaTagItem,
|
||||
MediaTitle,
|
||||
MediaTrailer,
|
||||
@@ -133,7 +136,7 @@ def _to_generic_studios(anilist_studios: AnilistStudioNodes) -> List[Studio]:
|
||||
def _to_generic_tags(anilist_tags: list[AnilistMediaTag]) -> List[MediaTagItem]:
|
||||
"""Maps a list of AniList tags to generic MediaTag objects."""
|
||||
return [
|
||||
MediaTagItem(name=t["name"], rank=t.get("rank"))
|
||||
MediaTagItem(name=MediaTag(t["name"]), rank=t.get("rank"))
|
||||
for t in anilist_tags
|
||||
if t.get("name")
|
||||
]
|
||||
@@ -244,14 +247,14 @@ def _to_generic_media_item(
|
||||
type=data.get("type", "ANIME"),
|
||||
title=_to_generic_media_title(data["title"]),
|
||||
status=status_map[data["status"]],
|
||||
format=data.get("format"),
|
||||
format=MediaFormat(data["format"]),
|
||||
cover_image=_to_generic_media_image(data["coverImage"]),
|
||||
banner_image=data.get("bannerImage"),
|
||||
trailer=_to_generic_media_trailer(data["trailer"]),
|
||||
description=data.get("description"),
|
||||
episodes=data.get("episodes"),
|
||||
duration=data.get("duration"),
|
||||
genres=data.get("genres", []),
|
||||
genres=[MediaGenre(genre) for genre in data["genres"]],
|
||||
tags=_to_generic_tags(data.get("tags")),
|
||||
studios=_to_generic_studios(data.get("studios")),
|
||||
synonymns=data.get("synonyms", []),
|
||||
|
||||
@@ -85,6 +85,7 @@ query (
|
||||
}
|
||||
favourites
|
||||
averageScore
|
||||
duration
|
||||
episodes
|
||||
genres
|
||||
synonyms
|
||||
|
||||
@@ -69,6 +69,7 @@ draw_rule
|
||||
|
||||
print_kv "Episodes" "{EPISODES}"
|
||||
print_kv "Next Episode" "{NEXT_EPISODE}"
|
||||
print_kv "Duration" "{DURATION}"
|
||||
|
||||
draw_rule
|
||||
|
||||
|
||||
Reference in New Issue
Block a user