]> jfr.im git - yt-dlp.git/blame - yt_dlp/extractor/nekohacker.py
[cleanup] Misc (#8510)
[yt-dlp.git] / yt_dlp / extractor / nekohacker.py
CommitLineData
489f5127 1import re
2
3from .common import InfoExtractor
4from ..utils import (
5 ExtractorError,
6 determine_ext,
7 extract_attributes,
8 get_element_by_class,
9 get_element_text_and_html_by_tag,
10 parse_duration,
11 traverse_obj,
12 try_call,
13 url_or_none,
14)
15
16
17class NekoHackerIE(InfoExtractor):
18 _VALID_URL = r'https?://(?:www\.)?nekohacker\.com/(?P<id>(?!free-dl)[\w-]+)'
19 _TESTS = [{
20 'url': 'https://nekohacker.com/nekoverse/',
21 'info_dict': {
22 'id': 'nekoverse',
23 'title': 'Nekoverse',
24 },
25 'playlist': [
26 {
27 'url': 'https://nekohacker.com/wp-content/uploads/2022/11/01-Spaceship.mp3',
28 'md5': '44223701ebedba0467ebda4cc07fb3aa',
29 'info_dict': {
30 'id': '1712',
31 'ext': 'mp3',
32 'title': 'Spaceship',
33 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2022/11/Nekoverse_Artwork-1024x1024.jpg',
34 'vcodec': 'none',
35 'acodec': 'mp3',
36 'release_date': '20221101',
37 'album': 'Nekoverse',
38 'artist': 'Neko Hacker',
39 'track': 'Spaceship',
40 'track_number': 1,
41 'duration': 195.0
42 }
43 },
44 {
45 'url': 'https://nekohacker.com/wp-content/uploads/2022/11/02-City-Runner.mp3',
46 'md5': '8f853c71719389d32bbbd3f1a87b3f08',
47 'info_dict': {
48 'id': '1713',
49 'ext': 'mp3',
50 'title': 'City Runner',
51 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2022/11/Nekoverse_Artwork-1024x1024.jpg',
52 'vcodec': 'none',
53 'acodec': 'mp3',
54 'release_date': '20221101',
55 'album': 'Nekoverse',
56 'artist': 'Neko Hacker',
57 'track': 'City Runner',
58 'track_number': 2,
59 'duration': 148.0
60 }
61 },
62 {
63 'url': 'https://nekohacker.com/wp-content/uploads/2022/11/03-Nature-Talk.mp3',
64 'md5': '5a8a8ae852720cee4c0ac95c7d1a7450',
65 'info_dict': {
66 'id': '1714',
67 'ext': 'mp3',
68 'title': 'Nature Talk',
69 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2022/11/Nekoverse_Artwork-1024x1024.jpg',
70 'vcodec': 'none',
71 'acodec': 'mp3',
72 'release_date': '20221101',
73 'album': 'Nekoverse',
74 'artist': 'Neko Hacker',
75 'track': 'Nature Talk',
76 'track_number': 3,
77 'duration': 174.0
78 }
79 },
80 {
81 'url': 'https://nekohacker.com/wp-content/uploads/2022/11/04-Crystal-World.mp3',
82 'md5': 'd8e59a48061764e50d92386a294abd50',
83 'info_dict': {
84 'id': '1715',
85 'ext': 'mp3',
86 'title': 'Crystal World',
87 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2022/11/Nekoverse_Artwork-1024x1024.jpg',
88 'vcodec': 'none',
89 'acodec': 'mp3',
90 'release_date': '20221101',
91 'album': 'Nekoverse',
92 'artist': 'Neko Hacker',
93 'track': 'Crystal World',
94 'track_number': 4,
95 'duration': 199.0
96 }
97 }
98 ]
99 }, {
100 'url': 'https://nekohacker.com/susume/',
101 'info_dict': {
102 'id': 'susume',
103 'title': '進め!むじなカンパニー',
104 },
105 'playlist': [
106 {
107 'url': 'https://nekohacker.com/wp-content/uploads/2021/01/進め!むじなカンパニー-feat.-六科なじむ-CV_-日高里菜-割戶真友-CV_-金元寿子-軽井沢ユキ-CV_-上坂すみれ-出稼ぎガルシア-CV_-金子彩花-.mp3',
108 'md5': 'fb13f008aa81f26ba48f91fd2d6186ce',
109 'info_dict': {
110 'id': '711',
111 'ext': 'mp3',
112 'title': 'md5:1a5fcbc96ca3c3265b1c6f9f79f30fd0',
113 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
114 'vcodec': 'none',
115 'acodec': 'mp3',
116 'release_date': '20210115',
117 'album': '進め!むじなカンパニー',
118 'artist': 'Neko Hacker',
119 'track': 'md5:1a5fcbc96ca3c3265b1c6f9f79f30fd0',
120 'track_number': 1,
121 'duration': None
122 }
123 },
124 {
125 'url': 'https://nekohacker.com/wp-content/uploads/2021/01/むじな-de-なじむ-feat.-六科なじむ-CV_-日高里菜-.mp3',
126 'md5': '028803f70241df512b7764e73396fdd1',
127 'info_dict': {
128 'id': '709',
129 'ext': 'mp3',
130 'title': 'むじな de なじむ feat. 六科なじむ (CV: 日高里菜 )',
131 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
132 'vcodec': 'none',
133 'acodec': 'mp3',
134 'release_date': '20210115',
135 'album': '進め!むじなカンパニー',
136 'artist': 'Neko Hacker',
137 'track': 'むじな de なじむ feat. 六科なじむ (CV: 日高里菜 )',
138 'track_number': 2,
139 'duration': None
140 }
141 },
142 {
143 'url': 'https://nekohacker.com/wp-content/uploads/2021/01/進め!むじなカンパニー-instrumental.mp3',
144 'md5': 'adde9e9a16e1da5e602b579c247d0fb9',
145 'info_dict': {
146 'id': '710',
147 'ext': 'mp3',
148 'title': '進め!むじなカンパニー (instrumental)',
149 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
150 'vcodec': 'none',
151 'acodec': 'mp3',
152 'release_date': '20210115',
153 'album': '進め!むじなカンパニー',
154 'artist': 'Neko Hacker',
155 'track': '進め!むじなカンパニー (instrumental)',
156 'track_number': 3,
157 'duration': None
158 }
159 },
160 {
161 'url': 'https://nekohacker.com/wp-content/uploads/2021/01/むじな-de-なじむ-instrumental.mp3',
162 'md5': 'ebb0443039cf5f9ff7fd557ed9b23599',
163 'info_dict': {
164 'id': '712',
165 'ext': 'mp3',
166 'title': 'むじな de なじむ (instrumental)',
167 'thumbnail': 'https://nekohacker.com/wp-content/uploads/2021/01/OP表-1024x1024.png',
168 'vcodec': 'none',
169 'acodec': 'mp3',
170 'release_date': '20210115',
171 'album': '進め!むじなカンパニー',
172 'artist': 'Neko Hacker',
173 'track': 'むじな de なじむ (instrumental)',
174 'track_number': 4,
175 'duration': None
176 }
177 }
178 ]
179 }]
180
181 def _real_extract(self, url):
182 playlist_id = self._match_id(url)
183
184 webpage = self._download_webpage(url, playlist_id)
185 playlist = get_element_by_class('playlist', webpage)
186
187 if not playlist:
188 iframe = try_call(lambda: get_element_text_and_html_by_tag('iframe', webpage)[1]) or ''
189 iframe_src = url_or_none(extract_attributes(iframe).get('src'))
190 if not iframe_src:
191 raise ExtractorError('No playlist or embed found in webpage')
192 elif re.match(r'https?://(?:\w+\.)?spotify\.com/', iframe_src):
193 raise ExtractorError('Spotify embeds are not supported', expected=True)
194 return self.url_result(url, 'Generic')
195
196 entries = []
197 for track_number, track in enumerate(re.findall(r'(<li[^>]+data-audiopath[^>]+>)', playlist), 1):
198 entry = traverse_obj(extract_attributes(track), {
199 'url': ('data-audiopath', {url_or_none}),
200 'ext': ('data-audiopath', {determine_ext}),
201 'id': 'data-trackid',
202 'title': 'data-tracktitle',
203 'track': 'data-tracktitle',
204 'album': 'data-albumtitle',
205 'duration': ('data-tracktime', {parse_duration}),
206 'release_date': ('data-releasedate', {lambda x: re.match(r'\d{8}', x.replace('.', ''))}, 0),
207 'thumbnail': ('data-albumart', {url_or_none}),
208 })
209 entries.append({
210 **entry,
211 'track_number': track_number,
212 'artist': 'Neko Hacker',
213 'vcodec': 'none',
214 'acodec': 'mp3' if entry['ext'] == 'mp3' else None,
215 })
216
217 return self.playlist_result(entries, playlist_id, traverse_obj(entries, (0, 'album')))