[ie/NinaProtocol] Add extractor (#8946)
[yt-dlp3.git] / yt_dlp / extractor / ninaprotocol.py
blobea57c5f383f96e21f80ed260d885d352f7a9a98e
1 from .common import InfoExtractor
2 from ..utils import int_or_none, mimetype2ext, parse_iso8601, url_or_none
3 from ..utils.traversal import traverse_obj
6 class NinaProtocolIE(InfoExtractor):
7 _VALID_URL = r'https?://(?:www\.)?ninaprotocol\.com/releases/(?P<id>[^/#?]+)'
8 _TESTS = [{
9 'url': 'https://www.ninaprotocol.com/releases/3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ',
10 'info_dict': {
11 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ',
12 'title': 'The Spatulas - March Chant',
13 'tags': ['punk', 'postpresentmedium', 'cambridge'],
14 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
15 'channel': 'ppm',
16 'description': 'md5:bb9f9d39d8f786449cd5d0ff7c5772db',
17 'album': 'The Spatulas - March Chant',
18 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
19 'timestamp': 1701417610,
20 'uploader': 'ppmrecs',
21 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
22 'display_id': 'the-spatulas-march-chant',
23 'upload_date': '20231201',
24 'album_artist': 'Post Present Medium ',
26 'playlist': [{
27 'info_dict': {
28 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_1',
29 'title': 'March Chant In April',
30 'track': 'March Chant In April',
31 'ext': 'mp3',
32 'duration': 152,
33 'track_number': 1,
34 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
35 'uploader': 'ppmrecs',
36 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
37 'timestamp': 1701417610,
38 'channel': 'ppm',
39 'album': 'The Spatulas - March Chant',
40 'tags': ['punk', 'postpresentmedium', 'cambridge'],
41 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
42 'upload_date': '20231201',
43 'album_artist': 'Post Present Medium ',
45 }, {
46 'info_dict': {
47 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_2',
48 'title': 'Rescue Mission',
49 'track': 'Rescue Mission',
50 'ext': 'mp3',
51 'duration': 212,
52 'track_number': 2,
53 'album_artist': 'Post Present Medium ',
54 'uploader': 'ppmrecs',
55 'tags': ['punk', 'postpresentmedium', 'cambridge'],
56 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
57 'channel': 'ppm',
58 'upload_date': '20231201',
59 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
60 'timestamp': 1701417610,
61 'album': 'The Spatulas - March Chant',
62 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
64 }, {
65 'info_dict': {
66 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_3',
67 'title': 'Slinger Style',
68 'track': 'Slinger Style',
69 'ext': 'mp3',
70 'duration': 179,
71 'track_number': 3,
72 'timestamp': 1701417610,
73 'upload_date': '20231201',
74 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
75 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
76 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
77 'album_artist': 'Post Present Medium ',
78 'album': 'The Spatulas - March Chant',
79 'tags': ['punk', 'postpresentmedium', 'cambridge'],
80 'uploader': 'ppmrecs',
81 'channel': 'ppm',
83 }, {
84 'info_dict': {
85 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_4',
86 'title': 'Psychic Signal',
87 'track': 'Psychic Signal',
88 'ext': 'mp3',
89 'duration': 220,
90 'track_number': 4,
91 'tags': ['punk', 'postpresentmedium', 'cambridge'],
92 'upload_date': '20231201',
93 'album': 'The Spatulas - March Chant',
94 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
95 'timestamp': 1701417610,
96 'album_artist': 'Post Present Medium ',
97 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
98 'channel': 'ppm',
99 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
100 'uploader': 'ppmrecs',
102 }, {
103 'info_dict': {
104 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_5',
105 'title': 'Curvy Color',
106 'track': 'Curvy Color',
107 'ext': 'mp3',
108 'duration': 148,
109 'track_number': 5,
110 'timestamp': 1701417610,
111 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
112 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
113 'album': 'The Spatulas - March Chant',
114 'album_artist': 'Post Present Medium ',
115 'channel': 'ppm',
116 'tags': ['punk', 'postpresentmedium', 'cambridge'],
117 'uploader': 'ppmrecs',
118 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
119 'upload_date': '20231201',
121 }, {
122 'info_dict': {
123 'id': '3SvsMM3y4oTPZ5DXFJnLkCAqkxz34hjzFxqms1vu9XBJ_6',
124 'title': 'Caveman Star',
125 'track': 'Caveman Star',
126 'ext': 'mp3',
127 'duration': 121,
128 'track_number': 6,
129 'channel_id': '4ceG4zsb7VVxBTGPtZMqDZWGHo3VUg2xRvzC2b17ymWP',
130 'thumbnail': 'https://www.arweave.net/VyZA6CBeUuqP174khvSrD44Eosi3MLVyWN42uaQKg50',
131 'tags': ['punk', 'postpresentmedium', 'cambridge'],
132 'album_artist': 'Post Present Medium ',
133 'uploader': 'ppmrecs',
134 'timestamp': 1701417610,
135 'uploader_id': '2bGjgdKUddJoj2shYGqfNcUfoSoABP21RJoiwGMZDq3A',
136 'album': 'The Spatulas - March Chant',
137 'channel': 'ppm',
138 'upload_date': '20231201',
141 }, {
142 'url': 'https://www.ninaprotocol.com/releases/f-g-s-american-shield',
143 'info_dict': {
144 'id': '76PZnJwaMgViQHYfA4NYJXds7CmW6vHQKAtQUxGene6J',
145 'description': 'md5:63f08d5db558b4b36e1896f317062721',
146 'title': 'F.G.S. - American Shield',
147 'uploader_id': 'Ej3rozs11wYqFk1Gs6oggGCkGLz8GzBhmJfnUxf6gPci',
148 'channel_id': '6JuksCZPXuP16wJ1BUfwuukJzh42C7guhLrFPPkVJfyE',
149 'channel': 'tinkscough',
150 'tags': [],
151 'album_artist': 'F.G.S.',
152 'album': 'F.G.S. - American Shield',
153 'thumbnail': 'https://www.arweave.net/YJpgImkXLT9SbpFb576KuZ5pm6bdvs452LMs3Rx6lm8',
154 'display_id': 'f-g-s-american-shield',
155 'uploader': 'flannerysilva',
156 'timestamp': 1702395858,
157 'upload_date': '20231212',
159 'playlist_count': 1,
160 }, {
161 'url': 'https://www.ninaprotocol.com/releases/time-to-figure-things-out',
162 'info_dict': {
163 'id': '6Zi1nC5hj6b13NkpxVYwRhFy6mYA7oLBbe9DMrgGDcYh',
164 'display_id': 'time-to-figure-things-out',
165 'description': 'md5:960202ed01c3134bb8958f1008527e35',
166 'timestamp': 1706283607,
167 'title': 'DJ STEPDAD - time to figure things out',
168 'album_artist': 'DJ STEPDAD',
169 'uploader': 'tddvsss',
170 'upload_date': '20240126',
171 'album': 'time to figure things out',
172 'uploader_id': 'AXQNRgTyYsySyAMFDwxzumuGjfmoXshorCesjpquwCBi',
173 'thumbnail': 'https://www.arweave.net/O4i8bcKVqJVZvNeHHFp6r8knpFGh9ZwEgbeYacr4nss',
174 'tags': [],
176 'playlist_count': 4,
179 def _real_extract(self, url):
180 video_id = self._match_id(url)
181 release = self._download_json(
182 f'https://api.ninaprotocol.com/v1/releases/{video_id}', video_id)['release']
184 video_id = release.get('publicKey') or video_id
186 common_info = traverse_obj(release, {
187 'album': ('metadata', 'properties', 'title', {str}),
188 'album_artist': ((('hub', 'data'), 'publisherAccount'), 'displayName', {str}),
189 'timestamp': ('datetime', {parse_iso8601}),
190 'thumbnail': ('metadata', 'image', {url_or_none}),
191 'uploader': ('publisherAccount', 'handle', {str}),
192 'uploader_id': ('publisherAccount', 'publicKey', {str}),
193 'channel': ('hub', 'handle', {str}),
194 'channel_id': ('hub', 'publicKey', {str}),
195 }, get_all=False)
196 common_info['tags'] = traverse_obj(release, ('metadata', 'properties', 'tags', ..., {str}))
198 entries = []
199 for track_num, track in enumerate(traverse_obj(release, (
200 'metadata', 'properties', 'files', lambda _, v: url_or_none(v['uri']))), 1):
201 entries.append({
202 'id': f'{video_id}_{track_num}',
203 'url': track['uri'],
204 **traverse_obj(track, {
205 'title': ('track_title', {str}),
206 'track': ('track_title', {str}),
207 'ext': ('type', {mimetype2ext}),
208 'track_number': ('track', {int_or_none}),
209 'duration': ('duration', {int_or_none}),
211 'vcodec': 'none',
212 **common_info,
215 return {
216 '_type': 'playlist',
217 'id': video_id,
218 'entries': entries,
219 **traverse_obj(release, {
220 'display_id': ('slug', {str}),
221 'title': ('metadata', 'name', {str}),
222 'description': ('metadata', 'description', {str}),
224 **common_info,