diff options
| author | 2026-01-06 04:24:52 -0500 | |
|---|---|---|
| committer | 2026-01-06 04:24:52 -0500 | |
| commit | 385e4bfb1e426d23417ac788a6f44d639e226c89 (patch) | |
| tree | e64f04e19d63014d48e3b5272ce112c637236ba7 /gallery_dl/extractor/whyp.py | |
| parent | a24ec1647aeac35a63b744ea856011ad6e06be3b (diff) | |
New upstream version 1.31.2.upstream/1.31.2upstream
Diffstat (limited to 'gallery_dl/extractor/whyp.py')
| -rw-r--r-- | gallery_dl/extractor/whyp.py | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/gallery_dl/extractor/whyp.py b/gallery_dl/extractor/whyp.py new file mode 100644 index 0000000..d5bc6ab --- /dev/null +++ b/gallery_dl/extractor/whyp.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- + +# Copyright 2025 Mike Fährmann +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Extractors for https://whyp.it/""" + +from .common import Extractor, Message +from .. import text + +BASE_PATTERN = r"(?:https?://)?(?:www\.)?whyp\.it" + + +class WhypExtractor(Extractor): + """Base class for whyp extractors""" + category = "whyp" + root = "https://whyp.it" + root_api = "https://api.whyp.it" + directory_fmt = ("{category}", "{user[username]} ({user[id]})") + filename_fmt = "{id} {title}.{extension}" + archive_fmt = "{id}" + + def _init(self): + self.headers_api = { + "Accept" : "application/json", + "Origin" : self.root, + "Referer": self.root + "/", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-site", + } + + def items(self): + for track in self.tracks(): + if url := track.get("lossless_url"): + track["original"] = True + else: + url = track["lossy_url"] + track["original"] = False + + if "created_at" in track: + track["date"] = self.parse_datetime_iso(track["created_at"]) + + yield Message.Directory, "", track + yield Message.Url, url, text.nameext_from_url(url, track) + + +class WhypAudioExtractor(WhypExtractor): + subcategory = "audio" + pattern = BASE_PATTERN + r"/tracks/(\d+)" + example = "https://whyp.it/tracks/12345/SLUG" + + def tracks(self): + url = f"{self.root_api}/api/tracks/{self.groups[0]}" + track = self.request_json(url, headers=self.headers_api)["track"] + return (track,) + + +class WhypUserExtractor(WhypExtractor): + subcategory = "user" + pattern = BASE_PATTERN + r"/users/(\d+)" + example = "https://whyp.it/users/123/NAME" + + def tracks(self): + url = f"{self.root_api}/api/users/{self.groups[0]}/tracks" + params = {} + headers = self.headers_api + + while True: + data = self.request_json(url, params=params, headers=headers) + + yield from data["tracks"] + + if not (cursor := data.get("next_cursor")): + break + params["cursor"] = cursor + + +class WhypCollectionExtractor(WhypExtractor): + subcategory = "collection" + pattern = BASE_PATTERN + r"/collections/(\d+)" + example = "https://whyp.it/collections/123/NAME" + + def tracks(self): + cid = self.groups[0] + + url = f"{self.root_api}/api/collections/{cid}" + headers = self.headers_api + self.kwdict["collection"] = collection = self.request_json( + url, headers=headers)["collection"] + + url = f"{self.root_api}/api/collections/{cid}/tracks" + params = {"token": collection["token"]} + data = self.request_json(url, params=params, headers=headers) + return data["tracks"] |
