logo

oasis-root

Compiled tree of Oasis Linux based on own branch at <https://hacktivis.me/git/oasis/> git clone https://anongit.hacktivis.me/git/oasis-root.git

nekohacker.py (9549B)


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