summaryrefslogtreecommitdiff
path: root/tidal_dl_ng/ui/media_details_helper.py
blob: bb56ab1ea9096c809ad1efa6f556237fddab1d02 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
"""Helpers for populating media details in InfoTabWidget - Reduces code duplication."""

from tidal_dl_ng.helper.metadata_utils import find_attr, safe_str
from tidal_dl_ng.helper.tidal import name_builder_title
from tidal_dl_ng.ui.info_tab_widget import TrackInfoFormatter


class MediaDetailsHelper:
    """Helper class to populate media details, reducing duplication in InfoTabWidget."""

    @staticmethod
    def populate_basic_fields(labels: dict, media, media_type: str = "track") -> None:
        """Populate fields common to all media types.

        Args:
            labels: Dictionary mapping field names to QLabel widgets
            media: The media object (Track, Video, Album, etc.)
            media_type: Type of media ("track", "video", "album")
        """
        # Title and version
        title = name_builder_title(media) if media_type != "album" else getattr(media, "name", None)
        version = getattr(media, "version", None)
        labels["title"].setText(safe_str(title))
        labels["version"].setText(safe_str(version))

        # Artists
        artists = TrackInfoFormatter.format_artists(media)
        labels["artists"].setText(safe_str(artists))

        # Duration
        duration = TrackInfoFormatter.format_duration(getattr(media, "duration", None))
        labels["duration"].setText(safe_str(duration))

        # Popularity
        popularity = getattr(media, "popularity", None)
        labels["popularity"].setText(safe_str(popularity))

    @staticmethod
    def populate_album_fields(labels: dict, media) -> None:
        """Populate album-related fields."""
        album_name = None
        release_date = None

        if hasattr(media, "album") and media.album:
            album_name = getattr(media.album, "name", None)
            if hasattr(media.album, "release_date"):
                release_date = TrackInfoFormatter.format_date(media.album.release_date)
        elif hasattr(media, "release_date"):
            release_date = TrackInfoFormatter.format_date(media.release_date)

        labels["album"].setText(safe_str(album_name))
        labels["release_date"].setText(safe_str(release_date))

    @staticmethod
    def populate_technical_fields(labels: dict, media) -> None:
        """Populate technical fields (codec, bitrate, ISRC, track number)."""
        # Codec & Bitrate
        codec = TrackInfoFormatter.format_codec(media)
        labels["codec"].setText(safe_str(codec))
        bitrate = TrackInfoFormatter.format_bitrate(media)
        labels["bitrate"].setText(safe_str(bitrate))

        # ISRC
        isrc = getattr(media, "isrc", None)
        labels["isrc"].setText(safe_str(isrc))

        # Track Number
        track_number = find_attr(media, "track_number", "tracknumber", "number", "position")
        if not track_number and hasattr(media, "album") and media.album:
            track_number = find_attr(media.album, "track_number", "tracknumber")
        labels["track_number"].setText(safe_str(track_number))

    @staticmethod
    def populate_metadata_fields(labels: dict, media) -> None:
        """Populate metadata fields (BPM, Label, Producers, Composers)."""
        # BPM
        bpm = find_attr(media, "bpm", "tempo")
        if not bpm and hasattr(media, "album") and media.album:
            bpm = find_attr(media.album, "bpm", "tempo")
        labels["bpm"].setText(safe_str(bpm))

        # Label
        label = None
        if hasattr(media, "album") and media.album:
            label = find_attr(media.album, "label", "label_name", "recordLabel")
        if not label:
            label = find_attr(media, "label", "label_name", "recordLabel")
        labels["label"].setText(safe_str(label))

        # Producers/Composers
        producers = find_attr(media, "producers", "producer")
        labels["producers"].setText(safe_str(producers) if producers else "—")

        composers = find_attr(media, "composers", "composer")
        labels["composers"].setText(safe_str(composers) if composers else "—")

    @staticmethod
    def populate_genres(labels: dict, media) -> None:
        """Extract and populate genre information with filtering."""
        genres = find_attr(media, "genres", "genre")
        if not genres and hasattr(media, "album") and media.album:
            genres = find_attr(media.album, "genres", "genre")

        if not genres:
            labels["genres"].setText("—")
            return

        # Normalize to list and filter technical tags
        genre_list = genres if isinstance(genres, list | tuple) else [genres]
        excluded = ("atmos", "dolby", "hq", "lossless", "mqa", "flac", "wav", "pcm", "audio", "bit", "track")
        filtered = [
            str(g) for g in genre_list if g and isinstance(g, str) and not any(kw in g.lower() for kw in excluded)
        ]

        labels["genres"].setText(safe_str(", ".join(filtered)) if filtered else "—")