/
/
/
1"""Album converter for nicovideo objects."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING
6
7from music_assistant_models.enums import ImageType, LinkType
8from music_assistant_models.media_items import (
9 Album,
10 Artist,
11 ItemMapping,
12 MediaItemImage,
13 MediaItemLink,
14 MediaItemMetadata,
15)
16from music_assistant_models.unique_list import UniqueList
17from niconico.objects.nvapi import SeriesData
18from niconico.objects.video.search import EssentialSeries
19from niconico.objects.video.watch import WatchSeries
20
21if TYPE_CHECKING:
22 from niconico.objects.user import UserSeriesItem
23
24from music_assistant.providers.nicovideo.converters.base import NicovideoConverterBase
25from music_assistant.providers.nicovideo.helpers import AlbumWithTracks
26
27
28class NicovideoAlbumConverter(NicovideoConverterBase):
29 """Handles album conversion for nicovideo."""
30
31 def convert_by_series(
32 self,
33 series: SeriesData | UserSeriesItem | EssentialSeries | WatchSeries,
34 artists_list: UniqueList[Artist | ItemMapping] | None = None,
35 ) -> Album:
36 """Convert a nicovideo SeriesData, UserSeriesItem, or EssentialSeries into an Album."""
37 # Extract common data based on series type
38 if isinstance(series, SeriesData):
39 item_id = str(series.detail.id_)
40 name = series.detail.title
41 description = series.detail.description or ""
42 thumbnail_url = series.detail.thumbnail_url
43 series_owner = series.detail.owner
44 owner_id = series_owner.id_ if series_owner else None
45 owner_name = None
46 if series_owner:
47 if series_owner.type_ == "user" and series_owner.user:
48 owner_name = series_owner.user.nickname
49 elif series_owner.type_ == "channel" and series_owner.channel:
50 owner_name = series_owner.channel.name
51 elif isinstance(series, WatchSeries):
52 item_id = str(series.id_)
53 name = series.title
54 description = series.description or ""
55 thumbnail_url = series.thumbnail_url
56 owner_id = None
57 owner_name = None
58 elif isinstance(series, EssentialSeries):
59 item_id = str(series.id_)
60 name = series.title
61 description = series.description or ""
62 thumbnail_url = series.thumbnail_url
63 essential_owner = series.owner
64 owner_id = essential_owner.id_ if essential_owner else None
65 owner_name = essential_owner.name if essential_owner else None
66 else: # UserSeriesItem
67 item_id = str(series.id_)
68 name = series.title
69 description = series.description or ""
70 thumbnail_url = series.thumbnail_url
71 user_owner = series.owner
72 owner_id = user_owner.id_ if user_owner else None
73 owner_name = None # UserSeriesItem doesn't seem to have owner name
74
75 # Create album with common structure
76 album = Album(
77 item_id=item_id,
78 provider=self.provider.instance_id,
79 name=name,
80 metadata=MediaItemMetadata(
81 description=description,
82 links={
83 MediaItemLink(
84 type=LinkType.WEBSITE,
85 url=f"https://www.nicovideo.jp/series/{item_id}",
86 )
87 },
88 ),
89 provider_mappings=self.helper.create_provider_mapping(item_id, "series"),
90 )
91
92 # Build artists list from provided artists and/or series owner
93 artists_out = UniqueList(artists_list)
94
95 if owner_id:
96 owner_artist = Artist(
97 item_id=str(owner_id),
98 provider=self.provider.instance_id,
99 name=owner_name if owner_name else "",
100 provider_mappings=self.helper.create_provider_mapping(
101 item_id=str(owner_id),
102 url_path="user",
103 ),
104 )
105 artists_out.append(owner_artist)
106 if artists_out:
107 album.artists = artists_out
108
109 # Add thumbnail image if available (exclude default no-thumbnail image)
110 if thumbnail_url and not thumbnail_url.endswith("/series/no_thumbnail.png"):
111 album.metadata.images = UniqueList(
112 [
113 MediaItemImage(
114 type=ImageType.THUMB,
115 path=thumbnail_url,
116 provider=self.provider.instance_id,
117 remotely_accessible=True,
118 )
119 ]
120 )
121
122 return album
123
124 def convert_series_to_album_with_tracks(self, series_data: SeriesData) -> AlbumWithTracks:
125 """Convert SeriesData to AlbumWithTracks."""
126 album = self.convert_by_series(series_data)
127 tracks = []
128 for item in series_data.items or []:
129 track = self.converter_manager.track.convert_by_essential_video(item.video)
130 if track:
131 tracks.append(track)
132 return AlbumWithTracks(album, tracks)
133