use 'operator +' when building 'pattern'
This commit is contained in:
@@ -20,7 +20,7 @@ class _2chThreadExtractor(Extractor):
|
|||||||
directory_fmt = ("{category}", "{board}", "{thread} {title}")
|
directory_fmt = ("{category}", "{board}", "{thread} {title}")
|
||||||
filename_fmt = "{tim}{filename:? //}.{extension}"
|
filename_fmt = "{tim}{filename:? //}.{extension}"
|
||||||
archive_fmt = "{board}_{thread}_{tim}"
|
archive_fmt = "{board}_{thread}_{tim}"
|
||||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/res/(\d+)"
|
pattern = BASE_PATTERN + r"/([^/?#]+)/res/(\d+)"
|
||||||
example = "https://2ch.org/a/res/12345.html"
|
example = "https://2ch.org/a/res/12345.html"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
@@ -66,7 +66,7 @@ class _2chBoardExtractor(Extractor):
|
|||||||
category = "2ch"
|
category = "2ch"
|
||||||
subcategory = "board"
|
subcategory = "board"
|
||||||
root = "https://2ch.org"
|
root = "https://2ch.org"
|
||||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/?$"
|
pattern = BASE_PATTERN + r"/([^/?#]+)/?$"
|
||||||
example = "https://2ch.org/a/"
|
example = "https://2ch.org/a/"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class AudiochanExtractor(Extractor):
|
|||||||
|
|
||||||
class AudiochanAudioExtractor(AudiochanExtractor):
|
class AudiochanAudioExtractor(AudiochanExtractor):
|
||||||
subcategory = "audio"
|
subcategory = "audio"
|
||||||
pattern = rf"{BASE_PATTERN}/a/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/a/([^/?#]+)"
|
||||||
example = "https://audiochan.com/a/SLUG"
|
example = "https://audiochan.com/a/SLUG"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -114,7 +114,7 @@ class AudiochanAudioExtractor(AudiochanExtractor):
|
|||||||
|
|
||||||
class AudiochanUserExtractor(AudiochanExtractor):
|
class AudiochanUserExtractor(AudiochanExtractor):
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{BASE_PATTERN}/u/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/u/([^/?#]+)"
|
||||||
example = "https://audiochan.com/u/USER"
|
example = "https://audiochan.com/u/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -130,7 +130,7 @@ class AudiochanUserExtractor(AudiochanExtractor):
|
|||||||
|
|
||||||
class AudiochanCollectionExtractor(AudiochanExtractor):
|
class AudiochanCollectionExtractor(AudiochanExtractor):
|
||||||
subcategory = "collection"
|
subcategory = "collection"
|
||||||
pattern = rf"{BASE_PATTERN}/c/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/c/([^/?#]+)"
|
||||||
example = "https://audiochan.com/c/SLUG"
|
example = "https://audiochan.com/c/SLUG"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -146,7 +146,7 @@ class AudiochanCollectionExtractor(AudiochanExtractor):
|
|||||||
|
|
||||||
class AudiochanSearchExtractor(AudiochanExtractor):
|
class AudiochanSearchExtractor(AudiochanExtractor):
|
||||||
subcategory = "search"
|
subcategory = "search"
|
||||||
pattern = rf"{BASE_PATTERN}/search/?\?([^#]+)"
|
pattern = BASE_PATTERN + r"/search/?\?([^#]+)"
|
||||||
example = "https://audiochan.com/search?q=QUERY"
|
example = "https://audiochan.com/search?q=QUERY"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -192,8 +192,8 @@ class BellazonExtractor(Extractor):
|
|||||||
|
|
||||||
class BellazonPostExtractor(BellazonExtractor):
|
class BellazonPostExtractor(BellazonExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = (rf"{BASE_PATTERN}(/topic/\d+-[\w-]+(?:/page/\d+)?)"
|
pattern = (BASE_PATTERN + r"(/topic/\d+-[\w-]+(?:/page/\d+)?)"
|
||||||
rf"/?#(?:findC|c)omment-(\d+)")
|
r"/?#(?:findC|c)omment-(\d+)")
|
||||||
example = "https://www.bellazon.com/main/topic/123-SLUG/#findComment-12345"
|
example = "https://www.bellazon.com/main/topic/123-SLUG/#findComment-12345"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -211,7 +211,7 @@ class BellazonPostExtractor(BellazonExtractor):
|
|||||||
|
|
||||||
class BellazonThreadExtractor(BellazonExtractor):
|
class BellazonThreadExtractor(BellazonExtractor):
|
||||||
subcategory = "thread"
|
subcategory = "thread"
|
||||||
pattern = rf"{BASE_PATTERN}(/topic/\d+-[\w-]+)(?:/page/(\d+))?"
|
pattern = BASE_PATTERN + r"(/topic/\d+-[\w-]+)(?:/page/(\d+))?"
|
||||||
example = "https://www.bellazon.com/main/topic/123-SLUG/"
|
example = "https://www.bellazon.com/main/topic/123-SLUG/"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -236,7 +236,7 @@ class BellazonThreadExtractor(BellazonExtractor):
|
|||||||
|
|
||||||
class BellazonForumExtractor(BellazonExtractor):
|
class BellazonForumExtractor(BellazonExtractor):
|
||||||
subcategory = "forum"
|
subcategory = "forum"
|
||||||
pattern = rf"{BASE_PATTERN}(/forum/\d+-[\w-]+)(?:/page/(\d+))?"
|
pattern = BASE_PATTERN + r"(/forum/\d+-[\w-]+)(?:/page/(\d+))?"
|
||||||
example = "https://www.bellazon.com/main/forum/123-SLUG/"
|
example = "https://www.bellazon.com/main/forum/123-SLUG/"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class CyberfileExtractor(Extractor):
|
|||||||
|
|
||||||
class CyberfileFolderExtractor(CyberfileExtractor):
|
class CyberfileFolderExtractor(CyberfileExtractor):
|
||||||
subcategory = "folder"
|
subcategory = "folder"
|
||||||
pattern = rf"{BASE_PATTERN}/folder/([0-9a-f]+)"
|
pattern = BASE_PATTERN + r"/folder/([0-9a-f]+)"
|
||||||
example = "https://cyberfile.me/folder/0123456789abcdef/NAME"
|
example = "https://cyberfile.me/folder/0123456789abcdef/NAME"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -97,7 +97,7 @@ class CyberfileFolderExtractor(CyberfileExtractor):
|
|||||||
|
|
||||||
class CyberfileSharedExtractor(CyberfileExtractor):
|
class CyberfileSharedExtractor(CyberfileExtractor):
|
||||||
subcategory = "shared"
|
subcategory = "shared"
|
||||||
pattern = rf"{BASE_PATTERN}/shared/([a-zA-Z0-9]+)"
|
pattern = BASE_PATTERN + r"/shared/([a-zA-Z0-9]+)"
|
||||||
example = "https://cyberfile.me/shared/AbCdEfGhIjK"
|
example = "https://cyberfile.me/shared/AbCdEfGhIjK"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -129,7 +129,7 @@ class CyberfileSharedExtractor(CyberfileExtractor):
|
|||||||
class CyberfileFileExtractor(CyberfileExtractor):
|
class CyberfileFileExtractor(CyberfileExtractor):
|
||||||
subcategory = "file"
|
subcategory = "file"
|
||||||
directory_fmt = ("{category}", "{uploader}", "{folder}")
|
directory_fmt = ("{category}", "{uploader}", "{folder}")
|
||||||
pattern = rf"{BASE_PATTERN}/([a-zA-Z0-9]+)"
|
pattern = BASE_PATTERN + r"/([a-zA-Z0-9]+)"
|
||||||
example = "https://cyberfile.me/AbCdE"
|
example = "https://cyberfile.me/AbCdE"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -349,7 +349,7 @@ class DanbooruMediaassetExtractor(DanbooruExtractor):
|
|||||||
subcategory = "media-asset"
|
subcategory = "media-asset"
|
||||||
filename_fmt = "{category}_ma{id}_{filename}.{extension}"
|
filename_fmt = "{category}_ma{id}_{filename}.{extension}"
|
||||||
archive_fmt = "m{id}"
|
archive_fmt = "m{id}"
|
||||||
pattern = rf"{BASE_PATTERN}/media_assets/(\d+)"
|
pattern = BASE_PATTERN + r"/media_assets/(\d+)"
|
||||||
example = "https://danbooru.donmai.us/media_assets/12345"
|
example = "https://danbooru.donmai.us/media_assets/12345"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class DandadanBase():
|
|||||||
|
|
||||||
class DandadanChapterExtractor(DandadanBase, ChapterExtractor):
|
class DandadanChapterExtractor(DandadanBase, ChapterExtractor):
|
||||||
"""Extractor for dandadan manga chapters"""
|
"""Extractor for dandadan manga chapters"""
|
||||||
pattern = rf"{BASE_PATTERN}(/manga/dandadan-chapter-([^/?#]+)/?)"
|
pattern = BASE_PATTERN + r"(/manga/dandadan-chapter-([^/?#]+)/?)"
|
||||||
example = "https://dandadan.net/manga/dandadan-chapter-123/"
|
example = "https://dandadan.net/manga/dandadan-chapter-123/"
|
||||||
|
|
||||||
def metadata(self, page):
|
def metadata(self, page):
|
||||||
@@ -54,7 +54,7 @@ class DandadanChapterExtractor(DandadanBase, ChapterExtractor):
|
|||||||
class DandadanMangaExtractor(DandadanBase, MangaExtractor):
|
class DandadanMangaExtractor(DandadanBase, MangaExtractor):
|
||||||
"""Extractor for dandadan manga"""
|
"""Extractor for dandadan manga"""
|
||||||
chapterclass = DandadanChapterExtractor
|
chapterclass = DandadanChapterExtractor
|
||||||
pattern = rf"{BASE_PATTERN}(/)"
|
pattern = BASE_PATTERN + r"(/)"
|
||||||
example = "https://dandadan.net/"
|
example = "https://dandadan.net/"
|
||||||
|
|
||||||
def chapters(self, page):
|
def chapters(self, page):
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class E621PopularExtractor(E621Extractor, danbooru.DanbooruPopularExtractor):
|
|||||||
class E621ArtistExtractor(E621Extractor, danbooru.DanbooruArtistExtractor):
|
class E621ArtistExtractor(E621Extractor, danbooru.DanbooruArtistExtractor):
|
||||||
"""Extractor for e621 artists"""
|
"""Extractor for e621 artists"""
|
||||||
subcategory = "artist"
|
subcategory = "artist"
|
||||||
pattern = rf"{BASE_PATTERN}/artists/(\d+)"
|
pattern = BASE_PATTERN + r"/artists/(\d+)"
|
||||||
example = "https://e621.net/artists/12345"
|
example = "https://e621.net/artists/12345"
|
||||||
|
|
||||||
items = E621Extractor.items_artists
|
items = E621Extractor.items_artists
|
||||||
@@ -155,7 +155,7 @@ class E621ArtistSearchExtractor(E621Extractor,
|
|||||||
danbooru.DanbooruArtistSearchExtractor):
|
danbooru.DanbooruArtistSearchExtractor):
|
||||||
"""Extractor for e621 artist searches"""
|
"""Extractor for e621 artist searches"""
|
||||||
subcategory = "artist-search"
|
subcategory = "artist-search"
|
||||||
pattern = rf"{BASE_PATTERN}/artists/?\?([^#]+)"
|
pattern = BASE_PATTERN + r"/artists/?\?([^#]+)"
|
||||||
example = "https://e621.net/artists?QUERY"
|
example = "https://e621.net/artists?QUERY"
|
||||||
|
|
||||||
items = E621Extractor.items_artists
|
items = E621Extractor.items_artists
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ class FanslyExtractor(Extractor):
|
|||||||
|
|
||||||
class FanslyPostExtractor(FanslyExtractor):
|
class FanslyPostExtractor(FanslyExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/post/(\d+)"
|
pattern = BASE_PATTERN + r"/post/(\d+)"
|
||||||
example = "https://fansly.com/post/1234567890"
|
example = "https://fansly.com/post/1234567890"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -164,7 +164,7 @@ class FanslyPostExtractor(FanslyExtractor):
|
|||||||
|
|
||||||
class FanslyHomeExtractor(FanslyExtractor):
|
class FanslyHomeExtractor(FanslyExtractor):
|
||||||
subcategory = "home"
|
subcategory = "home"
|
||||||
pattern = rf"{BASE_PATTERN}/home(?:/(?:subscribed()|list/(\d+)))?"
|
pattern = BASE_PATTERN + r"/home(?:/(?:subscribed()|list/(\d+)))?"
|
||||||
example = "https://fansly.com/home"
|
example = "https://fansly.com/home"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -180,7 +180,7 @@ class FanslyHomeExtractor(FanslyExtractor):
|
|||||||
|
|
||||||
class FanslyListExtractor(FanslyExtractor):
|
class FanslyListExtractor(FanslyExtractor):
|
||||||
subcategory = "list"
|
subcategory = "list"
|
||||||
pattern = rf"{BASE_PATTERN}/lists/(\d+)"
|
pattern = BASE_PATTERN + r"/lists/(\d+)"
|
||||||
example = "https://fansly.com/lists/1234567890"
|
example = "https://fansly.com/lists/1234567890"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -193,7 +193,7 @@ class FanslyListExtractor(FanslyExtractor):
|
|||||||
|
|
||||||
class FanslyListsExtractor(FanslyExtractor):
|
class FanslyListsExtractor(FanslyExtractor):
|
||||||
subcategory = "lists"
|
subcategory = "lists"
|
||||||
pattern = rf"{BASE_PATTERN}/lists"
|
pattern = BASE_PATTERN + r"/lists"
|
||||||
example = "https://fansly.com/lists"
|
example = "https://fansly.com/lists"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -206,7 +206,7 @@ class FanslyListsExtractor(FanslyExtractor):
|
|||||||
|
|
||||||
class FanslyCreatorPostsExtractor(FanslyExtractor):
|
class FanslyCreatorPostsExtractor(FanslyExtractor):
|
||||||
subcategory = "creator-posts"
|
subcategory = "creator-posts"
|
||||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/posts(?:/wall/(\d+))?"
|
pattern = BASE_PATTERN + r"/([^/?#]+)/posts(?:/wall/(\d+))?"
|
||||||
example = "https://fansly.com/CREATOR/posts"
|
example = "https://fansly.com/CREATOR/posts"
|
||||||
|
|
||||||
def posts_wall(self, account, wall):
|
def posts_wall(self, account, wall):
|
||||||
@@ -215,7 +215,7 @@ class FanslyCreatorPostsExtractor(FanslyExtractor):
|
|||||||
|
|
||||||
class FanslyCreatorMediaExtractor(FanslyExtractor):
|
class FanslyCreatorMediaExtractor(FanslyExtractor):
|
||||||
subcategory = "creator-media"
|
subcategory = "creator-media"
|
||||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/media(?:/wall/(\d+))?"
|
pattern = BASE_PATTERN + r"/([^/?#]+)/media(?:/wall/(\d+))?"
|
||||||
example = "https://fansly.com/CREATOR/media"
|
example = "https://fansly.com/CREATOR/media"
|
||||||
|
|
||||||
def posts_wall(self, account, wall):
|
def posts_wall(self, account, wall):
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class FikfapExtractor(Extractor):
|
|||||||
|
|
||||||
class FikfapPostExtractor(FikfapExtractor):
|
class FikfapPostExtractor(FikfapExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/user/(\w+)/post/(\d+)"
|
pattern = BASE_PATTERN + r"/user/(\w+)/post/(\d+)"
|
||||||
example = "https://fikfap.com/user/USER/post/12345"
|
example = "https://fikfap.com/user/USER/post/12345"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -86,7 +86,7 @@ class FikfapPostExtractor(FikfapExtractor):
|
|||||||
|
|
||||||
class FikfapUserExtractor(FikfapExtractor):
|
class FikfapUserExtractor(FikfapExtractor):
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{BASE_PATTERN}/user/(\w+)"
|
pattern = BASE_PATTERN + r"/user/(\w+)"
|
||||||
example = "https://fikfap.com/user/USER"
|
example = "https://fikfap.com/user/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class FitnakedgirlsGalleryExtractor(GalleryExtractor, FitnakedgirlsExtractor):
|
|||||||
directory_fmt = ("{category}", "{title}")
|
directory_fmt = ("{category}", "{title}")
|
||||||
filename_fmt = "{filename}.{extension}"
|
filename_fmt = "{filename}.{extension}"
|
||||||
archive_fmt = "{gallery_id}_{filename}"
|
archive_fmt = "{gallery_id}_{filename}"
|
||||||
pattern = rf"{BASE_PATTERN}/photos/gallery/([\w-]+)/?$"
|
pattern = BASE_PATTERN + r"/photos/gallery/([\w-]+)/?$"
|
||||||
example = "https://fitnakedgirls.com/photos/gallery/MODEL-nude/"
|
example = "https://fitnakedgirls.com/photos/gallery/MODEL-nude/"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
@@ -110,7 +110,7 @@ class FitnakedgirlsGalleryExtractor(GalleryExtractor, FitnakedgirlsExtractor):
|
|||||||
class FitnakedgirlsCategoryExtractor(FitnakedgirlsExtractor):
|
class FitnakedgirlsCategoryExtractor(FitnakedgirlsExtractor):
|
||||||
"""Extractor for fitnakedgirls category pages"""
|
"""Extractor for fitnakedgirls category pages"""
|
||||||
subcategory = "category"
|
subcategory = "category"
|
||||||
pattern = rf"{BASE_PATTERN}/photos/gallery/category/([\w-]+)"
|
pattern = BASE_PATTERN + r"/photos/gallery/category/([\w-]+)"
|
||||||
example = "https://fitnakedgirls.com/photos/gallery/category/CATEGORY/"
|
example = "https://fitnakedgirls.com/photos/gallery/category/CATEGORY/"
|
||||||
|
|
||||||
def galleries(self):
|
def galleries(self):
|
||||||
@@ -121,7 +121,7 @@ class FitnakedgirlsCategoryExtractor(FitnakedgirlsExtractor):
|
|||||||
class FitnakedgirlsTagExtractor(FitnakedgirlsExtractor):
|
class FitnakedgirlsTagExtractor(FitnakedgirlsExtractor):
|
||||||
"""Extractor for fitnakedgirls tag pages"""
|
"""Extractor for fitnakedgirls tag pages"""
|
||||||
subcategory = "tag"
|
subcategory = "tag"
|
||||||
pattern = rf"{BASE_PATTERN}/photos/gallery/tag/([\w-]+)"
|
pattern = BASE_PATTERN + r"/photos/gallery/tag/([\w-]+)"
|
||||||
example = "https://fitnakedgirls.com/photos/gallery/tag/TAG/"
|
example = "https://fitnakedgirls.com/photos/gallery/tag/TAG/"
|
||||||
|
|
||||||
def galleries(self):
|
def galleries(self):
|
||||||
@@ -135,7 +135,7 @@ class FitnakedgirlsVideoExtractor(FitnakedgirlsExtractor):
|
|||||||
directory_fmt = ("{category}", "{title}")
|
directory_fmt = ("{category}", "{title}")
|
||||||
filename_fmt = "{filename}.{extension}"
|
filename_fmt = "{filename}.{extension}"
|
||||||
archive_fmt = "{video_id}_{filename}"
|
archive_fmt = "{video_id}_{filename}"
|
||||||
pattern = rf"{BASE_PATTERN}/videos/(\d+)/(\d+)/([\w-]+)"
|
pattern = BASE_PATTERN + r"/videos/(\d+)/(\d+)/([\w-]+)"
|
||||||
example = "https://fitnakedgirls.com/videos/2025/08/VIDEO-TITLE/"
|
example = "https://fitnakedgirls.com/videos/2025/08/VIDEO-TITLE/"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -168,7 +168,7 @@ class FitnakedgirlsBlogExtractor(FitnakedgirlsExtractor):
|
|||||||
directory_fmt = ("{category}", "{title}")
|
directory_fmt = ("{category}", "{title}")
|
||||||
filename_fmt = "{filename}.{extension}"
|
filename_fmt = "{filename}.{extension}"
|
||||||
archive_fmt = "{post_id}_{filename}"
|
archive_fmt = "{post_id}_{filename}"
|
||||||
pattern = rf"{BASE_PATTERN}/fitblog/([\w-]+)"
|
pattern = BASE_PATTERN + r"/fitblog/([\w-]+)"
|
||||||
example = "https://fitnakedgirls.com/fitblog/MODEL-NAME/"
|
example = "https://fitnakedgirls.com/fitblog/MODEL-NAME/"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -23,19 +23,19 @@ class HdoujinBase():
|
|||||||
|
|
||||||
class HdoujinGalleryExtractor(
|
class HdoujinGalleryExtractor(
|
||||||
HdoujinBase, schalenetwork.SchalenetworkGalleryExtractor):
|
HdoujinBase, schalenetwork.SchalenetworkGalleryExtractor):
|
||||||
pattern = rf"{BASE_PATTERN}/(?:g|reader)/(\d+)/(\w+)"
|
pattern = BASE_PATTERN + r"/(?:g|reader)/(\d+)/(\w+)"
|
||||||
example = "https://hdoujin.org/g/12345/67890abcdef/"
|
example = "https://hdoujin.org/g/12345/67890abcdef/"
|
||||||
|
|
||||||
|
|
||||||
class HdoujinSearchExtractor(
|
class HdoujinSearchExtractor(
|
||||||
HdoujinBase, schalenetwork.SchalenetworkSearchExtractor):
|
HdoujinBase, schalenetwork.SchalenetworkSearchExtractor):
|
||||||
pattern = rf"{BASE_PATTERN}/(?:tag/([^/?#]+)|browse)?(?:/?\?([^#]*))?$"
|
pattern = BASE_PATTERN + r"/(?:tag/([^/?#]+)|browse)?(?:/?\?([^#]*))?$"
|
||||||
example = "https://hdoujin.org/browse?s=QUERY"
|
example = "https://hdoujin.org/browse?s=QUERY"
|
||||||
|
|
||||||
|
|
||||||
class HdoujinFavoriteExtractor(
|
class HdoujinFavoriteExtractor(
|
||||||
HdoujinBase, schalenetwork.SchalenetworkFavoriteExtractor):
|
HdoujinBase, schalenetwork.SchalenetworkFavoriteExtractor):
|
||||||
pattern = rf"{BASE_PATTERN}/favorites(?:\?([^#]*))?"
|
pattern = BASE_PATTERN + r"/favorites(?:\?([^#]*))?"
|
||||||
example = "https://hdoujin.org/favorites"
|
example = "https://hdoujin.org/favorites"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class ImgpileExtractor(Extractor):
|
|||||||
|
|
||||||
class ImgpilePostExtractor(ImgpileExtractor):
|
class ImgpilePostExtractor(ImgpileExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/p/(\w+)"
|
pattern = BASE_PATTERN + r"/p/(\w+)"
|
||||||
example = "https://imgpile.com/p/AbCdEfG"
|
example = "https://imgpile.com/p/AbCdEfG"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -78,7 +78,7 @@ class ImgpilePostExtractor(ImgpileExtractor):
|
|||||||
|
|
||||||
class ImgpileUserExtractor(ImgpileExtractor):
|
class ImgpileUserExtractor(ImgpileExtractor):
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{BASE_PATTERN}/u/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/u/([^/?#]+)"
|
||||||
example = "https://imgpile.com/u/USER"
|
example = "https://imgpile.com/u/USER"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ class InstagramCollectionExtractor(InstagramExtractor):
|
|||||||
class InstagramStoriesTrayExtractor(InstagramExtractor):
|
class InstagramStoriesTrayExtractor(InstagramExtractor):
|
||||||
"""Extractor for your Instagram account's stories tray"""
|
"""Extractor for your Instagram account's stories tray"""
|
||||||
subcategory = "stories-tray"
|
subcategory = "stories-tray"
|
||||||
pattern = rf"{BASE_PATTERN}/stories/me/?$()"
|
pattern = BASE_PATTERN + r"/stories/me/?$()"
|
||||||
example = "https://www.instagram.com/stories/me/"
|
example = "https://www.instagram.com/stories/me/"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from ..cache import cache, memcache
|
|||||||
import hashlib
|
import hashlib
|
||||||
|
|
||||||
BASE_PATTERN = r"(?:https?://)?(?:www\.)?iwara\.tv"
|
BASE_PATTERN = r"(?:https?://)?(?:www\.)?iwara\.tv"
|
||||||
USER_PATTERN = rf"{BASE_PATTERN}/profile/([^/?#]+)"
|
USER_PATTERN = BASE_PATTERN + r"/profile/([^/?#]+)"
|
||||||
|
|
||||||
|
|
||||||
class IwaraExtractor(Extractor):
|
class IwaraExtractor(Extractor):
|
||||||
@@ -158,7 +158,7 @@ class IwaraExtractor(Extractor):
|
|||||||
|
|
||||||
class IwaraUserExtractor(Dispatch, IwaraExtractor):
|
class IwaraUserExtractor(Dispatch, IwaraExtractor):
|
||||||
"""Extractor for iwara.tv profile pages"""
|
"""Extractor for iwara.tv profile pages"""
|
||||||
pattern = rf"{USER_PATTERN}/?$"
|
pattern = USER_PATTERN + r"/?$"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME"
|
example = "https://www.iwara.tv/profile/USERNAME"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -172,7 +172,7 @@ class IwaraUserExtractor(Dispatch, IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraUserImagesExtractor(IwaraExtractor):
|
class IwaraUserImagesExtractor(IwaraExtractor):
|
||||||
subcategory = "user-images"
|
subcategory = "user-images"
|
||||||
pattern = rf"{USER_PATTERN}/images(?:\?([^#]+))?"
|
pattern = USER_PATTERN + r"/images(?:\?([^#]+))?"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME/images"
|
example = "https://www.iwara.tv/profile/USERNAME/images"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -182,7 +182,7 @@ class IwaraUserImagesExtractor(IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraUserVideosExtractor(IwaraExtractor):
|
class IwaraUserVideosExtractor(IwaraExtractor):
|
||||||
subcategory = "user-videos"
|
subcategory = "user-videos"
|
||||||
pattern = rf"{USER_PATTERN}/videos(?:\?([^#]+))?"
|
pattern = USER_PATTERN + r"/videos(?:\?([^#]+))?"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME/videos"
|
example = "https://www.iwara.tv/profile/USERNAME/videos"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -192,7 +192,7 @@ class IwaraUserVideosExtractor(IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraUserPlaylistsExtractor(IwaraExtractor):
|
class IwaraUserPlaylistsExtractor(IwaraExtractor):
|
||||||
subcategory = "user-playlists"
|
subcategory = "user-playlists"
|
||||||
pattern = rf"{USER_PATTERN}/playlists(?:\?([^#]+))?"
|
pattern = USER_PATTERN + r"/playlists(?:\?([^#]+))?"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME/playlists"
|
example = "https://www.iwara.tv/profile/USERNAME/playlists"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -207,7 +207,7 @@ class IwaraUserPlaylistsExtractor(IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraFollowingExtractor(IwaraExtractor):
|
class IwaraFollowingExtractor(IwaraExtractor):
|
||||||
subcategory = "following"
|
subcategory = "following"
|
||||||
pattern = rf"{USER_PATTERN}/following"
|
pattern = USER_PATTERN + r"/following"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME/following"
|
example = "https://www.iwara.tv/profile/USERNAME/following"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -217,7 +217,7 @@ class IwaraFollowingExtractor(IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraFollowersExtractor(IwaraExtractor):
|
class IwaraFollowersExtractor(IwaraExtractor):
|
||||||
subcategory = "followers"
|
subcategory = "followers"
|
||||||
pattern = rf"{USER_PATTERN}/followers"
|
pattern = USER_PATTERN + r"/followers"
|
||||||
example = "https://www.iwara.tv/profile/USERNAME/followers"
|
example = "https://www.iwara.tv/profile/USERNAME/followers"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -228,7 +228,7 @@ class IwaraFollowersExtractor(IwaraExtractor):
|
|||||||
class IwaraImageExtractor(IwaraExtractor):
|
class IwaraImageExtractor(IwaraExtractor):
|
||||||
"""Extractor for individual iwara.tv image pages"""
|
"""Extractor for individual iwara.tv image pages"""
|
||||||
subcategory = "image"
|
subcategory = "image"
|
||||||
pattern = rf"{BASE_PATTERN}/image/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/image/([^/?#]+)"
|
||||||
example = "https://www.iwara.tv/image/ID"
|
example = "https://www.iwara.tv/image/ID"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -238,7 +238,7 @@ class IwaraImageExtractor(IwaraExtractor):
|
|||||||
class IwaraVideoExtractor(IwaraExtractor):
|
class IwaraVideoExtractor(IwaraExtractor):
|
||||||
"""Extractor for individual iwara.tv videos"""
|
"""Extractor for individual iwara.tv videos"""
|
||||||
subcategory = "video"
|
subcategory = "video"
|
||||||
pattern = rf"{BASE_PATTERN}/video/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/video/([^/?#]+)"
|
||||||
example = "https://www.iwara.tv/video/ID"
|
example = "https://www.iwara.tv/video/ID"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -248,7 +248,7 @@ class IwaraVideoExtractor(IwaraExtractor):
|
|||||||
class IwaraPlaylistExtractor(IwaraExtractor):
|
class IwaraPlaylistExtractor(IwaraExtractor):
|
||||||
"""Extractor for individual iwara.tv playlist pages"""
|
"""Extractor for individual iwara.tv playlist pages"""
|
||||||
subcategory = "playlist"
|
subcategory = "playlist"
|
||||||
pattern = rf"{BASE_PATTERN}/playlist/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/playlist/([^/?#]+)"
|
||||||
example = "https://www.iwara.tv/playlist/ID"
|
example = "https://www.iwara.tv/playlist/ID"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -257,7 +257,7 @@ class IwaraPlaylistExtractor(IwaraExtractor):
|
|||||||
|
|
||||||
class IwaraFavoriteExtractor(IwaraExtractor):
|
class IwaraFavoriteExtractor(IwaraExtractor):
|
||||||
subcategory = "favorite"
|
subcategory = "favorite"
|
||||||
pattern = rf"{BASE_PATTERN}/favorites(?:/(image|video)s)?"
|
pattern = BASE_PATTERN + r"/favorites(?:/(image|video)s)?"
|
||||||
example = "https://www.iwara.tv/favorites/videos"
|
example = "https://www.iwara.tv/favorites/videos"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -268,7 +268,7 @@ class IwaraFavoriteExtractor(IwaraExtractor):
|
|||||||
class IwaraSearchExtractor(IwaraExtractor):
|
class IwaraSearchExtractor(IwaraExtractor):
|
||||||
"""Extractor for iwara.tv search pages"""
|
"""Extractor for iwara.tv search pages"""
|
||||||
subcategory = "search"
|
subcategory = "search"
|
||||||
pattern = rf"{BASE_PATTERN}/search\?([^#]+)"
|
pattern = BASE_PATTERN + r"/search\?([^#]+)"
|
||||||
example = "https://www.iwara.tv/search?query=QUERY&type=TYPE"
|
example = "https://www.iwara.tv/search?query=QUERY&type=TYPE"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -281,7 +281,7 @@ class IwaraSearchExtractor(IwaraExtractor):
|
|||||||
class IwaraTagExtractor(IwaraExtractor):
|
class IwaraTagExtractor(IwaraExtractor):
|
||||||
"""Extractor for iwara.tv tag search"""
|
"""Extractor for iwara.tv tag search"""
|
||||||
subcategory = "tag"
|
subcategory = "tag"
|
||||||
pattern = rf"{BASE_PATTERN}/(image|video)s(?:\?([^#]+))?"
|
pattern = BASE_PATTERN + r"/(image|video)s(?:\?([^#]+))?"
|
||||||
example = "https://www.iwara.tv/videos?tags=TAGS"
|
example = "https://www.iwara.tv/videos?tags=TAGS"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import json
|
|||||||
|
|
||||||
BASE_PATTERN = (r"(?:https?://)?(?:www\.|beta\.)?"
|
BASE_PATTERN = (r"(?:https?://)?(?:www\.|beta\.)?"
|
||||||
r"(kemono|coomer)\.(cr|s[tu]|party)")
|
r"(kemono|coomer)\.(cr|s[tu]|party)")
|
||||||
USER_PATTERN = rf"{BASE_PATTERN}/([^/?#]+)/user/([^/?#]+)"
|
USER_PATTERN = BASE_PATTERN + r"/([^/?#]+)/user/([^/?#]+)"
|
||||||
HASH_PATTERN = r"/[0-9a-f]{2}/[0-9a-f]{2}/([0-9a-f]{64})"
|
HASH_PATTERN = r"/[0-9a-f]{2}/[0-9a-f]{2}/([0-9a-f]{64})"
|
||||||
|
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ def _validate(response):
|
|||||||
class KemonoUserExtractor(KemonoExtractor):
|
class KemonoUserExtractor(KemonoExtractor):
|
||||||
"""Extractor for all posts from a kemono.cr user listing"""
|
"""Extractor for all posts from a kemono.cr user listing"""
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{USER_PATTERN}/?(?:\?([^#]+))?(?:$|\?|#)"
|
pattern = USER_PATTERN + r"/?(?:\?([^#]+))?(?:$|\?|#)"
|
||||||
example = "https://kemono.cr/SERVICE/user/12345"
|
example = "https://kemono.cr/SERVICE/user/12345"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
@@ -345,7 +345,7 @@ class KemonoUserExtractor(KemonoExtractor):
|
|||||||
class KemonoPostsExtractor(KemonoExtractor):
|
class KemonoPostsExtractor(KemonoExtractor):
|
||||||
"""Extractor for kemono.cr post listings"""
|
"""Extractor for kemono.cr post listings"""
|
||||||
subcategory = "posts"
|
subcategory = "posts"
|
||||||
pattern = rf"{BASE_PATTERN}/posts()()(?:/?\?([^#]+))?"
|
pattern = BASE_PATTERN + r"/posts()()(?:/?\?([^#]+))?"
|
||||||
example = "https://kemono.cr/posts"
|
example = "https://kemono.cr/posts"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -357,7 +357,7 @@ class KemonoPostsExtractor(KemonoExtractor):
|
|||||||
class KemonoPostExtractor(KemonoExtractor):
|
class KemonoPostExtractor(KemonoExtractor):
|
||||||
"""Extractor for a single kemono.cr post"""
|
"""Extractor for a single kemono.cr post"""
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{USER_PATTERN}/post/([^/?#]+)(/revisions?(?:/(\d*))?)?"
|
pattern = USER_PATTERN + r"/post/([^/?#]+)(/revisions?(?:/(\d*))?)?"
|
||||||
example = "https://kemono.cr/SERVICE/user/12345/post/12345"
|
example = "https://kemono.cr/SERVICE/user/12345/post/12345"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
@@ -390,7 +390,7 @@ class KemonoDiscordExtractor(KemonoExtractor):
|
|||||||
"{server_id} {server}", "{channel_id} {channel}")
|
"{server_id} {server}", "{channel_id} {channel}")
|
||||||
filename_fmt = "{id}_{num:>02}_{filename}.{extension}"
|
filename_fmt = "{id}_{num:>02}_{filename}.{extension}"
|
||||||
archive_fmt = "discord_{server_id}_{id}_{num}"
|
archive_fmt = "discord_{server_id}_{id}_{num}"
|
||||||
pattern = rf"{BASE_PATTERN}/discord/server/(\d+)[/#](?:channel/)?(\d+)"
|
pattern = BASE_PATTERN + r"/discord/server/(\d+)[/#](?:channel/)?(\d+)"
|
||||||
example = "https://kemono.cr/discord/server/12345/12345"
|
example = "https://kemono.cr/discord/server/12345/12345"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -460,7 +460,7 @@ class KemonoDiscordExtractor(KemonoExtractor):
|
|||||||
|
|
||||||
class KemonoDiscordServerExtractor(KemonoExtractor):
|
class KemonoDiscordServerExtractor(KemonoExtractor):
|
||||||
subcategory = "discord-server"
|
subcategory = "discord-server"
|
||||||
pattern = rf"{BASE_PATTERN}/discord/server/(\d+)$"
|
pattern = BASE_PATTERN + r"/discord/server/(\d+)$"
|
||||||
example = "https://kemono.cr/discord/server/12345"
|
example = "https://kemono.cr/discord/server/12345"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -488,7 +488,7 @@ def discord_server_info(extr, server_id):
|
|||||||
class KemonoFavoriteExtractor(KemonoExtractor):
|
class KemonoFavoriteExtractor(KemonoExtractor):
|
||||||
"""Extractor for kemono.cr favorites"""
|
"""Extractor for kemono.cr favorites"""
|
||||||
subcategory = "favorite"
|
subcategory = "favorite"
|
||||||
pattern = rf"{BASE_PATTERN}/(?:account/)?favorites()()(?:/?\?([^#]+))?"
|
pattern = BASE_PATTERN + r"/(?:account/)?favorites()()(?:/?\?([^#]+))?"
|
||||||
example = "https://kemono.cr/account/favorites/artists"
|
example = "https://kemono.cr/account/favorites/artists"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -536,7 +536,7 @@ class KemonoFavoriteExtractor(KemonoExtractor):
|
|||||||
class KemonoArtistsExtractor(KemonoExtractor):
|
class KemonoArtistsExtractor(KemonoExtractor):
|
||||||
"""Extractor for kemono artists"""
|
"""Extractor for kemono artists"""
|
||||||
subcategory = "artists"
|
subcategory = "artists"
|
||||||
pattern = rf"{BASE_PATTERN}/artists(?:\?([^#]+))?"
|
pattern = BASE_PATTERN + r"/artists(?:\?([^#]+))?"
|
||||||
example = "https://kemono.cr/artists"
|
example = "https://kemono.cr/artists"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class MadokamiMangaExtractor(MadokamiExtractor):
|
|||||||
subcategory = "manga"
|
subcategory = "manga"
|
||||||
directory_fmt = ("{category}", "{manga}")
|
directory_fmt = ("{category}", "{manga}")
|
||||||
archive_fmt = "{chapter_id}"
|
archive_fmt = "{chapter_id}"
|
||||||
pattern = rf"{BASE_PATTERN}/Manga/(\w/\w{{2}}/\w{{4}}/.+)"
|
pattern = BASE_PATTERN + r"/Manga/(\w/\w{2}/\w{4}/.+)"
|
||||||
example = "https://manga.madokami.al/Manga/A/AB/ABCD/ABCDE_TITLE"
|
example = "https://manga.madokami.al/Manga/A/AB/ABCD/ABCDE_TITLE"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -83,8 +83,8 @@ class MangadexCoversExtractor(MangadexExtractor):
|
|||||||
directory_fmt = ("{category}", "{manga}", "Covers")
|
directory_fmt = ("{category}", "{manga}", "Covers")
|
||||||
filename_fmt = "{volume:>02}_{lang}.{extension}"
|
filename_fmt = "{volume:>02}_{lang}.{extension}"
|
||||||
archive_fmt = "c_{cover_id}"
|
archive_fmt = "c_{cover_id}"
|
||||||
pattern = (rf"{BASE_PATTERN}/(?:title|manga)/(?!follows|feed$)([0-9a-f-]+)"
|
pattern = (BASE_PATTERN + r"/(?:title|manga)/(?!follows|feed$)([0-9a-f-]+)"
|
||||||
rf"(?:/[^/?#]+)?\?tab=art")
|
r"(?:/[^/?#]+)?\?tab=art")
|
||||||
example = ("https://mangadex.org/title"
|
example = ("https://mangadex.org/title"
|
||||||
"/01234567-89ab-cdef-0123-456789abcdef?tab=art")
|
"/01234567-89ab-cdef-0123-456789abcdef?tab=art")
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ class MangadexCoversExtractor(MangadexExtractor):
|
|||||||
class MangadexChapterExtractor(MangadexExtractor):
|
class MangadexChapterExtractor(MangadexExtractor):
|
||||||
"""Extractor for manga-chapters from mangadex.org"""
|
"""Extractor for manga-chapters from mangadex.org"""
|
||||||
subcategory = "chapter"
|
subcategory = "chapter"
|
||||||
pattern = rf"{BASE_PATTERN}/chapter/([0-9a-f-]+)"
|
pattern = BASE_PATTERN + r"/chapter/([0-9a-f-]+)"
|
||||||
example = ("https://mangadex.org/chapter"
|
example = ("https://mangadex.org/chapter"
|
||||||
"/01234567-89ab-cdef-0123-456789abcdef")
|
"/01234567-89ab-cdef-0123-456789abcdef")
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ class MangadexChapterExtractor(MangadexExtractor):
|
|||||||
class MangadexMangaExtractor(MangadexExtractor):
|
class MangadexMangaExtractor(MangadexExtractor):
|
||||||
"""Extractor for manga from mangadex.org"""
|
"""Extractor for manga from mangadex.org"""
|
||||||
subcategory = "manga"
|
subcategory = "manga"
|
||||||
pattern = rf"{BASE_PATTERN}/(?:title|manga)/(?!follows|feed$)([0-9a-f-]+)"
|
pattern = BASE_PATTERN + r"/(?:title|manga)/(?!follows|feed$)([0-9a-f-]+)"
|
||||||
example = ("https://mangadex.org/title"
|
example = ("https://mangadex.org/title"
|
||||||
"/01234567-89ab-cdef-0123-456789abcdef")
|
"/01234567-89ab-cdef-0123-456789abcdef")
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ class MangadexMangaExtractor(MangadexExtractor):
|
|||||||
class MangadexFeedExtractor(MangadexExtractor):
|
class MangadexFeedExtractor(MangadexExtractor):
|
||||||
"""Extractor for chapters from your Updates Feed"""
|
"""Extractor for chapters from your Updates Feed"""
|
||||||
subcategory = "feed"
|
subcategory = "feed"
|
||||||
pattern = rf"{BASE_PATTERN}/titles?/feed$()"
|
pattern = BASE_PATTERN + r"/titles?/feed$()"
|
||||||
example = "https://mangadex.org/title/feed"
|
example = "https://mangadex.org/title/feed"
|
||||||
|
|
||||||
def chapters(self):
|
def chapters(self):
|
||||||
@@ -177,7 +177,7 @@ class MangadexFeedExtractor(MangadexExtractor):
|
|||||||
class MangadexFollowingExtractor(MangadexExtractor):
|
class MangadexFollowingExtractor(MangadexExtractor):
|
||||||
"""Extractor for followed manga from your Library"""
|
"""Extractor for followed manga from your Library"""
|
||||||
subcategory = "following"
|
subcategory = "following"
|
||||||
pattern = rf"{BASE_PATTERN}/titles?/follows(?:\?([^#]+))?$"
|
pattern = BASE_PATTERN + r"/titles?/follows(?:\?([^#]+))?$"
|
||||||
example = "https://mangadex.org/title/follows"
|
example = "https://mangadex.org/title/follows"
|
||||||
|
|
||||||
items = MangadexExtractor._items_manga
|
items = MangadexExtractor._items_manga
|
||||||
@@ -189,8 +189,8 @@ class MangadexFollowingExtractor(MangadexExtractor):
|
|||||||
class MangadexListExtractor(MangadexExtractor):
|
class MangadexListExtractor(MangadexExtractor):
|
||||||
"""Extractor for mangadex MDLists"""
|
"""Extractor for mangadex MDLists"""
|
||||||
subcategory = "list"
|
subcategory = "list"
|
||||||
pattern = (rf"{BASE_PATTERN}"
|
pattern = (BASE_PATTERN +
|
||||||
rf"/list/([0-9a-f-]+)(?:/[^/?#]*)?(?:\?tab=(\w+))?")
|
r"/list/([0-9a-f-]+)(?:/[^/?#]*)?(?:\?tab=(\w+))?")
|
||||||
example = ("https://mangadex.org/list"
|
example = ("https://mangadex.org/list"
|
||||||
"/01234567-89ab-cdef-0123-456789abcdef/NAME")
|
"/01234567-89ab-cdef-0123-456789abcdef/NAME")
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ class MangadexListExtractor(MangadexExtractor):
|
|||||||
class MangadexAuthorExtractor(MangadexExtractor):
|
class MangadexAuthorExtractor(MangadexExtractor):
|
||||||
"""Extractor for mangadex authors"""
|
"""Extractor for mangadex authors"""
|
||||||
subcategory = "author"
|
subcategory = "author"
|
||||||
pattern = rf"{BASE_PATTERN}/author/([0-9a-f-]+)"
|
pattern = BASE_PATTERN + r"/author/([0-9a-f-]+)"
|
||||||
example = ("https://mangadex.org/author"
|
example = ("https://mangadex.org/author"
|
||||||
"/01234567-89ab-cdef-0123-456789abcdef/NAME")
|
"/01234567-89ab-cdef-0123-456789abcdef/NAME")
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class MangafireChapterExtractor(MangafireBase, ChapterExtractor):
|
|||||||
"{page:>03}.{extension}")
|
"{page:>03}.{extension}")
|
||||||
archive_fmt = (
|
archive_fmt = (
|
||||||
"{manga_id}_{chapter_id}_{page}")
|
"{manga_id}_{chapter_id}_{page}")
|
||||||
pattern = (rf"{BASE_PATTERN}/read/([\w-]+\.(\w+))/([\w-]+)"
|
pattern = (BASE_PATTERN + r"/read/([\w-]+\.(\w+))/([\w-]+)"
|
||||||
rf"/((chapter|volume)-\d+(?:\D.*)?)")
|
r"/((chapter|volume)-\d+(?:\D.*)?)")
|
||||||
example = "https://mangafire.to/read/MANGA.ID/LANG/chapter-123"
|
example = "https://mangafire.to/read/MANGA.ID/LANG/chapter-123"
|
||||||
|
|
||||||
def metadata(self, _):
|
def metadata(self, _):
|
||||||
@@ -64,7 +64,7 @@ class MangafireChapterExtractor(MangafireBase, ChapterExtractor):
|
|||||||
class MangafireMangaExtractor(MangafireBase, MangaExtractor):
|
class MangafireMangaExtractor(MangafireBase, MangaExtractor):
|
||||||
"""Extractor for mangafire manga"""
|
"""Extractor for mangafire manga"""
|
||||||
chapterclass = MangafireChapterExtractor
|
chapterclass = MangafireChapterExtractor
|
||||||
pattern = rf"{BASE_PATTERN}/manga/([\w-]+)\.(\w+)"
|
pattern = BASE_PATTERN + r"/manga/([\w-]+)\.(\w+)"
|
||||||
example = "https://mangafire.to/manga/MANGA.ID"
|
example = "https://mangafire.to/manga/MANGA.ID"
|
||||||
|
|
||||||
def chapters(self, page):
|
def chapters(self, page):
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ class MangareaderChapterExtractor(MangareaderBase, ChapterExtractor):
|
|||||||
"{page:>03}.{extension}")
|
"{page:>03}.{extension}")
|
||||||
archive_fmt = (
|
archive_fmt = (
|
||||||
"{manga_id}_{chapter_id}_{page}")
|
"{manga_id}_{chapter_id}_{page}")
|
||||||
pattern = (rf"{BASE_PATTERN}/read/([\w-]+-\d+)/([^/?#]+)"
|
pattern = (BASE_PATTERN + r"/read/([\w-]+-\d+)/([^/?#]+)"
|
||||||
rf"/(chapter|volume)-(\d+[^/?#]*)")
|
r"/(chapter|volume)-(\d+[^/?#]*)")
|
||||||
example = "https://mangareader.to/read/MANGA-123/LANG/chapter-123"
|
example = "https://mangareader.to/read/MANGA-123/LANG/chapter-123"
|
||||||
|
|
||||||
def metadata(self, _):
|
def metadata(self, _):
|
||||||
@@ -81,7 +81,7 @@ class MangareaderChapterExtractor(MangareaderBase, ChapterExtractor):
|
|||||||
class MangareaderMangaExtractor(MangareaderBase, MangaExtractor):
|
class MangareaderMangaExtractor(MangareaderBase, MangaExtractor):
|
||||||
"""Extractor for mangareader manga"""
|
"""Extractor for mangareader manga"""
|
||||||
chapterclass = MangareaderChapterExtractor
|
chapterclass = MangareaderChapterExtractor
|
||||||
pattern = rf"{BASE_PATTERN}/([\w-]+-\d+)"
|
pattern = BASE_PATTERN + r"/([\w-]+-\d+)"
|
||||||
example = "https://mangareader.to/MANGA-123"
|
example = "https://mangareader.to/MANGA-123"
|
||||||
|
|
||||||
def chapters(self, page):
|
def chapters(self, page):
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class MangataroBase():
|
|||||||
|
|
||||||
class MangataroChapterExtractor(MangataroBase, ChapterExtractor):
|
class MangataroChapterExtractor(MangataroBase, ChapterExtractor):
|
||||||
"""Extractor for mangataro manga chapters"""
|
"""Extractor for mangataro manga chapters"""
|
||||||
pattern = rf"{BASE_PATTERN}(/read/([^/?#]+)/(?:[^/?#]*-)?(\d+))"
|
pattern = BASE_PATTERN + r"(/read/([^/?#]+)/(?:[^/?#]*-)?(\d+))"
|
||||||
example = "https://mangataro.org/read/MANGA/ch123-12345"
|
example = "https://mangataro.org/read/MANGA/ch123-12345"
|
||||||
|
|
||||||
def metadata(self, page):
|
def metadata(self, page):
|
||||||
@@ -59,7 +59,7 @@ class MangataroChapterExtractor(MangataroBase, ChapterExtractor):
|
|||||||
class MangataroMangaExtractor(MangataroBase, MangaExtractor):
|
class MangataroMangaExtractor(MangataroBase, MangaExtractor):
|
||||||
"""Extractor for mangataro manga"""
|
"""Extractor for mangataro manga"""
|
||||||
chapterclass = MangataroChapterExtractor
|
chapterclass = MangataroChapterExtractor
|
||||||
pattern = rf"{BASE_PATTERN}(/manga/([^/?#]+))"
|
pattern = BASE_PATTERN + r"(/manga/([^/?#]+))"
|
||||||
example = "https://mangataro.org/manga/MANGA"
|
example = "https://mangataro.org/manga/MANGA"
|
||||||
|
|
||||||
def chapters(self, page):
|
def chapters(self, page):
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class MyhentaigalleryBase():
|
|||||||
class MyhentaigalleryGalleryExtractor(MyhentaigalleryBase, GalleryExtractor):
|
class MyhentaigalleryGalleryExtractor(MyhentaigalleryBase, GalleryExtractor):
|
||||||
"""Extractor for image galleries from myhentaigallery.com"""
|
"""Extractor for image galleries from myhentaigallery.com"""
|
||||||
directory_fmt = ("{category}", "{gallery_id} {artist:?[/] /J, }{title}")
|
directory_fmt = ("{category}", "{gallery_id} {artist:?[/] /J, }{title}")
|
||||||
pattern = rf"{BASE_PATTERN}/g(?:allery/(?:thumbnails|show))?/(\d+)"
|
pattern = BASE_PATTERN + r"/g(?:allery/(?:thumbnails|show))?/(\d+)"
|
||||||
example = "https://myhentaigallery.com/g/12345"
|
example = "https://myhentaigallery.com/g/12345"
|
||||||
|
|
||||||
def __init__(self, match):
|
def __init__(self, match):
|
||||||
@@ -62,7 +62,7 @@ class MyhentaigalleryGalleryExtractor(MyhentaigalleryBase, GalleryExtractor):
|
|||||||
class MyhentaigalleryTagExtractor(MyhentaigalleryBase, Extractor):
|
class MyhentaigalleryTagExtractor(MyhentaigalleryBase, Extractor):
|
||||||
"""Extractor for myhentaigallery tag searches"""
|
"""Extractor for myhentaigallery tag searches"""
|
||||||
subcategory = "tag"
|
subcategory = "tag"
|
||||||
pattern = rf"{BASE_PATTERN}(/g/(artist|category|group|parody)/(\d+).*)"
|
pattern = BASE_PATTERN + r"(/g/(artist|category|group|parody)/(\d+).*)"
|
||||||
example = "https://myhentaigallery.com/g/category/123"
|
example = "https://myhentaigallery.com/g/category/123"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -176,8 +176,8 @@ class PoipikuExtractor(Extractor):
|
|||||||
class PoipikuUserExtractor(PoipikuExtractor):
|
class PoipikuUserExtractor(PoipikuExtractor):
|
||||||
"""Extractor for posts from a poipiku user"""
|
"""Extractor for posts from a poipiku user"""
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = (rf"{BASE_PATTERN}/(?:IllustListPcV\.jsp\?PG=(\d+)&ID=)?"
|
pattern = (BASE_PATTERN + r"/(?:IllustListPcV\.jsp\?PG=(\d+)&ID=)?"
|
||||||
rf"(\d+)/?(?:$|[?&#])")
|
r"(\d+)/?(?:$|[?&#])")
|
||||||
example = "https://poipiku.com/12345/"
|
example = "https://poipiku.com/12345/"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -207,7 +207,7 @@ class PoipikuUserExtractor(PoipikuExtractor):
|
|||||||
class PoipikuPostExtractor(PoipikuExtractor):
|
class PoipikuPostExtractor(PoipikuExtractor):
|
||||||
"""Extractor for a poipiku post"""
|
"""Extractor for a poipiku post"""
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/(\d+)/(\d+)"
|
pattern = BASE_PATTERN + r"/(\d+)/(\d+)"
|
||||||
example = "https://poipiku.com/12345/12345.html"
|
example = "https://poipiku.com/12345/12345.html"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ class PornpicsListingExtractor(PornpicsExtractor):
|
|||||||
and use single quotes in HTML, unlike category pages.
|
and use single quotes in HTML, unlike category pages.
|
||||||
"""
|
"""
|
||||||
subcategory = "listing"
|
subcategory = "listing"
|
||||||
pattern = (rf"{BASE_PATTERN}"
|
pattern = (BASE_PATTERN +
|
||||||
rf"/(popular|recent|rating|likes|views|comments)/?$")
|
r"/(popular|recent|rating|likes|views|comments)/?$")
|
||||||
example = "https://www.pornpics.com/popular/"
|
example = "https://www.pornpics.com/popular/"
|
||||||
|
|
||||||
def galleries(self):
|
def galleries(self):
|
||||||
@@ -142,7 +142,7 @@ class PornpicsListingExtractor(PornpicsExtractor):
|
|||||||
class PornpicsCategoryExtractor(PornpicsExtractor):
|
class PornpicsCategoryExtractor(PornpicsExtractor):
|
||||||
"""Extractor for galleries from pornpics categories"""
|
"""Extractor for galleries from pornpics categories"""
|
||||||
subcategory = "category"
|
subcategory = "category"
|
||||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/?$"
|
pattern = BASE_PATTERN + r"/([^/?#]+)/?$"
|
||||||
example = "https://www.pornpics.com/ass/"
|
example = "https://www.pornpics.com/ass/"
|
||||||
|
|
||||||
def galleries(self):
|
def galleries(self):
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class S3ndpicsExtractor(Extractor):
|
|||||||
|
|
||||||
class S3ndpicsPostExtractor(S3ndpicsExtractor):
|
class S3ndpicsPostExtractor(S3ndpicsExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/post/([0-9a-f]+)"
|
pattern = BASE_PATTERN + r"/post/([0-9a-f]+)"
|
||||||
example = "https://s3nd.pics/post/0123456789abcdef01234567"
|
example = "https://s3nd.pics/post/0123456789abcdef01234567"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -69,7 +69,7 @@ class S3ndpicsPostExtractor(S3ndpicsExtractor):
|
|||||||
|
|
||||||
class S3ndpicsUserExtractor(S3ndpicsExtractor):
|
class S3ndpicsUserExtractor(S3ndpicsExtractor):
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{BASE_PATTERN}/user/(\w+)"
|
pattern = BASE_PATTERN + r"/user/(\w+)"
|
||||||
example = "https://s3nd.pics/user/USER"
|
example = "https://s3nd.pics/user/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -87,7 +87,7 @@ class S3ndpicsUserExtractor(S3ndpicsExtractor):
|
|||||||
|
|
||||||
class S3ndpicsSearchExtractor(S3ndpicsExtractor):
|
class S3ndpicsSearchExtractor(S3ndpicsExtractor):
|
||||||
subcategory = "search"
|
subcategory = "search"
|
||||||
pattern = rf"{BASE_PATTERN}/search/?\?([^#]+)"
|
pattern = BASE_PATTERN + r"/search/?\?([^#]+)"
|
||||||
example = "https://s3nd.pics/search?QUERY"
|
example = "https://s3nd.pics/search?QUERY"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class SchalenetworkGalleryExtractor(SchalenetworkExtractor, GalleryExtractor):
|
|||||||
directory_fmt = ("{category}", "{id} {title}")
|
directory_fmt = ("{category}", "{id} {title}")
|
||||||
archive_fmt = "{id}_{num}"
|
archive_fmt = "{id}_{num}"
|
||||||
request_interval = 0.0
|
request_interval = 0.0
|
||||||
pattern = rf"{BASE_PATTERN}/(?:g|reader)/(\d+)/(\w+)"
|
pattern = BASE_PATTERN + r"/(?:g|reader)/(\d+)/(\w+)"
|
||||||
example = "https://niyaniya.moe/g/12345/67890abcde/"
|
example = "https://niyaniya.moe/g/12345/67890abcde/"
|
||||||
|
|
||||||
TAG_TYPES = {
|
TAG_TYPES = {
|
||||||
@@ -227,7 +227,7 @@ class SchalenetworkGalleryExtractor(SchalenetworkExtractor, GalleryExtractor):
|
|||||||
class SchalenetworkSearchExtractor(SchalenetworkExtractor):
|
class SchalenetworkSearchExtractor(SchalenetworkExtractor):
|
||||||
"""Extractor for schale.network search results"""
|
"""Extractor for schale.network search results"""
|
||||||
subcategory = "search"
|
subcategory = "search"
|
||||||
pattern = rf"{BASE_PATTERN}/(?:tag/([^/?#]+)|browse)?(?:/?\?([^#]*))?$"
|
pattern = BASE_PATTERN + r"/(?:tag/([^/?#]+)|browse)?(?:/?\?([^#]*))?$"
|
||||||
example = "https://niyaniya.moe/browse?s=QUERY"
|
example = "https://niyaniya.moe/browse?s=QUERY"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -252,7 +252,7 @@ class SchalenetworkSearchExtractor(SchalenetworkExtractor):
|
|||||||
class SchalenetworkFavoriteExtractor(SchalenetworkExtractor):
|
class SchalenetworkFavoriteExtractor(SchalenetworkExtractor):
|
||||||
"""Extractor for schale.network favorites"""
|
"""Extractor for schale.network favorites"""
|
||||||
subcategory = "favorite"
|
subcategory = "favorite"
|
||||||
pattern = rf"{BASE_PATTERN}/favorites(?:\?([^#]*))?"
|
pattern = BASE_PATTERN + r"/favorites(?:\?([^#]*))?"
|
||||||
example = "https://niyaniya.moe/favorites"
|
example = "https://niyaniya.moe/favorites"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ class SexcomFeedExtractor(SexcomExtractor):
|
|||||||
"""Extractor for pins from your account's main feed on www.sex.com"""
|
"""Extractor for pins from your account's main feed on www.sex.com"""
|
||||||
subcategory = "feed"
|
subcategory = "feed"
|
||||||
directory_fmt = ("{category}", "feed")
|
directory_fmt = ("{category}", "feed")
|
||||||
pattern = rf"{BASE_PATTERN}/feed"
|
pattern = BASE_PATTERN + r"/feed"
|
||||||
example = "https://www.sex.com/feed/"
|
example = "https://www.sex.com/feed/"
|
||||||
|
|
||||||
def metadata(self):
|
def metadata(self):
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ class SizebooruExtractor(BooruExtractor):
|
|||||||
class SizebooruPostExtractor(SizebooruExtractor):
|
class SizebooruPostExtractor(SizebooruExtractor):
|
||||||
"""Extractor for sizebooru posts"""
|
"""Extractor for sizebooru posts"""
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/Details/(\d+)"
|
pattern = BASE_PATTERN + r"/Details/(\d+)"
|
||||||
example = "https://sizebooru.com/Details/12345"
|
example = "https://sizebooru.com/Details/12345"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -109,7 +109,7 @@ class SizebooruTagExtractor(SizebooruExtractor):
|
|||||||
"""Extractor for sizebooru tag searches"""
|
"""Extractor for sizebooru tag searches"""
|
||||||
subcategory = "tag"
|
subcategory = "tag"
|
||||||
directory_fmt = ("{category}", "{search_tags}")
|
directory_fmt = ("{category}", "{search_tags}")
|
||||||
pattern = rf"{BASE_PATTERN}/Search/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/Search/([^/?#]+)"
|
||||||
example = "https://sizebooru.com/Search/TAG"
|
example = "https://sizebooru.com/Search/TAG"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -122,7 +122,7 @@ class SizebooruGalleryExtractor(SizebooruExtractor):
|
|||||||
"""Extractor for sizebooru galleries"""
|
"""Extractor for sizebooru galleries"""
|
||||||
subcategory = "gallery"
|
subcategory = "gallery"
|
||||||
directory_fmt = ("{category}", "{gallery_name} ({gallery_id})")
|
directory_fmt = ("{category}", "{gallery_name} ({gallery_id})")
|
||||||
pattern = rf"{BASE_PATTERN}/Galleries/List/(\d+)"
|
pattern = BASE_PATTERN + r"/Galleries/List/(\d+)"
|
||||||
example = "https://sizebooru.com/Galleries/List/123"
|
example = "https://sizebooru.com/Galleries/List/123"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -140,7 +140,7 @@ class SizebooruUserExtractor(SizebooruExtractor):
|
|||||||
"""Extractor for a sizebooru user's uploads"""
|
"""Extractor for a sizebooru user's uploads"""
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
directory_fmt = ("{category}", "Uploads {user}")
|
directory_fmt = ("{category}", "Uploads {user}")
|
||||||
pattern = rf"{BASE_PATTERN}/Profile/Uploads/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/Profile/Uploads/([^/?#]+)"
|
||||||
example = "https://sizebooru.com/Profile/Uploads/USER"
|
example = "https://sizebooru.com/Profile/Uploads/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -153,7 +153,7 @@ class SizebooruFavoriteExtractor(SizebooruExtractor):
|
|||||||
"""Extractor for a sizebooru user's favorites"""
|
"""Extractor for a sizebooru user's favorites"""
|
||||||
subcategory = "favorite"
|
subcategory = "favorite"
|
||||||
directory_fmt = ("{category}", "Favorites {user}")
|
directory_fmt = ("{category}", "Favorites {user}")
|
||||||
pattern = rf"{BASE_PATTERN}/Profile/Favorites/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/Profile/Favorites/([^/?#]+)"
|
||||||
example = "https://sizebooru.com/Profile/Favorites/USER"
|
example = "https://sizebooru.com/Profile/Favorites/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ class ThehentaiworldTagExtractor(ThehentaiworldExtractor):
|
|||||||
page_start = 1
|
page_start = 1
|
||||||
post_start = 0
|
post_start = 0
|
||||||
directory_fmt = ("{category}", "{search_tags}")
|
directory_fmt = ("{category}", "{search_tags}")
|
||||||
pattern = rf"{BASE_PATTERN}/tag/([^/?#]+)"
|
pattern = BASE_PATTERN + r"/tag/([^/?#]+)"
|
||||||
example = "https://thehentaiworld.com/tag/TAG/"
|
example = "https://thehentaiworld.com/tag/TAG/"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -132,8 +132,8 @@ class ThehentaiworldTagExtractor(ThehentaiworldExtractor):
|
|||||||
|
|
||||||
class ThehentaiworldPostExtractor(ThehentaiworldExtractor):
|
class ThehentaiworldPostExtractor(ThehentaiworldExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = (rf"{BASE_PATTERN}("
|
pattern = (BASE_PATTERN +
|
||||||
rf"/(?:video|(?:[\w-]+-)?hentai-image)s/([^/?#]+))")
|
r"(/(?:video|(?:[\w-]+-)?hentai-image)s/([^/?#]+))")
|
||||||
example = "https://thehentaiworld.com/hentai-images/SLUG/"
|
example = "https://thehentaiworld.com/hentai-images/SLUG/"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class TungstenExtractor(Extractor):
|
|||||||
|
|
||||||
class TungstenPostExtractor(TungstenExtractor):
|
class TungstenPostExtractor(TungstenExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = rf"{BASE_PATTERN}/post/(\w+)"
|
pattern = BASE_PATTERN + r"/post/(\w+)"
|
||||||
example = "https://tungsten.run/post/AbCdEfGhIjKlMnOp"
|
example = "https://tungsten.run/post/AbCdEfGhIjKlMnOp"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -64,7 +64,7 @@ class TungstenPostExtractor(TungstenExtractor):
|
|||||||
|
|
||||||
class TungstenModelExtractor(TungstenExtractor):
|
class TungstenModelExtractor(TungstenExtractor):
|
||||||
subcategory = "model"
|
subcategory = "model"
|
||||||
pattern = rf"{BASE_PATTERN}/model/(\w+)(?:/?\?model_version=(\w+))?"
|
pattern = BASE_PATTERN + r"/model/(\w+)(?:/?\?model_version=(\w+))?"
|
||||||
example = "https://tungsten.run/model/AbCdEfGhIjKlM"
|
example = "https://tungsten.run/model/AbCdEfGhIjKlM"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -87,7 +87,7 @@ class TungstenModelExtractor(TungstenExtractor):
|
|||||||
|
|
||||||
class TungstenUserExtractor(TungstenExtractor):
|
class TungstenUserExtractor(TungstenExtractor):
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)(?:/posts)?/?(?:\?([^#]+))?"
|
pattern = BASE_PATTERN + r"/user/([^/?#]+)(?:/posts)?/?(?:\?([^#]+))?"
|
||||||
example = "https://tungsten.run/user/USER"
|
example = "https://tungsten.run/user/USER"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import random
|
|||||||
|
|
||||||
BASE_PATTERN = (r"(?:https?://)?(?:www\.|mobile\.)?"
|
BASE_PATTERN = (r"(?:https?://)?(?:www\.|mobile\.)?"
|
||||||
r"(?:(?:[fv]x)?twitter|(?:fix(?:up|v))?x)\.com")
|
r"(?:(?:[fv]x)?twitter|(?:fix(?:up|v))?x)\.com")
|
||||||
USER_PATTERN = rf"{BASE_PATTERN}/([^/?#]+)"
|
USER_PATTERN = BASE_PATTERN + r"/([^/?#]+)"
|
||||||
|
|
||||||
|
|
||||||
class TwitterExtractor(Extractor):
|
class TwitterExtractor(Extractor):
|
||||||
@@ -749,7 +749,7 @@ class TwitterUserExtractor(Dispatch, TwitterExtractor):
|
|||||||
class TwitterTimelineExtractor(TwitterExtractor):
|
class TwitterTimelineExtractor(TwitterExtractor):
|
||||||
"""Extractor for a Twitter user timeline"""
|
"""Extractor for a Twitter user timeline"""
|
||||||
subcategory = "timeline"
|
subcategory = "timeline"
|
||||||
pattern = rf"{USER_PATTERN}/timeline(?!\w)"
|
pattern = USER_PATTERN + r"/timeline(?!\w)"
|
||||||
example = "https://x.com/USER/timeline"
|
example = "https://x.com/USER/timeline"
|
||||||
|
|
||||||
def _init_cursor(self):
|
def _init_cursor(self):
|
||||||
@@ -846,7 +846,7 @@ class TwitterTimelineExtractor(TwitterExtractor):
|
|||||||
class TwitterTweetsExtractor(TwitterExtractor):
|
class TwitterTweetsExtractor(TwitterExtractor):
|
||||||
"""Extractor for Tweets from a user's Tweets timeline"""
|
"""Extractor for Tweets from a user's Tweets timeline"""
|
||||||
subcategory = "tweets"
|
subcategory = "tweets"
|
||||||
pattern = rf"{USER_PATTERN}/tweets(?!\w)"
|
pattern = USER_PATTERN + r"/tweets(?!\w)"
|
||||||
example = "https://x.com/USER/tweets"
|
example = "https://x.com/USER/tweets"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
@@ -856,7 +856,7 @@ class TwitterTweetsExtractor(TwitterExtractor):
|
|||||||
class TwitterRepliesExtractor(TwitterExtractor):
|
class TwitterRepliesExtractor(TwitterExtractor):
|
||||||
"""Extractor for Tweets from a user's timeline including replies"""
|
"""Extractor for Tweets from a user's timeline including replies"""
|
||||||
subcategory = "replies"
|
subcategory = "replies"
|
||||||
pattern = rf"{USER_PATTERN}/with_replies(?!\w)"
|
pattern = USER_PATTERN + r"/with_replies(?!\w)"
|
||||||
example = "https://x.com/USER/with_replies"
|
example = "https://x.com/USER/with_replies"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
@@ -866,7 +866,7 @@ class TwitterRepliesExtractor(TwitterExtractor):
|
|||||||
class TwitterHighlightsExtractor(TwitterExtractor):
|
class TwitterHighlightsExtractor(TwitterExtractor):
|
||||||
"""Extractor for Tweets from a user's highlights timeline"""
|
"""Extractor for Tweets from a user's highlights timeline"""
|
||||||
subcategory = "highlights"
|
subcategory = "highlights"
|
||||||
pattern = rf"{USER_PATTERN}/highlights(?!\w)"
|
pattern = USER_PATTERN + r"/highlights(?!\w)"
|
||||||
example = "https://x.com/USER/highlights"
|
example = "https://x.com/USER/highlights"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
@@ -876,7 +876,7 @@ class TwitterHighlightsExtractor(TwitterExtractor):
|
|||||||
class TwitterMediaExtractor(TwitterExtractor):
|
class TwitterMediaExtractor(TwitterExtractor):
|
||||||
"""Extractor for Tweets from a user's Media timeline"""
|
"""Extractor for Tweets from a user's Media timeline"""
|
||||||
subcategory = "media"
|
subcategory = "media"
|
||||||
pattern = rf"{USER_PATTERN}/media(?!\w)"
|
pattern = USER_PATTERN + r"/media(?!\w)"
|
||||||
example = "https://x.com/USER/media"
|
example = "https://x.com/USER/media"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
@@ -886,7 +886,7 @@ class TwitterMediaExtractor(TwitterExtractor):
|
|||||||
class TwitterLikesExtractor(TwitterExtractor):
|
class TwitterLikesExtractor(TwitterExtractor):
|
||||||
"""Extractor for liked tweets"""
|
"""Extractor for liked tweets"""
|
||||||
subcategory = "likes"
|
subcategory = "likes"
|
||||||
pattern = rf"{USER_PATTERN}/likes(?!\w)"
|
pattern = USER_PATTERN + r"/likes(?!\w)"
|
||||||
example = "https://x.com/USER/likes"
|
example = "https://x.com/USER/likes"
|
||||||
|
|
||||||
def metadata(self):
|
def metadata(self):
|
||||||
@@ -936,7 +936,7 @@ class TwitterListMembersExtractor(TwitterExtractor):
|
|||||||
class TwitterFollowingExtractor(TwitterExtractor):
|
class TwitterFollowingExtractor(TwitterExtractor):
|
||||||
"""Extractor for followed users"""
|
"""Extractor for followed users"""
|
||||||
subcategory = "following"
|
subcategory = "following"
|
||||||
pattern = rf"{USER_PATTERN}/following(?!\w)"
|
pattern = USER_PATTERN + r"/following(?!\w)"
|
||||||
example = "https://x.com/USER/following"
|
example = "https://x.com/USER/following"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -947,7 +947,7 @@ class TwitterFollowingExtractor(TwitterExtractor):
|
|||||||
class TwitterFollowersExtractor(TwitterExtractor):
|
class TwitterFollowersExtractor(TwitterExtractor):
|
||||||
"""Extractor for a user's followers"""
|
"""Extractor for a user's followers"""
|
||||||
subcategory = "followers"
|
subcategory = "followers"
|
||||||
pattern = rf"{USER_PATTERN}/followers(?!\w)"
|
pattern = USER_PATTERN + r"/followers(?!\w)"
|
||||||
example = "https://x.com/USER/followers"
|
example = "https://x.com/USER/followers"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -1093,7 +1093,7 @@ class TwitterQuotesExtractor(TwitterExtractor):
|
|||||||
class TwitterInfoExtractor(TwitterExtractor):
|
class TwitterInfoExtractor(TwitterExtractor):
|
||||||
"""Extractor for a user's profile data"""
|
"""Extractor for a user's profile data"""
|
||||||
subcategory = "info"
|
subcategory = "info"
|
||||||
pattern = rf"{USER_PATTERN}/info"
|
pattern = USER_PATTERN + r"/info"
|
||||||
example = "https://x.com/USER/info"
|
example = "https://x.com/USER/info"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
@@ -1112,7 +1112,7 @@ class TwitterAvatarExtractor(TwitterExtractor):
|
|||||||
subcategory = "avatar"
|
subcategory = "avatar"
|
||||||
filename_fmt = "avatar {date}.{extension}"
|
filename_fmt = "avatar {date}.{extension}"
|
||||||
archive_fmt = "AV_{user[id]}_{date}"
|
archive_fmt = "AV_{user[id]}_{date}"
|
||||||
pattern = rf"{USER_PATTERN}/photo"
|
pattern = USER_PATTERN + r"/photo"
|
||||||
example = "https://x.com/USER/photo"
|
example = "https://x.com/USER/photo"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
@@ -1134,7 +1134,7 @@ class TwitterBackgroundExtractor(TwitterExtractor):
|
|||||||
subcategory = "background"
|
subcategory = "background"
|
||||||
filename_fmt = "background {date}.{extension}"
|
filename_fmt = "background {date}.{extension}"
|
||||||
archive_fmt = "BG_{user[id]}_{date}"
|
archive_fmt = "BG_{user[id]}_{date}"
|
||||||
pattern = rf"{USER_PATTERN}/header_photo"
|
pattern = USER_PATTERN + r"/header_photo"
|
||||||
example = "https://x.com/USER/header_photo"
|
example = "https://x.com/USER/header_photo"
|
||||||
|
|
||||||
def tweets(self):
|
def tweets(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from ..cache import cache
|
|||||||
import random
|
import random
|
||||||
|
|
||||||
BASE_PATTERN = r"(?:https?://)?(?:www\.|m\.)?weibo\.c(?:om|n)"
|
BASE_PATTERN = r"(?:https?://)?(?:www\.|m\.)?weibo\.c(?:om|n)"
|
||||||
USER_PATTERN = rf"{BASE_PATTERN}/(?:(u|n|p(?:rofile)?)/)?([^/?#]+)(?:/home)?"
|
USER_PATTERN = BASE_PATTERN + r"/(?:(u|n|p(?:rofile)?)/)?([^/?#]+)(?:/home)?"
|
||||||
|
|
||||||
|
|
||||||
class WeiboExtractor(Extractor):
|
class WeiboExtractor(Extractor):
|
||||||
@@ -296,7 +296,7 @@ class WeiboExtractor(Extractor):
|
|||||||
class WeiboUserExtractor(WeiboExtractor):
|
class WeiboUserExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo user profiles"""
|
"""Extractor for weibo user profiles"""
|
||||||
subcategory = "user"
|
subcategory = "user"
|
||||||
pattern = rf"{USER_PATTERN}(?:$|#)"
|
pattern = USER_PATTERN + r"(?:$|#)"
|
||||||
example = "https://weibo.com/USER"
|
example = "https://weibo.com/USER"
|
||||||
|
|
||||||
# do NOT override 'initialize()'
|
# do NOT override 'initialize()'
|
||||||
@@ -318,7 +318,7 @@ class WeiboUserExtractor(WeiboExtractor):
|
|||||||
class WeiboHomeExtractor(WeiboExtractor):
|
class WeiboHomeExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo 'home' listings"""
|
"""Extractor for weibo 'home' listings"""
|
||||||
subcategory = "home"
|
subcategory = "home"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=home"
|
pattern = USER_PATTERN + r"\?tabtype=home"
|
||||||
example = "https://weibo.com/USER?tabtype=home"
|
example = "https://weibo.com/USER?tabtype=home"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -330,7 +330,7 @@ class WeiboHomeExtractor(WeiboExtractor):
|
|||||||
class WeiboFeedExtractor(WeiboExtractor):
|
class WeiboFeedExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo user feeds"""
|
"""Extractor for weibo user feeds"""
|
||||||
subcategory = "feed"
|
subcategory = "feed"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=feed"
|
pattern = USER_PATTERN + r"\?tabtype=feed"
|
||||||
example = "https://weibo.com/USER?tabtype=feed"
|
example = "https://weibo.com/USER?tabtype=feed"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -344,7 +344,7 @@ class WeiboFeedExtractor(WeiboExtractor):
|
|||||||
class WeiboVideosExtractor(WeiboExtractor):
|
class WeiboVideosExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo 'video' listings"""
|
"""Extractor for weibo 'video' listings"""
|
||||||
subcategory = "videos"
|
subcategory = "videos"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=video"
|
pattern = USER_PATTERN + r"\?tabtype=video"
|
||||||
example = "https://weibo.com/USER?tabtype=video"
|
example = "https://weibo.com/USER?tabtype=video"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -358,7 +358,7 @@ class WeiboVideosExtractor(WeiboExtractor):
|
|||||||
class WeiboNewvideoExtractor(WeiboExtractor):
|
class WeiboNewvideoExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo 'newVideo' listings"""
|
"""Extractor for weibo 'newVideo' listings"""
|
||||||
subcategory = "newvideo"
|
subcategory = "newvideo"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=newVideo"
|
pattern = USER_PATTERN + r"\?tabtype=newVideo"
|
||||||
example = "https://weibo.com/USER?tabtype=newVideo"
|
example = "https://weibo.com/USER?tabtype=newVideo"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -370,7 +370,7 @@ class WeiboNewvideoExtractor(WeiboExtractor):
|
|||||||
class WeiboArticleExtractor(WeiboExtractor):
|
class WeiboArticleExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo 'article' listings"""
|
"""Extractor for weibo 'article' listings"""
|
||||||
subcategory = "article"
|
subcategory = "article"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=article"
|
pattern = USER_PATTERN + r"\?tabtype=article"
|
||||||
example = "https://weibo.com/USER?tabtype=article"
|
example = "https://weibo.com/USER?tabtype=article"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -382,7 +382,7 @@ class WeiboArticleExtractor(WeiboExtractor):
|
|||||||
class WeiboAlbumExtractor(WeiboExtractor):
|
class WeiboAlbumExtractor(WeiboExtractor):
|
||||||
"""Extractor for weibo 'album' listings"""
|
"""Extractor for weibo 'album' listings"""
|
||||||
subcategory = "album"
|
subcategory = "album"
|
||||||
pattern = rf"{USER_PATTERN}\?tabtype=album"
|
pattern = USER_PATTERN + r"\?tabtype=album"
|
||||||
example = "https://weibo.com/USER?tabtype=album"
|
example = "https://weibo.com/USER?tabtype=album"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
@@ -404,7 +404,7 @@ class WeiboAlbumExtractor(WeiboExtractor):
|
|||||||
class WeiboStatusExtractor(WeiboExtractor):
|
class WeiboStatusExtractor(WeiboExtractor):
|
||||||
"""Extractor for a weibo status"""
|
"""Extractor for a weibo status"""
|
||||||
subcategory = "status"
|
subcategory = "status"
|
||||||
pattern = rf"{BASE_PATTERN}/(detail|status|\d+)/(\w+)"
|
pattern = BASE_PATTERN + r"/(detail|status|\d+)/(\w+)"
|
||||||
example = "https://weibo.com/detail/12345"
|
example = "https://weibo.com/detail/12345"
|
||||||
|
|
||||||
def statuses(self):
|
def statuses(self):
|
||||||
|
|||||||
@@ -282,8 +282,8 @@ BASE_PATTERN = XenforoExtractor.update({
|
|||||||
|
|
||||||
class XenforoPostExtractor(XenforoExtractor):
|
class XenforoPostExtractor(XenforoExtractor):
|
||||||
subcategory = "post"
|
subcategory = "post"
|
||||||
pattern = (rf"{BASE_PATTERN}(/(?:index\.php\?)?threads"
|
pattern = (BASE_PATTERN + r"(/(?:index\.php\?)?threads"
|
||||||
rf"/[^/?#]+/post-|/posts/)(\d+)")
|
r"/[^/?#]+/post-|/posts/)(\d+)")
|
||||||
example = "https://simpcity.cr/threads/TITLE.12345/post-54321"
|
example = "https://simpcity.cr/threads/TITLE.12345/post-54321"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -303,8 +303,8 @@ class XenforoPostExtractor(XenforoExtractor):
|
|||||||
|
|
||||||
class XenforoThreadExtractor(XenforoExtractor):
|
class XenforoThreadExtractor(XenforoExtractor):
|
||||||
subcategory = "thread"
|
subcategory = "thread"
|
||||||
pattern = (rf"{BASE_PATTERN}(/(?:index\.php\?)?threads"
|
pattern = (BASE_PATTERN + r"(/(?:index\.php\?)?threads"
|
||||||
rf"/(?:[^/?#]+\.)?\d+)(?:/page-(\d+))?")
|
r"/(?:[^/?#]+\.)?\d+)(?:/page-(\d+))?")
|
||||||
example = "https://simpcity.cr/threads/TITLE.12345/"
|
example = "https://simpcity.cr/threads/TITLE.12345/"
|
||||||
|
|
||||||
def posts(self):
|
def posts(self):
|
||||||
@@ -332,8 +332,8 @@ class XenforoThreadExtractor(XenforoExtractor):
|
|||||||
|
|
||||||
class XenforoForumExtractor(XenforoExtractor):
|
class XenforoForumExtractor(XenforoExtractor):
|
||||||
subcategory = "forum"
|
subcategory = "forum"
|
||||||
pattern = (rf"{BASE_PATTERN}(/(?:index\.php\?)?forums"
|
pattern = (BASE_PATTERN + r"(/(?:index\.php\?)?forums"
|
||||||
rf"/(?:[^/?#]+\.)?[^/?#]+)(?:/page-(\d+))?")
|
r"/(?:[^/?#]+\.)?[^/?#]+)(?:/page-(\d+))?")
|
||||||
example = "https://simpcity.cr/forums/TITLE.123/"
|
example = "https://simpcity.cr/forums/TITLE.123/"
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user