diff --git a/.gitignore b/.gitignore
index af2643ae..e068618c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,3 +67,4 @@ target/
/*.snap
/*_source.tar.bz2
+/gallery-dl
diff --git a/docs/supportedsites.md b/docs/supportedsites.md
index 600ea43c..7a89d773 100644
--- a/docs/supportedsites.md
+++ b/docs/supportedsites.md
@@ -655,6 +655,12 @@ Consider all listed sites to potentially be NSFW.
Albums |
|
+
+ | NudoStar.TV |
+ https://nudostar.tv/ |
+ individual Images, Models |
+ |
+
| Patreon |
https://www.patreon.com/ |
diff --git a/gallery_dl/extractor/__init__.py b/gallery_dl/extractor/__init__.py
index 3891be8b..fa911205 100644
--- a/gallery_dl/extractor/__init__.py
+++ b/gallery_dl/extractor/__init__.py
@@ -123,6 +123,7 @@ modules = [
"nitter",
"nozomi",
"nsfwalbum",
+ "nudostar",
"paheal",
"patreon",
"pexels",
diff --git a/gallery_dl/extractor/nudostar.py b/gallery_dl/extractor/nudostar.py
new file mode 100644
index 00000000..adaa422a
--- /dev/null
+++ b/gallery_dl/extractor/nudostar.py
@@ -0,0 +1,71 @@
+# -*- 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.
+
+"""Extractors for https://nudostar.tv/"""
+
+from .common import GalleryExtractor, Message
+from .. import text
+
+BASE_PATTERN = r"(?:https?://)?(?:[a-z]{2}.)?nudostar\.tv"
+
+
+class NudostarExtractor(GalleryExtractor):
+ """Base class for NudoStar extractors"""
+ category = "nudostar"
+ root = "https://nudostar.tv"
+
+
+class NudostarModelExtractor(NudostarExtractor):
+ """Extractor for NudoStar models"""
+ subcategory = "model"
+ pattern = BASE_PATTERN + r"(/models/([^/?#]+)/?)$"
+ example = "https://nudostar.tv/models/MODEL/"
+
+ def metadata(self, page):
+ names = text.extr(page, "", "<").rpartition(
+ " Nude ")[0].split(" / ")
+ slug = self.groups[1]
+
+ return {
+ "gallery_id" : slug,
+ "model_slug" : slug,
+ "model_names": names,
+ "model" : names[0],
+ "title" : "",
+ }
+
+ def images(self, page):
+ path = text.extr(page, '" src="https://nudostar.tv', '"')
+ path, cnt, end = path.rsplit("_", 2)
+
+ base = f"{self.root}{path}_"
+ ext = "." + end.rpartition(".")[2]
+
+ return [
+ (f"{base}{i:04}{ext}", None)
+ for i in range(1, int(cnt)+1)
+ ]
+
+
+class NudostarImageExtractor(NudostarExtractor):
+ """Extractor for NudoStar images"""
+ subcategory = "image"
+ pattern = BASE_PATTERN + r"(/models/([^/?#]+)/(\d+)/)"
+ example = "https://nudostar.tv/models/MODEL/123/"
+
+ def items(self):
+ page = self.request(self.gallery_url, notfound=self.subcategory).text
+
+ img_url = text.extract(
+ page, 'src="', '"', page.index('class="headline"'))[0]
+
+ data = NudostarModelExtractor.metadata(self, page)
+ data = text.nameext_from_url(img_url, data)
+ data["num"] = text.parse_int(self.groups[2])
+ data["url"] = img_url
+
+ yield Message.Directory, data
+ yield Message.Url, img_url, data
diff --git a/scripts/supportedsites.py b/scripts/supportedsites.py
index 56acc140..4c560c6a 100755
--- a/scripts/supportedsites.py
+++ b/scripts/supportedsites.py
@@ -114,6 +114,7 @@ CATEGORY_MAP = {
"nijie" : "nijie",
"nozomi" : "Nozomi.la",
"nsfwalbum" : "NSFWalbum.com",
+ "nudostar" : "NudoStar.TV",
"paheal" : "rule #34",
"photovogue" : "PhotoVogue",
"pidgiwiki" : "PidgiWiki",
diff --git a/test/results/nudostar.py b/test/results/nudostar.py
new file mode 100644
index 00000000..1c3b7c42
--- /dev/null
+++ b/test/results/nudostar.py
@@ -0,0 +1,53 @@
+# -*- 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 nudostar
+
+
+__tests__ = (
+{
+ "#url" : "https://nudostar.tv/models/eva-joys/",
+ "#class" : nudostar.NudostarModelExtractor,
+ "#pattern": r"https://nudostar.tv/contents/e/v/eva-joys/1000/eva-joys_\d{4}\.jpg",
+ "#count" : range(50, 80),
+
+ "count" : 54,
+ "num" : range(1, 54),
+ "extension" : "jpg",
+ "filename" : r"re:eva-joys_00\d\d",
+ "gallery_id" : "eva-joys",
+ "model" : "eva_joy",
+ "model_slug" : "eva-joys",
+ "model_names": [
+ "eva_joy",
+ "eva_joys",
+ ],
+},
+
+{
+ "#url" : "https://nl.nudostar.tv/models/eva-joys/",
+ "#class" : nudostar.NudostarModelExtractor,
+},
+
+{
+ "#url" : "https://nudostar.tv/models/thebigtittiecommittee/148/",
+ "#class" : nudostar.NudostarImageExtractor,
+ "#results": "https://nudostar.tv/contents/t/h/thebigtittiecommittee/1000/thebigtittiecommittee_0148.jpg",
+
+ "extension" : "jpg",
+ "filename" : "thebigtittiecommittee_0148",
+ "gallery_id" : "thebigtittiecommittee",
+ "num" : 148,
+ "url" : "https://nudostar.tv/contents/t/h/thebigtittiecommittee/1000/thebigtittiecommittee_0148.jpg",
+ "model" : "Hari Beavis",
+ "model_slug" : "thebigtittiecommittee",
+ "model_names": [
+ "Hari Beavis",
+ "Thebigtittiecommittee",
+ ],
+},
+
+)