diff --git a/docs/supportedsites.md b/docs/supportedsites.md index 3ba8b2b272..ce6beac3e7 100644 --- a/docs/supportedsites.md +++ b/docs/supportedsites.md @@ -313,6 +313,12 @@ Consider all listed sites to potentially be NSFW. Favorites, Pools, Posts, Redirects, Tag Searches + + Girlsreleased + https://girlsreleased.com/ + Models, Sets, Sites + + Gofile https://gofile.io/ diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py index d003a61a2a..67cc24895b 100644 --- a/gallery_dl/extractor/__init__.py +++ b/gallery_dl/extractor/__init__.py @@ -62,6 +62,7 @@ "gelbooru", "gelbooru_v01", "gelbooru_v02", + "girlsreleased", "gofile", "hatenablog", "hentai2read", diff --git a/gallery_dl/extractor/girlsreleased.py b/gallery_dl/extractor/girlsreleased.py new file mode 100644 index 0000000000..bb661eadf0 --- /dev/null +++ b/gallery_dl/extractor/girlsreleased.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Copyright 2023 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://girlsreleased.com/""" + +from .common import Extractor, Message +from .. import text +import itertools + +BASE_PATTERN = r"(?:https?://)?(?:www\.)?girlsreleased\.com" + + +class GirlsreleasedSetExtractor(Extractor): + """Extractor for girlsreleased galleries""" + category = "girlsreleased" + subcategory = "set" + pattern = BASE_PATTERN + r"/set/(\d+)" + example = "https://girlsreleased.com/set/12345" + root = "https://girlsreleased.com" + request_interval = 0.5 + request_interval_min = 0.2 + + def __init__(self, match): + super().__init__(match) + self.id = match.group(1) + + def items(self): + url = "{}/api/0.1/set/{}".format(self.root, self.id) + json = self.request(url).json()["set"] + data = { + "title": json["name"] or json["id"], + "id": json["id"], + "site": json["site"], + "model": [model for _, model in json["models"]], + "date": text.parse_timestamp(json["date"]), + "count": len(json["images"]), + "url": "https://girlsreleased.com/set/" + json["id"], + } + yield Message.Directory, data + for data["num"], image in enumerate(json["images"], 1): + text.nameext_from_url(image[5], data) + yield Message.Queue, image[3], data + + +class GirlsreleasedModelExtractor(GirlsreleasedSetExtractor): + """Extractor for girlsreleased models""" + subcategory = "model" + pattern = BASE_PATTERN + r"/model/(\d+/?.*)" + example = "https://girlsreleased.com/model/12345/MODEL" + + def _pagination(self): + for page in itertools.count(): + url = "{}/api/0.1/sets/{}/{}/page/{}".format( + self.root, self.subcategory, self.id, page + ) + json = self.request(url).json()["sets"] + if not json: + return + offset = 0 if page == 0 else 1 + yield from json[offset:] + + def items(self): + data = {"_extractor": GirlsreleasedSetExtractor} + for set in self._pagination(): + yield Message.Queue, "{}/set/{}".format(self.root, set[0]), data + + +class GirlsreleasedSiteExtractor(GirlsreleasedModelExtractor): + """Extractor for girlsreleased sites""" + subcategory = "site" + pattern = BASE_PATTERN + r"/site/(.+(?:/model/\d+/?.*)?)" + example = "https://girlsreleased.com/site/SITE" diff --git a/test/results/girlsreleased.py b/test/results/girlsreleased.py new file mode 100644 index 0000000000..e68230d8e7 --- /dev/null +++ b/test/results/girlsreleased.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# 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. + +from gallery_dl.extractor import girlsreleased +import datetime + + +__tests__ = ( +{ + "#url" : "https://girlsreleased.com/set/32332", + "#category": ("", "girlsreleased", "set"), + "#class" : girlsreleased.GirlsreleasedSetExtractor, + "#count" : 122, + + "id" : "32332", + "title" : "Monadiko", + "model" : ["Mia Sollis"], + "site" : "sexart.com", + "date" : datetime.datetime, +}, + +{ + "#url" : "https://girlsreleased.com/set/124943", + "#category": ("", "girlsreleased", "set"), + "#class" : girlsreleased.GirlsreleasedSetExtractor, + "#count" : 79, + + "id" : "124943", + "title" : "124943", + "model" : ["Iveta"], + "site" : "errotica-archives.com", + "date" : datetime.datetime, +}, + +{ + "#url" : "https://girlsreleased.com/model/11545/Ariana%20Regent", + "#category": ("", "girlsreleased", "model"), + "#class" : girlsreleased.GirlsreleasedModelExtractor, +}, + +{ + "#url" : "https://girlsreleased.com/site/amourangels.com", + "#category": ("", "girlsreleased", "site"), + "#class" : girlsreleased.GirlsreleasedSiteExtractor, +}, + +{ + "#url" : "https://girlsreleased.com/site/femjoy.com/model/854/Gabi", + "#category": ("", "girlsreleased", "site"), + "#class" : girlsreleased.GirlsreleasedSiteExtractor, +}, +)