@@ -34,7 +34,7 @@ class _2chenThreadExtractor(_2chenExtractor):
|
||||
directory_fmt = ("{category}", "{board}", "{thread} {title}")
|
||||
filename_fmt = "{time} {filename}.{extension}"
|
||||
archive_fmt = "{board}_{thread}_{no}_{time}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/(\d+)"
|
||||
example = "https://sturdychan.help/a/12345/"
|
||||
|
||||
def items(self):
|
||||
@@ -84,7 +84,7 @@ class _2chenThreadExtractor(_2chenExtractor):
|
||||
class _2chenBoardExtractor(_2chenExtractor):
|
||||
"""Extractor for 2chen boards"""
|
||||
subcategory = "board"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)(?:/catalog|/?$)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)(?:/catalog|/?$)"
|
||||
example = "https://sturdychan.help/a/"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -92,7 +92,7 @@ class _500pxExtractor(Extractor):
|
||||
class _500pxUserExtractor(_500pxExtractor):
|
||||
"""Extractor for photos from a user's photostream on 500px.com"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?!photo/|liked)(?:p/)?([^/?#]+)/?(?:$|[?#])"
|
||||
pattern = BASE_PATTERN + r"/(?!photo/|liked)(?:p/)?([^/?#]+)/?(?:$|[?#])"
|
||||
example = "https://500px.com/USER"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -121,8 +121,8 @@ class _500pxGalleryExtractor(_500pxExtractor):
|
||||
"""Extractor for photo galleries on 500px.com"""
|
||||
subcategory = "gallery"
|
||||
directory_fmt = ("{category}", "{user[username]}", "{gallery[name]}")
|
||||
pattern = (rf"{BASE_PATTERN}/(?!photo/)(?:p/)?"
|
||||
rf"([^/?#]+)/galleries/([^/?#]+)")
|
||||
pattern = (BASE_PATTERN + r"/(?!photo/)(?:p/)?"
|
||||
r"([^/?#]+)/galleries/([^/?#]+)")
|
||||
example = "https://500px.com/USER/galleries/GALLERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -178,7 +178,7 @@ class _500pxGalleryExtractor(_500pxExtractor):
|
||||
class _500pxFavoriteExtractor(_500pxExtractor):
|
||||
"""Extractor for favorite 500px photos"""
|
||||
subcategory = "favorite"
|
||||
pattern = rf"{BASE_PATTERN}/liked/?$"
|
||||
pattern = BASE_PATTERN + r"/liked/?$"
|
||||
example = "https://500px.com/liked"
|
||||
|
||||
def photos(self):
|
||||
@@ -202,7 +202,7 @@ class _500pxFavoriteExtractor(_500pxExtractor):
|
||||
class _500pxImageExtractor(_500pxExtractor):
|
||||
"""Extractor for individual images from 500px.com"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/photo/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/photo/(\d+)"
|
||||
example = "https://500px.com/photo/12345/TITLE"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -69,7 +69,7 @@ class _8chanThreadExtractor(_8chanExtractor):
|
||||
"{threadId} {subject[:50]}")
|
||||
filename_fmt = "{postId}{num:?-//} {filename[:200]}.{extension}"
|
||||
archive_fmt = "{boardUri}_{postId}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/(?:res|last)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/(?:res|last)/(\d+)"
|
||||
example = "https://8chan.moe/a/res/12345.html"
|
||||
|
||||
def items(self):
|
||||
@@ -107,7 +107,7 @@ class _8chanThreadExtractor(_8chanExtractor):
|
||||
class _8chanBoardExtractor(_8chanExtractor):
|
||||
"""Extractor for 8chan boards"""
|
||||
subcategory = "board"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/(?:(\d+)\.html)?$"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/(?:(\d+)\.html)?$"
|
||||
example = "https://8chan.moe/a/"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -81,7 +81,7 @@ class AgnphTagExtractor(AgnphExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/post/(?:\?([^#]+))?$"
|
||||
pattern = BASE_PATTERN + r"/gallery/post/(?:\?([^#]+))?$"
|
||||
example = "https://agn.ph/gallery/post/?search=TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -99,7 +99,7 @@ class AgnphTagExtractor(AgnphExtractor):
|
||||
class AgnphPostExtractor(AgnphExtractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/post/show/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/gallery/post/show/(\d+)"
|
||||
example = "https://agn.ph/gallery/post/show/12345/"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -118,7 +118,7 @@ class Ao3WorkExtractor(Ao3Extractor):
|
||||
directory_fmt = ("{category}", "{author}")
|
||||
filename_fmt = "{id} {title}.{extension}"
|
||||
archive_fmt = "{id}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/works/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/works/(\d+)"
|
||||
example = "https://archiveofourown.org/works/12345"
|
||||
|
||||
def _init(self):
|
||||
@@ -233,28 +233,28 @@ class Ao3WorkExtractor(Ao3Extractor):
|
||||
class Ao3SeriesExtractor(Ao3Extractor):
|
||||
"""Extractor for AO3 works of a series"""
|
||||
subcategory = "series"
|
||||
pattern = rf"{BASE_PATTERN}(/series/(\d+))"
|
||||
pattern = BASE_PATTERN + r"(/series/(\d+))"
|
||||
example = "https://archiveofourown.org/series/12345"
|
||||
|
||||
|
||||
class Ao3TagExtractor(Ao3Extractor):
|
||||
"""Extractor for AO3 works by tag"""
|
||||
subcategory = "tag"
|
||||
pattern = rf"{BASE_PATTERN}(/tags/([^/?#]+)/works(?:/?\?.+)?)"
|
||||
pattern = BASE_PATTERN + r"(/tags/([^/?#]+)/works(?:/?\?.+)?)"
|
||||
example = "https://archiveofourown.org/tags/TAG/works"
|
||||
|
||||
|
||||
class Ao3SearchExtractor(Ao3Extractor):
|
||||
"""Extractor for AO3 search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}(/works/search/?\?.+)"
|
||||
pattern = BASE_PATTERN + r"(/works/search/?\?.+)"
|
||||
example = "https://archiveofourown.org/works/search?work_search[query]=air"
|
||||
|
||||
|
||||
class Ao3UserExtractor(Dispatch, Ao3Extractor):
|
||||
"""Extractor for an AO3 user profile"""
|
||||
pattern = (rf"{BASE_PATTERN}/users/([^/?#]+(?:/pseuds/[^/?#]+)?)"
|
||||
rf"(?:/profile)?/?(?:$|\?|#)")
|
||||
pattern = (BASE_PATTERN + r"/users/([^/?#]+(?:/pseuds/[^/?#]+)?)"
|
||||
r"(?:/profile)?/?(?:$|\?|#)")
|
||||
example = "https://archiveofourown.org/users/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -269,16 +269,16 @@ class Ao3UserExtractor(Dispatch, Ao3Extractor):
|
||||
class Ao3UserWorksExtractor(Ao3Extractor):
|
||||
"""Extractor for works of an AO3 user"""
|
||||
subcategory = "user-works"
|
||||
pattern = (rf"{BASE_PATTERN}(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
rf"works(?:/?\?.+)?)")
|
||||
pattern = (BASE_PATTERN + r"(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
r"works(?:/?\?.+)?)")
|
||||
example = "https://archiveofourown.org/users/USER/works"
|
||||
|
||||
|
||||
class Ao3UserSeriesExtractor(Ao3Extractor):
|
||||
"""Extractor for series of an AO3 user"""
|
||||
subcategory = "user-series"
|
||||
pattern = (rf"{BASE_PATTERN}(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
rf"series(?:/?\?.+)?)")
|
||||
pattern = (BASE_PATTERN + r"(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
r"series(?:/?\?.+)?)")
|
||||
example = "https://archiveofourown.org/users/USER/series"
|
||||
|
||||
def items(self):
|
||||
@@ -297,8 +297,8 @@ class Ao3UserSeriesExtractor(Ao3Extractor):
|
||||
class Ao3UserBookmarkExtractor(Ao3Extractor):
|
||||
"""Extractor for bookmarked works of an AO3 user"""
|
||||
subcategory = "user-bookmark"
|
||||
pattern = (rf"{BASE_PATTERN}(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
rf"bookmarks(?:/?\?.+)?)")
|
||||
pattern = (BASE_PATTERN + r"(/users/([^/?#]+)/(?:pseuds/([^/?#]+)/)?"
|
||||
r"bookmarks(?:/?\?.+)?)")
|
||||
example = "https://archiveofourown.org/users/USER/bookmarks"
|
||||
|
||||
def items(self):
|
||||
@@ -308,7 +308,7 @@ class Ao3UserBookmarkExtractor(Ao3Extractor):
|
||||
class Ao3SubscriptionsExtractor(Ao3Extractor):
|
||||
"""Extractor for your AO3 account's subscriptions"""
|
||||
subcategory = "subscriptions"
|
||||
pattern = rf"{BASE_PATTERN}(/users/([^/?#]+)/subscriptions(?:/?\?.+)?)"
|
||||
pattern = BASE_PATTERN + r"(/users/([^/?#]+)/subscriptions(?:/?\?.+)?)"
|
||||
example = "https://archiveofourown.org/users/USER/subscriptions"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -36,7 +36,7 @@ class ArcalivePostExtractor(ArcaliveExtractor):
|
||||
directory_fmt = ("{category}", "{boardSlug}")
|
||||
filename_fmt = "{id}_{num}{title:? //[b:230]}.{extension}"
|
||||
archive_fmt = "{id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/b/(?:\w+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/b/(?:\w+)/(\d+)"
|
||||
example = "https://arca.live/b/breaking/123456789"
|
||||
|
||||
def items(self):
|
||||
@@ -115,7 +115,7 @@ class ArcalivePostExtractor(ArcaliveExtractor):
|
||||
class ArcaliveBoardExtractor(ArcaliveExtractor):
|
||||
"""Extractor for an arca.live board's posts"""
|
||||
subcategory = "board"
|
||||
pattern = rf"{BASE_PATTERN}/b/([^/?#]+)/?(?:\?([^#]+))?$"
|
||||
pattern = BASE_PATTERN + r"/b/([^/?#]+)/?(?:\?([^#]+))?$"
|
||||
example = "https://arca.live/b/breaking"
|
||||
|
||||
def articles(self):
|
||||
@@ -127,7 +127,7 @@ class ArcaliveBoardExtractor(ArcaliveExtractor):
|
||||
class ArcaliveUserExtractor(ArcaliveExtractor):
|
||||
"""Extractor for an arca.live users's posts"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/u/@([^/?#]+)/?(?:\?([^#]+))?$"
|
||||
pattern = BASE_PATTERN + r"/u/@([^/?#]+)/?(?:\?([^#]+))?$"
|
||||
example = "https://arca.live/u/@USER"
|
||||
|
||||
def articles(self):
|
||||
|
||||
@@ -211,7 +211,7 @@ class AryionGalleryExtractor(AryionExtractor):
|
||||
"""Extractor for a user's gallery on eka's portal"""
|
||||
subcategory = "gallery"
|
||||
categorytransfer = True
|
||||
pattern = rf"{BASE_PATTERN}/(?:gallery/|user/|latest.php\?name=)([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:gallery/|user/|latest.php\?name=)([^/?#]+)"
|
||||
example = "https://aryion.com/g4/gallery/USER"
|
||||
|
||||
def _init(self):
|
||||
@@ -238,7 +238,7 @@ class AryionFavoriteExtractor(AryionExtractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{user!l}", "favorites", "{folder}")
|
||||
archive_fmt = "f_{user}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/favorites/([^/?#]+)(?:/([^?#]+))?"
|
||||
pattern = BASE_PATTERN + r"/favorites/([^/?#]+)(?:/([^?#]+))?"
|
||||
example = "https://aryion.com/g4/favorites/USER"
|
||||
|
||||
def _init(self):
|
||||
@@ -253,7 +253,7 @@ class AryionWatchExtractor(AryionExtractor):
|
||||
"""Extractor for your watched users and tags"""
|
||||
subcategory = "watch"
|
||||
directory_fmt = ("{category}", "{user!l}",)
|
||||
pattern = rf"{BASE_PATTERN}/messagepage\.php()"
|
||||
pattern = BASE_PATTERN + r"/messagepage\.php()"
|
||||
example = "https://aryion.com/g4/messagepage.php"
|
||||
|
||||
def posts(self):
|
||||
@@ -271,7 +271,7 @@ class AryionTagExtractor(AryionExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "tags", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/tags\.php\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/tags\.php\?([^#]+)"
|
||||
example = "https://aryion.com/g4/tags.php?tag=TAG"
|
||||
|
||||
def _init(self):
|
||||
@@ -293,7 +293,7 @@ class AryionSearchExtractor(AryionExtractor):
|
||||
"{search[q]|search[tags]|search[user]}")
|
||||
archive_fmt = ("s_{search[prefix]}"
|
||||
"{search[q]|search[tags]|search[user]}_{id}")
|
||||
pattern = rf"{BASE_PATTERN}/search\.php\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search\.php\?([^#]+)"
|
||||
example = "https://aryion.com/g4/search.php?q=TEXT&tags=TAGS&user=USER"
|
||||
|
||||
def metadata(self):
|
||||
@@ -313,7 +313,7 @@ class AryionSearchExtractor(AryionExtractor):
|
||||
class AryionPostExtractor(AryionExtractor):
|
||||
"""Extractor for individual posts on eka's portal"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/view/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/view/(\d+)"
|
||||
example = "https://aryion.com/g4/view/12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -80,7 +80,7 @@ class BatotoBase():
|
||||
class BatotoChapterExtractor(BatotoBase, ChapterExtractor):
|
||||
"""Extractor for batoto manga chapters"""
|
||||
archive_fmt = "{chapter_id}_{page}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:title/[^/?#]+|chapter)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?:title/[^/?#]+|chapter)/(\d+)"
|
||||
example = "https://xbato.org/title/12345-MANGA/54321"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -139,8 +139,8 @@ class BatotoMangaExtractor(BatotoBase, MangaExtractor):
|
||||
"""Extractor for batoto manga"""
|
||||
reverse = False
|
||||
chapterclass = BatotoChapterExtractor
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"/(?:title/(\d+)[^/?#]*|series/(\d+)(?:/[^/?#]*)?)/?$")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/(?:title/(\d+)[^/?#]*|series/(\d+)(?:/[^/?#]*)?)/?$")
|
||||
example = "https://xbato.org/title/12345-MANGA/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -21,7 +21,7 @@ class BbcGalleryExtractor(GalleryExtractor):
|
||||
directory_fmt = ("{category}", "{path:I}")
|
||||
filename_fmt = "{num:>02}.{extension}"
|
||||
archive_fmt = "{programme}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}[^/?#]+(?!/galleries)(?:/[^/?#]+)?)$"
|
||||
pattern = BASE_PATTERN + r"[^/?#]+(?!/galleries)(?:/[^/?#]+)?)$"
|
||||
example = "https://www.bbc.co.uk/programmes/PATH"
|
||||
|
||||
def metadata(self, page):
|
||||
@@ -71,7 +71,7 @@ class BbcProgrammeExtractor(Extractor):
|
||||
category = "bbc"
|
||||
subcategory = "programme"
|
||||
root = "https://www.bbc.co.uk"
|
||||
pattern = rf"{BASE_PATTERN}[^/?#]+/galleries)(?:/?\?page=(\d+))?"
|
||||
pattern = BASE_PATTERN + r"[^/?#]+/galleries)(?:/?\?page=(\d+))?"
|
||||
example = "https://www.bbc.co.uk/programmes/ID/galleries"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -117,7 +117,7 @@ BASE_PATTERN = BloggerExtractor.update({
|
||||
class BloggerPostExtractor(BloggerExtractor):
|
||||
"""Extractor for a single blog post"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}(/\d\d\d\d/\d\d/[^/?#]+\.html)"
|
||||
pattern = BASE_PATTERN + r"(/\d\d\d\d/\d\d/[^/?#]+\.html)"
|
||||
example = "https://BLOG.blogspot.com/1970/01/TITLE.html"
|
||||
|
||||
def posts(self, blog):
|
||||
@@ -127,7 +127,7 @@ class BloggerPostExtractor(BloggerExtractor):
|
||||
class BloggerBlogExtractor(BloggerExtractor):
|
||||
"""Extractor for an entire Blogger blog"""
|
||||
subcategory = "blog"
|
||||
pattern = rf"{BASE_PATTERN}/?$"
|
||||
pattern = BASE_PATTERN + r"/?$"
|
||||
example = "https://BLOG.blogspot.com/"
|
||||
|
||||
def posts(self, blog):
|
||||
@@ -137,7 +137,7 @@ class BloggerBlogExtractor(BloggerExtractor):
|
||||
class BloggerSearchExtractor(BloggerExtractor):
|
||||
"""Extractor for Blogger search resuls"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search/?\?q=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/?\?q=([^&#]+)"
|
||||
example = "https://BLOG.blogspot.com/search?q=QUERY"
|
||||
|
||||
def metadata(self):
|
||||
@@ -151,7 +151,7 @@ class BloggerSearchExtractor(BloggerExtractor):
|
||||
class BloggerLabelExtractor(BloggerExtractor):
|
||||
"""Extractor for Blogger posts by label"""
|
||||
subcategory = "label"
|
||||
pattern = rf"{BASE_PATTERN}/search/label/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/label/([^/?#]+)"
|
||||
example = "https://BLOG.blogspot.com/search/label/LABEL"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -14,7 +14,7 @@ from ..cache import cache, memcache
|
||||
|
||||
BASE_PATTERN = (r"(?:https?://)?"
|
||||
r"(?:(?:www\.)?(?:c|[fv]x)?bs[ky]y[ex]?\.app|main\.bsky\.dev)")
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/profile/([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/profile/([^/?#]+)"
|
||||
|
||||
|
||||
class BlueskyExtractor(Extractor):
|
||||
@@ -216,7 +216,7 @@ class BlueskyExtractor(Extractor):
|
||||
|
||||
|
||||
class BlueskyUserExtractor(Dispatch, BlueskyExtractor):
|
||||
pattern = rf"{USER_PATTERN}$"
|
||||
pattern = USER_PATTERN + r"$"
|
||||
example = "https://bsky.app/profile/HANDLE"
|
||||
|
||||
def items(self):
|
||||
@@ -237,7 +237,7 @@ class BlueskyUserExtractor(Dispatch, BlueskyExtractor):
|
||||
|
||||
class BlueskyPostsExtractor(BlueskyExtractor):
|
||||
subcategory = "posts"
|
||||
pattern = rf"{USER_PATTERN}/posts"
|
||||
pattern = USER_PATTERN + r"/posts"
|
||||
example = "https://bsky.app/profile/HANDLE/posts"
|
||||
|
||||
def posts(self):
|
||||
@@ -247,7 +247,7 @@ class BlueskyPostsExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyRepliesExtractor(BlueskyExtractor):
|
||||
subcategory = "replies"
|
||||
pattern = rf"{USER_PATTERN}/replies"
|
||||
pattern = USER_PATTERN + r"/replies"
|
||||
example = "https://bsky.app/profile/HANDLE/replies"
|
||||
|
||||
def posts(self):
|
||||
@@ -257,7 +257,7 @@ class BlueskyRepliesExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyMediaExtractor(BlueskyExtractor):
|
||||
subcategory = "media"
|
||||
pattern = rf"{USER_PATTERN}/media"
|
||||
pattern = USER_PATTERN + r"/media"
|
||||
example = "https://bsky.app/profile/HANDLE/media"
|
||||
|
||||
def posts(self):
|
||||
@@ -267,7 +267,7 @@ class BlueskyMediaExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyVideoExtractor(BlueskyExtractor):
|
||||
subcategory = "video"
|
||||
pattern = rf"{USER_PATTERN}/video"
|
||||
pattern = USER_PATTERN + r"/video"
|
||||
example = "https://bsky.app/profile/HANDLE/video"
|
||||
|
||||
def posts(self):
|
||||
@@ -277,7 +277,7 @@ class BlueskyVideoExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyLikesExtractor(BlueskyExtractor):
|
||||
subcategory = "likes"
|
||||
pattern = rf"{USER_PATTERN}/likes"
|
||||
pattern = USER_PATTERN + r"/likes"
|
||||
example = "https://bsky.app/profile/HANDLE/likes"
|
||||
|
||||
def posts(self):
|
||||
@@ -288,7 +288,7 @@ class BlueskyLikesExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyFeedExtractor(BlueskyExtractor):
|
||||
subcategory = "feed"
|
||||
pattern = rf"{USER_PATTERN}/feed/([^/?#]+)"
|
||||
pattern = USER_PATTERN + r"/feed/([^/?#]+)"
|
||||
example = "https://bsky.app/profile/HANDLE/feed/NAME"
|
||||
|
||||
def posts(self):
|
||||
@@ -298,7 +298,7 @@ class BlueskyFeedExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyListExtractor(BlueskyExtractor):
|
||||
subcategory = "list"
|
||||
pattern = rf"{USER_PATTERN}/lists/([^/?#]+)"
|
||||
pattern = USER_PATTERN + r"/lists/([^/?#]+)"
|
||||
example = "https://bsky.app/profile/HANDLE/lists/ID"
|
||||
|
||||
def posts(self):
|
||||
@@ -308,7 +308,7 @@ class BlueskyListExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyFollowingExtractor(BlueskyExtractor):
|
||||
subcategory = "following"
|
||||
pattern = rf"{USER_PATTERN}/follows"
|
||||
pattern = USER_PATTERN + r"/follows"
|
||||
example = "https://bsky.app/profile/HANDLE/follows"
|
||||
|
||||
def items(self):
|
||||
@@ -320,7 +320,7 @@ class BlueskyFollowingExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyPostExtractor(BlueskyExtractor):
|
||||
subcategory = "post"
|
||||
pattern = rf"{USER_PATTERN}/post/([^/?#]+)"
|
||||
pattern = USER_PATTERN + r"/post/([^/?#]+)"
|
||||
example = "https://bsky.app/profile/HANDLE/post/ID"
|
||||
|
||||
def posts(self):
|
||||
@@ -330,7 +330,7 @@ class BlueskyPostExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyInfoExtractor(BlueskyExtractor):
|
||||
subcategory = "info"
|
||||
pattern = rf"{USER_PATTERN}/info"
|
||||
pattern = USER_PATTERN + r"/info"
|
||||
example = "https://bsky.app/profile/HANDLE/info"
|
||||
|
||||
def items(self):
|
||||
@@ -342,7 +342,7 @@ class BlueskyInfoExtractor(BlueskyExtractor):
|
||||
class BlueskyAvatarExtractor(BlueskyExtractor):
|
||||
subcategory = "avatar"
|
||||
filename_fmt = "avatar_{post_id}.{extension}"
|
||||
pattern = rf"{USER_PATTERN}/avatar"
|
||||
pattern = USER_PATTERN + r"/avatar"
|
||||
example = "https://bsky.app/profile/HANDLE/avatar"
|
||||
|
||||
def posts(self):
|
||||
@@ -352,7 +352,7 @@ class BlueskyAvatarExtractor(BlueskyExtractor):
|
||||
class BlueskyBackgroundExtractor(BlueskyExtractor):
|
||||
subcategory = "background"
|
||||
filename_fmt = "background_{post_id}.{extension}"
|
||||
pattern = rf"{USER_PATTERN}/ba(?:nner|ckground)"
|
||||
pattern = USER_PATTERN + r"/ba(?:nner|ckground)"
|
||||
example = "https://bsky.app/profile/HANDLE/banner"
|
||||
|
||||
def posts(self):
|
||||
@@ -361,7 +361,7 @@ class BlueskyBackgroundExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskySearchExtractor(BlueskyExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search(?:/|\?q=)(.+)"
|
||||
pattern = BASE_PATTERN + r"/search(?:/|\?q=)(.+)"
|
||||
example = "https://bsky.app/search?q=QUERY"
|
||||
|
||||
def posts(self):
|
||||
@@ -371,7 +371,7 @@ class BlueskySearchExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyHashtagExtractor(BlueskyExtractor):
|
||||
subcategory = "hashtag"
|
||||
pattern = rf"{BASE_PATTERN}/hashtag/([^/?#]+)(?:/(top|latest))?"
|
||||
pattern = BASE_PATTERN + r"/hashtag/([^/?#]+)(?:/(top|latest))?"
|
||||
example = "https://bsky.app/hashtag/NAME"
|
||||
|
||||
def posts(self):
|
||||
@@ -381,7 +381,7 @@ class BlueskyHashtagExtractor(BlueskyExtractor):
|
||||
|
||||
class BlueskyBookmarkExtractor(BlueskyExtractor):
|
||||
subcategory = "bookmark"
|
||||
pattern = rf"{BASE_PATTERN}/saved"
|
||||
pattern = BASE_PATTERN + r"/saved"
|
||||
example = "https://bsky.app/saved"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -163,7 +163,7 @@ class BoostyExtractor(Extractor):
|
||||
class BoostyUserExtractor(BoostyExtractor):
|
||||
"""Extractor for boosty.to user profiles"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)(?:\?([^#]+))?$"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)(?:\?([^#]+))?$"
|
||||
example = "https://boosty.to/USER"
|
||||
|
||||
def posts(self):
|
||||
@@ -179,7 +179,7 @@ class BoostyMediaExtractor(BoostyExtractor):
|
||||
subcategory = "media"
|
||||
directory_fmt = "{category}", "{user[blogUrl]} ({user[id]})", "media"
|
||||
filename_fmt = "{post[id]}_{num}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/media/([^/?#]+)(?:\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/media/([^/?#]+)(?:\?([^#]+))?"
|
||||
example = "https://boosty.to/USER/media/all"
|
||||
|
||||
def posts(self):
|
||||
@@ -192,7 +192,7 @@ class BoostyMediaExtractor(BoostyExtractor):
|
||||
class BoostyFeedExtractor(BoostyExtractor):
|
||||
"""Extractor for your boosty.to subscription feed"""
|
||||
subcategory = "feed"
|
||||
pattern = rf"{BASE_PATTERN}/(?:\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/(?:\?([^#]+))?(?:$|#)"
|
||||
example = "https://boosty.to/"
|
||||
|
||||
def posts(self):
|
||||
@@ -203,7 +203,7 @@ class BoostyFeedExtractor(BoostyExtractor):
|
||||
class BoostyPostExtractor(BoostyExtractor):
|
||||
"""Extractor for boosty.to posts"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/posts/([0-9a-f-]+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/posts/([0-9a-f-]+)"
|
||||
example = "https://boosty.to/USER/posts/01234567-89ab-cdef-0123-456789abcd"
|
||||
|
||||
def posts(self):
|
||||
@@ -216,7 +216,7 @@ class BoostyPostExtractor(BoostyExtractor):
|
||||
class BoostyFollowingExtractor(BoostyExtractor):
|
||||
"""Extractor for your boosty.to subscribed users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/app/settings/subscriptions"
|
||||
pattern = BASE_PATTERN + r"/app/settings/subscriptions"
|
||||
example = "https://boosty.to/app/settings/subscriptions"
|
||||
|
||||
def items(self):
|
||||
@@ -231,7 +231,7 @@ class BoostyDirectMessagesExtractor(BoostyExtractor):
|
||||
subcategory = "direct-messages"
|
||||
directory_fmt = ("{category}", "{user[blogUrl]} ({user[id]})",
|
||||
"Direct Messages")
|
||||
pattern = rf"{BASE_PATTERN}/app/messages/?\?dialogId=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/app/messages/?\?dialogId=(\d+)"
|
||||
example = "https://boosty.to/app/messages?dialogId=12345"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -64,7 +64,7 @@ class BunkrAlbumExtractor(LolisafeAlbumExtractor):
|
||||
root_dl = "https://get.bunkrr.su"
|
||||
root_api = "https://apidl.bunkr.ru"
|
||||
archive_fmt = "{album_id}_{id|id_url|slug}"
|
||||
pattern = rf"{BASE_PATTERN}/a/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/a/([^/?#]+)"
|
||||
example = "https://bunkr.si/a/ID"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -216,7 +216,7 @@ class BunkrMediaExtractor(BunkrAlbumExtractor):
|
||||
"""Extractor for bunkr.si media links"""
|
||||
subcategory = "media"
|
||||
directory_fmt = ("{category}",)
|
||||
pattern = rf"{BASE_PATTERN}(/[fvid]/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/[fvid]/[^/?#]+)"
|
||||
example = "https://bunkr.si/f/FILENAME"
|
||||
|
||||
def fetch_album(self, album_id):
|
||||
|
||||
@@ -60,7 +60,7 @@ BASE_PATTERN = CheveretoExtractor.update({
|
||||
class CheveretoImageExtractor(CheveretoExtractor):
|
||||
"""Extractor for chevereto images"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}(/im(?:g|age)/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/im(?:g|age)/[^/?#]+)"
|
||||
example = "https://jpg7.cr/img/TITLE.ID"
|
||||
|
||||
def items(self):
|
||||
@@ -98,7 +98,7 @@ class CheveretoImageExtractor(CheveretoExtractor):
|
||||
class CheveretoVideoExtractor(CheveretoExtractor):
|
||||
"""Extractor for chevereto videos"""
|
||||
subcategory = "video"
|
||||
pattern = rf"{BASE_PATTERN}(/video/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/video/[^/?#]+)"
|
||||
example = "https://imagepond.net/video/TITLE.ID"
|
||||
|
||||
def items(self):
|
||||
@@ -145,7 +145,7 @@ class CheveretoVideoExtractor(CheveretoExtractor):
|
||||
class CheveretoAlbumExtractor(CheveretoExtractor):
|
||||
"""Extractor for chevereto albums"""
|
||||
subcategory = "album"
|
||||
pattern = rf"{BASE_PATTERN}(/a(?:lbum)?/[^/?#]+(?:/sub)?)"
|
||||
pattern = BASE_PATTERN + r"(/a(?:lbum)?/[^/?#]+(?:/sub)?)"
|
||||
example = "https://jpg7.cr/album/TITLE.ID"
|
||||
|
||||
def items(self):
|
||||
@@ -182,7 +182,7 @@ class CheveretoAlbumExtractor(CheveretoExtractor):
|
||||
class CheveretoCategoryExtractor(CheveretoExtractor):
|
||||
"""Extractor for chevereto galleries"""
|
||||
subcategory = "category"
|
||||
pattern = rf"{BASE_PATTERN}(/category/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/category/[^/?#]+)"
|
||||
example = "https://imglike.com/category/TITLE"
|
||||
|
||||
def items(self):
|
||||
@@ -194,7 +194,7 @@ class CheveretoCategoryExtractor(CheveretoExtractor):
|
||||
class CheveretoUserExtractor(CheveretoExtractor):
|
||||
"""Extractor for chevereto users"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}(/[^/?#]+(?:/albums)?)"
|
||||
pattern = BASE_PATTERN + r"(/[^/?#]+(?:/albums)?)"
|
||||
example = "https://jpg7.cr/USER"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -48,7 +48,7 @@ class CienArticleExtractor(CienExtractor):
|
||||
filename_fmt = "{num:>02} {filename}.{extension}"
|
||||
directory_fmt = ("{category}", "{author[name]}", "{post_id} {name}")
|
||||
archive_fmt = "{post_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/creator/(\d+)/article/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/creator/(\d+)/article/(\d+)"
|
||||
example = "https://ci-en.net/creator/123/article/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -160,7 +160,7 @@ class CienArticleExtractor(CienExtractor):
|
||||
|
||||
class CienCreatorExtractor(CienExtractor):
|
||||
subcategory = "creator"
|
||||
pattern = rf"{BASE_PATTERN}/creator/(\d+)(?:/article(?:\?([^#]+))?)?/?$"
|
||||
pattern = BASE_PATTERN + r"/creator/(\d+)(?:/article(?:\?([^#]+))?)?/?$"
|
||||
example = "https://ci-en.net/creator/123"
|
||||
|
||||
def items(self):
|
||||
@@ -172,7 +172,7 @@ class CienCreatorExtractor(CienExtractor):
|
||||
|
||||
class CienRecentExtractor(CienExtractor):
|
||||
subcategory = "recent"
|
||||
pattern = rf"{BASE_PATTERN}/mypage/recent(?:\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/mypage/recent(?:\?([^#]+))?"
|
||||
example = "https://ci-en.net/mypage/recent"
|
||||
|
||||
def items(self):
|
||||
@@ -183,7 +183,7 @@ class CienRecentExtractor(CienExtractor):
|
||||
|
||||
class CienFollowingExtractor(CienExtractor):
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/mypage/subscription(/following)?"
|
||||
pattern = BASE_PATTERN + r"/mypage/subscription(/following)?"
|
||||
example = "https://ci-en.net/mypage/subscription"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -15,7 +15,7 @@ import itertools
|
||||
import time
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?civitai\.com"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/user/([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/user/([^/?#]+)"
|
||||
|
||||
|
||||
class CivitaiExtractor(Extractor):
|
||||
@@ -258,7 +258,7 @@ class CivitaiModelExtractor(CivitaiExtractor):
|
||||
directory_fmt = ("{category}", "{user[username]}",
|
||||
"{model[id]}{model[name]:? //}",
|
||||
"{version[id]}{version[name]:? //}")
|
||||
pattern = rf"{BASE_PATTERN}/models/(\d+)(?:/?\?modelVersionId=(\d+))?"
|
||||
pattern = BASE_PATTERN + r"/models/(\d+)(?:/?\?modelVersionId=(\d+))?"
|
||||
example = "https://civitai.com/models/12345/TITLE"
|
||||
|
||||
def items(self):
|
||||
@@ -375,7 +375,7 @@ class CivitaiModelExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiImageExtractor(CivitaiExtractor):
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/images/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/images/(\d+)"
|
||||
example = "https://civitai.com/images/12345"
|
||||
|
||||
def images(self):
|
||||
@@ -386,7 +386,7 @@ class CivitaiCollectionExtractor(CivitaiExtractor):
|
||||
subcategory = "collection"
|
||||
directory_fmt = ("{category}", "{user_collection[username]}",
|
||||
"collections", "{collection[id]}{collection[name]:? //}")
|
||||
pattern = rf"{BASE_PATTERN}/collections/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/collections/(\d+)"
|
||||
example = "https://civitai.com/collections/12345"
|
||||
|
||||
def images(self):
|
||||
@@ -408,7 +408,7 @@ class CivitaiPostExtractor(CivitaiExtractor):
|
||||
subcategory = "post"
|
||||
directory_fmt = ("{category}", "{username|user[username]}", "posts",
|
||||
"{post[id]}{post[title]:? //}")
|
||||
pattern = rf"{BASE_PATTERN}/posts/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/posts/(\d+)"
|
||||
example = "https://civitai.com/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -417,7 +417,7 @@ class CivitaiPostExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiTagExtractor(CivitaiExtractor):
|
||||
subcategory = "tag"
|
||||
pattern = rf"{BASE_PATTERN}/tag/([^/?&#]+)"
|
||||
pattern = BASE_PATTERN + r"/tag/([^/?&#]+)"
|
||||
example = "https://civitai.com/tag/TAG"
|
||||
|
||||
def models(self):
|
||||
@@ -427,7 +427,7 @@ class CivitaiTagExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiSearchModelsExtractor(CivitaiExtractor):
|
||||
subcategory = "search-models"
|
||||
pattern = rf"{BASE_PATTERN}/search/models\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/models\?([^#]+)"
|
||||
example = "https://civitai.com/search/models?query=QUERY"
|
||||
|
||||
def models(self):
|
||||
@@ -438,7 +438,7 @@ class CivitaiSearchModelsExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiSearchImagesExtractor(CivitaiExtractor):
|
||||
subcategory = "search-images"
|
||||
pattern = rf"{BASE_PATTERN}/search/images\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/images\?([^#]+)"
|
||||
example = "https://civitai.com/search/images?query=QUERY"
|
||||
|
||||
def images(self):
|
||||
@@ -449,7 +449,7 @@ class CivitaiSearchImagesExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiModelsExtractor(CivitaiExtractor):
|
||||
subcategory = "models"
|
||||
pattern = rf"{BASE_PATTERN}/models(?:/?\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/models(?:/?\?([^#]+))?(?:$|#)"
|
||||
example = "https://civitai.com/models"
|
||||
|
||||
def models(self):
|
||||
@@ -459,7 +459,7 @@ class CivitaiModelsExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiImagesExtractor(CivitaiExtractor):
|
||||
subcategory = "images"
|
||||
pattern = rf"{BASE_PATTERN}/images(?:/?\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/images(?:/?\?([^#]+))?(?:$|#)"
|
||||
example = "https://civitai.com/images"
|
||||
|
||||
def images(self):
|
||||
@@ -470,7 +470,7 @@ class CivitaiImagesExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiVideosExtractor(CivitaiExtractor):
|
||||
subcategory = "videos"
|
||||
pattern = rf"{BASE_PATTERN}/videos(?:/?\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/videos(?:/?\?([^#]+))?(?:$|#)"
|
||||
example = "https://civitai.com/videos"
|
||||
|
||||
def images(self):
|
||||
@@ -481,7 +481,7 @@ class CivitaiVideosExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiPostsExtractor(CivitaiExtractor):
|
||||
subcategory = "posts"
|
||||
pattern = rf"{BASE_PATTERN}/posts(?:/?\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/posts(?:/?\?([^#]+))?(?:$|#)"
|
||||
example = "https://civitai.com/posts"
|
||||
|
||||
def posts(self):
|
||||
@@ -490,7 +490,7 @@ class CivitaiPostsExtractor(CivitaiExtractor):
|
||||
|
||||
|
||||
class CivitaiUserExtractor(Dispatch, CivitaiExtractor):
|
||||
pattern = rf"{USER_PATTERN}/?(?:$|\?|#)"
|
||||
pattern = USER_PATTERN + r"/?(?:$|\?|#)"
|
||||
example = "https://civitai.com/user/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -506,7 +506,7 @@ class CivitaiUserExtractor(Dispatch, CivitaiExtractor):
|
||||
|
||||
class CivitaiUserModelsExtractor(CivitaiExtractor):
|
||||
subcategory = "user-models"
|
||||
pattern = rf"{USER_PATTERN}/models/?(?:\?([^#]+))?"
|
||||
pattern = USER_PATTERN + r"/models/?(?:\?([^#]+))?"
|
||||
example = "https://civitai.com/user/USER/models"
|
||||
|
||||
def models(self):
|
||||
@@ -520,7 +520,7 @@ class CivitaiUserPostsExtractor(CivitaiExtractor):
|
||||
subcategory = "user-posts"
|
||||
directory_fmt = ("{category}", "{username|user[username]}", "posts",
|
||||
"{post[id]}{post[title]:? //}")
|
||||
pattern = rf"{USER_PATTERN}/posts/?(?:\?([^#]+))?"
|
||||
pattern = USER_PATTERN + r"/posts/?(?:\?([^#]+))?"
|
||||
example = "https://civitai.com/user/USER/posts"
|
||||
|
||||
def posts(self):
|
||||
@@ -532,7 +532,7 @@ class CivitaiUserPostsExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiUserImagesExtractor(CivitaiExtractor):
|
||||
subcategory = "user-images"
|
||||
pattern = rf"{USER_PATTERN}/images/?(?:\?([^#]+))?"
|
||||
pattern = USER_PATTERN + r"/images/?(?:\?([^#]+))?"
|
||||
example = "https://civitai.com/user/USER/images"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -553,7 +553,7 @@ class CivitaiUserImagesExtractor(CivitaiExtractor):
|
||||
class CivitaiUserVideosExtractor(CivitaiExtractor):
|
||||
subcategory = "user-videos"
|
||||
directory_fmt = ("{category}", "{username|user[username]}", "videos")
|
||||
pattern = rf"{USER_PATTERN}/videos/?(?:\?([^#]+))?"
|
||||
pattern = USER_PATTERN + r"/videos/?(?:\?([^#]+))?"
|
||||
example = "https://civitai.com/user/USER/videos"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -572,7 +572,7 @@ class CivitaiUserVideosExtractor(CivitaiExtractor):
|
||||
|
||||
class CivitaiUserCollectionsExtractor(CivitaiExtractor):
|
||||
subcategory = "user-collections"
|
||||
pattern = rf"{USER_PATTERN}/collections/?(?:\?([^#]+))?"
|
||||
pattern = USER_PATTERN + r"/collections/?(?:\?([^#]+))?"
|
||||
example = "https://civitai.com/user/USER/collections"
|
||||
|
||||
def items(self):
|
||||
@@ -591,7 +591,7 @@ class CivitaiGeneratedExtractor(CivitaiExtractor):
|
||||
subcategory = "generated"
|
||||
filename_fmt = "{filename}.{extension}"
|
||||
directory_fmt = ("{category}", "generated")
|
||||
pattern = rf"{BASE_PATTERN}/generate"
|
||||
pattern = f"{BASE_PATTERN}/generate"
|
||||
example = "https://civitai.com/generate"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -27,7 +27,7 @@ class ComickCoversExtractor(ComickBase, GalleryExtractor):
|
||||
directory_fmt = ("{category}", "{manga}", "Covers")
|
||||
filename_fmt = "{volume:>02}_{lang}.{extension}"
|
||||
archive_fmt = "c_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/comic/([\w-]+)/cover"
|
||||
pattern = BASE_PATTERN + r"/comic/([\w-]+)/cover"
|
||||
example = "https://comick.io/comic/MANGA/cover"
|
||||
|
||||
def metadata(self, page):
|
||||
@@ -60,7 +60,7 @@ class ComickCoversExtractor(ComickBase, GalleryExtractor):
|
||||
class ComickChapterExtractor(ComickBase, ChapterExtractor):
|
||||
"""Extractor for comick.io manga chapters"""
|
||||
archive_fmt = "{chapter_hid}_{page}"
|
||||
pattern = (rf"{BASE_PATTERN}/comic/([\w-]+)"
|
||||
pattern = (BASE_PATTERN + r"/comic/([\w-]+)"
|
||||
r"/(\w+(?:-(?:chapter|volume)-[^/?#]+)?)")
|
||||
example = "https://comick.io/comic/MANGA/ID-chapter-123-en"
|
||||
|
||||
@@ -140,7 +140,7 @@ class ComickChapterExtractor(ComickBase, ChapterExtractor):
|
||||
|
||||
class ComickMangaExtractor(ComickBase, MangaExtractor):
|
||||
"""Extractor for comick.io manga"""
|
||||
pattern = rf"{BASE_PATTERN}/comic/([\w-]+)/?(?:\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/comic/([\w-]+)/?(?:\?([^#]+))?"
|
||||
example = "https://comick.io/comic/MANGA"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -18,7 +18,7 @@ class CyberdropAlbumExtractor(lolisafe.LolisafeAlbumExtractor):
|
||||
category = "cyberdrop"
|
||||
root = "https://cyberdrop.cr"
|
||||
root_api = "https://api.cyberdrop.cr"
|
||||
pattern = rf"{BASE_PATTERN}/a/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/a/([^/?#]+)"
|
||||
example = "https://cyberdrop.cr/a/ID"
|
||||
|
||||
def items(self):
|
||||
@@ -76,7 +76,7 @@ class CyberdropMediaExtractor(CyberdropAlbumExtractor):
|
||||
"""Extractor for cyberdrop media links"""
|
||||
subcategory = "media"
|
||||
directory_fmt = ("{category}",)
|
||||
pattern = rf"{BASE_PATTERN}/f/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/f/([^/?#]+)"
|
||||
example = "https://cyberdrop.cr/f/ID"
|
||||
|
||||
def fetch_album(self, album_id):
|
||||
|
||||
@@ -251,7 +251,7 @@ class DanbooruTagExtractor(DanbooruExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/posts\?(?:[^&#]*&)*tags=([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"/posts\?(?:[^&#]*&)*tags=([^&#]*)"
|
||||
example = "https://danbooru.donmai.us/posts?tags=TAG"
|
||||
|
||||
def metadata(self):
|
||||
@@ -279,7 +279,7 @@ class DanbooruTagExtractor(DanbooruExtractor):
|
||||
class DanbooruRandomExtractor(DanbooruTagExtractor):
|
||||
"""Extractor for a random danbooru post"""
|
||||
subcategory = "random"
|
||||
pattern = rf"{BASE_PATTERN}/posts/random(?:\?(?:[^&#]*&)*tags=([^&#]*))?"
|
||||
pattern = BASE_PATTERN + r"/posts/random(?:\?(?:[^&#]*&)*tags=([^&#]*))?"
|
||||
example = "https://danbooru.donmai.us/posts/random?tags=TAG"
|
||||
|
||||
def metadata(self):
|
||||
@@ -299,7 +299,7 @@ class DanbooruPoolExtractor(DanbooruExtractor):
|
||||
directory_fmt = ("{category}", "pool", "{pool[id]} {pool[name]}")
|
||||
filename_fmt = "{num:>04}_{id}_{filename}.{extension}"
|
||||
archive_fmt = "p_{pool[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/pool(?:s|/show)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/pool(?:s|/show)/(\d+)"
|
||||
example = "https://danbooru.donmai.us/pools/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -317,7 +317,7 @@ class DanbooruFavgroupExtractor(DanbooruExtractor):
|
||||
"{favgroup[id]} {favgroup[name]}")
|
||||
filename_fmt = "{num:>04}_{id}_{filename}.{extension}"
|
||||
archive_fmt = "fg_{favgroup[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/favorite_group(?:s|/show)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/favorite_group(?:s|/show)/(\d+)"
|
||||
example = "https://danbooru.donmai.us/favorite_groups/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -332,7 +332,7 @@ class DanbooruPostExtractor(DanbooruExtractor):
|
||||
"""Extractor for single danbooru posts"""
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post(?:s|/show)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post(?:s|/show)/(\d+)"
|
||||
example = "https://danbooru.donmai.us/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -375,7 +375,7 @@ class DanbooruPopularExtractor(DanbooruExtractor):
|
||||
subcategory = "popular"
|
||||
directory_fmt = ("{category}", "popular", "{scale}", "{date}")
|
||||
archive_fmt = "P_{scale[0]}_{date}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:explore/posts/)?popular(?:\?([^#]*))?"
|
||||
pattern = BASE_PATTERN + r"/(?:explore/posts/)?popular(?:\?([^#]*))?"
|
||||
example = "https://danbooru.donmai.us/explore/posts/popular"
|
||||
|
||||
def metadata(self):
|
||||
@@ -398,7 +398,7 @@ class DanbooruPopularExtractor(DanbooruExtractor):
|
||||
class DanbooruArtistExtractor(DanbooruExtractor):
|
||||
"""Extractor for danbooru artists"""
|
||||
subcategory = "artist"
|
||||
pattern = rf"{BASE_PATTERN}/artists/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/artists/(\d+)"
|
||||
example = "https://danbooru.donmai.us/artists/12345"
|
||||
|
||||
items = DanbooruExtractor.items_artists
|
||||
@@ -411,7 +411,7 @@ class DanbooruArtistExtractor(DanbooruExtractor):
|
||||
class DanbooruArtistSearchExtractor(DanbooruExtractor):
|
||||
"""Extractor for danbooru artist searches"""
|
||||
subcategory = "artist-search"
|
||||
pattern = rf"{BASE_PATTERN}/artists/?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/artists/?\?([^#]+)"
|
||||
example = "https://danbooru.donmai.us/artists?QUERY"
|
||||
|
||||
items = DanbooruExtractor.items_artists
|
||||
|
||||
@@ -28,7 +28,7 @@ class DankefuerslesenBase():
|
||||
|
||||
class DankefuerslesenChapterExtractor(DankefuerslesenBase, ChapterExtractor):
|
||||
"""Extractor for Danke fürs Lesen manga chapters"""
|
||||
pattern = rf"{BASE_PATTERN}/read/manga/([\w-]+)/([\w-]+)"
|
||||
pattern = BASE_PATTERN + r"/read/manga/([\w-]+)/([\w-]+)"
|
||||
example = "https://danke.moe/read/manga/TITLE/123/1/"
|
||||
|
||||
def _init(self):
|
||||
@@ -95,7 +95,7 @@ class DankefuerslesenMangaExtractor(DankefuerslesenBase, MangaExtractor):
|
||||
"""Extractor for Danke fürs Lesen manga"""
|
||||
chapterclass = DankefuerslesenChapterExtractor
|
||||
reverse = False
|
||||
pattern = rf"{BASE_PATTERN}/read/manga/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/read/manga/([^/?#]+)"
|
||||
example = "https://danke.moe/read/manga/TITLE/"
|
||||
|
||||
def chapters(self, page):
|
||||
|
||||
@@ -22,7 +22,7 @@ class DesktopographyExtractor(Extractor):
|
||||
class DesktopographySiteExtractor(DesktopographyExtractor):
|
||||
"""Extractor for all desktopography exhibitions """
|
||||
subcategory = "site"
|
||||
pattern = rf"{BASE_PATTERN}/$"
|
||||
pattern = BASE_PATTERN + r"/$"
|
||||
example = "https://desktopography.net/"
|
||||
|
||||
def items(self):
|
||||
@@ -41,7 +41,7 @@ class DesktopographySiteExtractor(DesktopographyExtractor):
|
||||
class DesktopographyExhibitionExtractor(DesktopographyExtractor):
|
||||
"""Extractor for a yearly desktopography exhibition"""
|
||||
subcategory = "exhibition"
|
||||
pattern = rf"{BASE_PATTERN}/exhibition-([^/?#]+)/"
|
||||
pattern = BASE_PATTERN + r"/exhibition-([^/?#]+)/"
|
||||
example = "https://desktopography.net/exhibition-2020/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -70,7 +70,7 @@ class DesktopographyExhibitionExtractor(DesktopographyExtractor):
|
||||
class DesktopographyEntryExtractor(DesktopographyExtractor):
|
||||
"""Extractor for all resolutions of a desktopography wallpaper"""
|
||||
subcategory = "entry"
|
||||
pattern = rf"{BASE_PATTERN}/portfolios/([\w-]+)"
|
||||
pattern = BASE_PATTERN + r"/portfolios/([\w-]+)"
|
||||
example = "https://desktopography.net/portfolios/NAME/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -864,7 +864,7 @@ x2="45.4107524%" y2="71.4898596%" id="app-root-3">\
|
||||
|
||||
class DeviantartUserExtractor(Dispatch, DeviantartExtractor):
|
||||
"""Extractor for an artist's user profile"""
|
||||
pattern = rf"{BASE_PATTERN}/?$"
|
||||
pattern = BASE_PATTERN + r"/?$"
|
||||
example = "https://www.deviantart.com/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -887,7 +887,7 @@ class DeviantartGalleryExtractor(DeviantartExtractor):
|
||||
"""Extractor for all deviations from an artist's gallery"""
|
||||
subcategory = "gallery"
|
||||
archive_fmt = "g_{_username}_{index}.{extension}"
|
||||
pattern = (rf"{BASE_PATTERN}/gallery"
|
||||
pattern = (BASE_PATTERN + r"/gallery"
|
||||
r"(?:/all|/recommended-for-you)?/?(\?(?!q=).*)?$")
|
||||
example = "https://www.deviantart.com/USER/gallery/"
|
||||
|
||||
@@ -902,7 +902,7 @@ class DeviantartAvatarExtractor(DeviantartExtractor):
|
||||
"""Extractor for an artist's avatar"""
|
||||
subcategory = "avatar"
|
||||
archive_fmt = "a_{_username}_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/avatar"
|
||||
pattern = BASE_PATTERN + r"/avatar"
|
||||
example = "https://www.deviantart.com/USER/avatar/"
|
||||
|
||||
def deviations(self):
|
||||
@@ -956,7 +956,7 @@ class DeviantartBackgroundExtractor(DeviantartExtractor):
|
||||
"""Extractor for an artist's banner"""
|
||||
subcategory = "background"
|
||||
archive_fmt = "b_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/ba(?:nner|ckground)"
|
||||
pattern = BASE_PATTERN + r"/ba(?:nner|ckground)"
|
||||
example = "https://www.deviantart.com/USER/banner/"
|
||||
|
||||
def deviations(self):
|
||||
@@ -972,7 +972,7 @@ class DeviantartFolderExtractor(DeviantartExtractor):
|
||||
subcategory = "folder"
|
||||
directory_fmt = ("{category}", "{username}", "{folder[title]}")
|
||||
archive_fmt = "F_{folder[uuid]}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/([^/?#]+)/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/gallery/([^/?#]+)/([^/?#]+)"
|
||||
example = "https://www.deviantart.com/USER/gallery/12345/TITLE"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -1088,7 +1088,7 @@ class DeviantartFavoriteExtractor(DeviantartExtractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{username}", "Favourites")
|
||||
archive_fmt = "f_{_username}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/favourites(?:/all|/?\?catpath=)?/?$"
|
||||
pattern = BASE_PATTERN + r"/favourites(?:/all|/?\?catpath=)?/?$"
|
||||
example = "https://www.deviantart.com/USER/favourites/"
|
||||
|
||||
def deviations(self):
|
||||
@@ -1105,7 +1105,7 @@ class DeviantartCollectionExtractor(DeviantartExtractor):
|
||||
directory_fmt = ("{category}", "{username}", "Favourites",
|
||||
"{collection[title]}")
|
||||
archive_fmt = "C_{collection[uuid]}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/favourites/([^/?#]+)/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/favourites/([^/?#]+)/([^/?#]+)"
|
||||
example = "https://www.deviantart.com/USER/favourites/12345/TITLE"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -1136,7 +1136,7 @@ class DeviantartJournalExtractor(DeviantartExtractor):
|
||||
subcategory = "journal"
|
||||
directory_fmt = ("{category}", "{username}", "Journal")
|
||||
archive_fmt = "j_{_username}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:posts(?:/journals)?|journal)/?(?:\?.*)?$"
|
||||
pattern = BASE_PATTERN + r"/(?:posts(?:/journals)?|journal)/?(?:\?.*)?$"
|
||||
example = "https://www.deviantart.com/USER/posts/journals/"
|
||||
|
||||
def deviations(self):
|
||||
@@ -1149,7 +1149,7 @@ class DeviantartStatusExtractor(DeviantartExtractor):
|
||||
directory_fmt = ("{category}", "{username}", "Status")
|
||||
filename_fmt = "{category}_{index}_{title}_{date}.{extension}"
|
||||
archive_fmt = "S_{_username}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/posts/statuses"
|
||||
pattern = BASE_PATTERN + r"/posts/statuses"
|
||||
example = "https://www.deviantart.com/USER/posts/statuses/"
|
||||
|
||||
def deviations(self):
|
||||
@@ -1253,7 +1253,7 @@ class DeviantartDeviationExtractor(DeviantartExtractor):
|
||||
"""Extractor for single deviations"""
|
||||
subcategory = "deviation"
|
||||
archive_fmt = "g_{_username}_{index}.{extension}"
|
||||
pattern = (rf"{BASE_PATTERN}/(art|journal)/(?:[^/?#]+-)?(\d+)"
|
||||
pattern = (BASE_PATTERN + r"/(art|journal)/(?:[^/?#]+-)?(\d+)"
|
||||
r"|(?:https?://)?(?:www\.)?(?:fx)?deviantart\.com/"
|
||||
r"(?:view/|deviation/|view(?:-full)?\.php/*\?(?:[^#]+&)?id=)"
|
||||
r"(\d+)" # bare deviation ID without slug
|
||||
@@ -1315,7 +1315,7 @@ class DeviantartScrapsExtractor(DeviantartExtractor):
|
||||
subcategory = "scraps"
|
||||
directory_fmt = ("{category}", "{username}", "Scraps")
|
||||
archive_fmt = "s_{_username}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/(?:\?catpath=)?scraps\b"
|
||||
pattern = BASE_PATTERN + r"/gallery/(?:\?catpath=)?scraps\b"
|
||||
example = "https://www.deviantart.com/USER/gallery/scraps"
|
||||
|
||||
def deviations(self):
|
||||
@@ -1382,7 +1382,7 @@ class DeviantartGallerySearchExtractor(DeviantartExtractor):
|
||||
"""Extractor for deviantart gallery searches"""
|
||||
subcategory = "gallery-search"
|
||||
archive_fmt = "g_{_username}_{index}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/?\?(q=[^#]+)"
|
||||
pattern = BASE_PATTERN + r"/gallery/?\?(q=[^#]+)"
|
||||
example = "https://www.deviantart.com/USER/gallery?q=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -1412,7 +1412,7 @@ class DeviantartGallerySearchExtractor(DeviantartExtractor):
|
||||
class DeviantartFollowingExtractor(DeviantartExtractor):
|
||||
"""Extractor for user's watched users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/(?:about#)?watching"
|
||||
pattern = BASE_PATTERN + "/(?:about#)?watching"
|
||||
example = "https://www.deviantart.com/USER/about#watching"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -238,7 +238,7 @@ class DiscordExtractor(Extractor):
|
||||
|
||||
class DiscordChannelExtractor(DiscordExtractor):
|
||||
subcategory = "channel"
|
||||
pattern = rf"{BASE_PATTERN}/channels/(\d+)/(?:\d+/threads/)?(\d+)/?$"
|
||||
pattern = BASE_PATTERN + r"/channels/(\d+)/(?:\d+/threads/)?(\d+)/?$"
|
||||
example = "https://discord.com/channels/1234567890/9876543210"
|
||||
|
||||
def items(self):
|
||||
@@ -251,7 +251,7 @@ class DiscordChannelExtractor(DiscordExtractor):
|
||||
|
||||
class DiscordMessageExtractor(DiscordExtractor):
|
||||
subcategory = "message"
|
||||
pattern = rf"{BASE_PATTERN}/channels/(\d+)/(\d+)/(\d+)/?$"
|
||||
pattern = BASE_PATTERN + r"/channels/(\d+)/(\d+)/(\d+)/?$"
|
||||
example = "https://discord.com/channels/1234567890/9876543210/2468013579"
|
||||
|
||||
def items(self):
|
||||
@@ -268,7 +268,7 @@ class DiscordMessageExtractor(DiscordExtractor):
|
||||
|
||||
class DiscordServerExtractor(DiscordExtractor):
|
||||
subcategory = "server"
|
||||
pattern = rf"{BASE_PATTERN}/channels/(\d+)/?$"
|
||||
pattern = BASE_PATTERN + r"/channels/(\d+)/?$"
|
||||
example = "https://discord.com/channels/1234567890"
|
||||
|
||||
def items(self):
|
||||
@@ -286,7 +286,7 @@ class DiscordDirectMessagesExtractor(DiscordExtractor):
|
||||
subcategory = "direct-messages"
|
||||
directory_fmt = ("{category}", "Direct Messages",
|
||||
"{channel_id}_{recipients:J,}")
|
||||
pattern = rf"{BASE_PATTERN}/channels/@me/(\d+)/?$"
|
||||
pattern = BASE_PATTERN + r"/channels/@me/(\d+)/?$"
|
||||
example = "https://discord.com/channels/@me/1234567890"
|
||||
|
||||
def items(self):
|
||||
@@ -297,7 +297,7 @@ class DiscordDirectMessageExtractor(DiscordExtractor):
|
||||
subcategory = "direct-message"
|
||||
directory_fmt = ("{category}", "Direct Messages",
|
||||
"{channel_id}_{recipients:J,}")
|
||||
pattern = rf"{BASE_PATTERN}/channels/@me/(\d+)/(\d+)/?$"
|
||||
pattern = BASE_PATTERN + r"/channels/@me/(\d+)/(\d+)/?$"
|
||||
example = "https://discord.com/channels/@me/1234567890/9876543210"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -41,7 +41,7 @@ class DynastyscansBase():
|
||||
|
||||
class DynastyscansChapterExtractor(DynastyscansBase, ChapterExtractor):
|
||||
"""Extractor for manga-chapters from dynasty-scans.com"""
|
||||
pattern = rf"{BASE_PATTERN}(/chapters/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/chapters/[^/?#]+)"
|
||||
example = "https://dynasty-scans.com/chapters/NAME"
|
||||
|
||||
def metadata(self, page):
|
||||
@@ -81,7 +81,7 @@ class DynastyscansChapterExtractor(DynastyscansBase, ChapterExtractor):
|
||||
class DynastyscansMangaExtractor(DynastyscansBase, MangaExtractor):
|
||||
chapterclass = DynastyscansChapterExtractor
|
||||
reverse = False
|
||||
pattern = rf"{BASE_PATTERN}(/series/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/series/[^/?#]+)"
|
||||
example = "https://dynasty-scans.com/series/NAME"
|
||||
|
||||
def chapters(self, page):
|
||||
@@ -97,7 +97,7 @@ class DynastyscansSearchExtractor(DynastyscansBase, Extractor):
|
||||
directory_fmt = ("{category}", "Images")
|
||||
filename_fmt = "{image_id}.{extension}"
|
||||
archive_fmt = "i_{image_id}"
|
||||
pattern = rf"{BASE_PATTERN}/images/?(?:\?([^#]+))?$"
|
||||
pattern = BASE_PATTERN + r"/images/?(?:\?([^#]+))?$"
|
||||
example = "https://dynasty-scans.com/images?QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -126,7 +126,7 @@ class DynastyscansSearchExtractor(DynastyscansBase, Extractor):
|
||||
class DynastyscansImageExtractor(DynastyscansSearchExtractor):
|
||||
"""Extractor for individual images on dynasty-scans.com"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/images/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/images/(\d+)"
|
||||
example = "https://dynasty-scans.com/images/12345"
|
||||
|
||||
def images(self):
|
||||
@@ -136,7 +136,7 @@ class DynastyscansImageExtractor(DynastyscansSearchExtractor):
|
||||
class DynastyscansAnthologyExtractor(DynastyscansSearchExtractor):
|
||||
"""Extractor for dynasty-scans anthologies"""
|
||||
subcategory = "anthology"
|
||||
pattern = rf"{BASE_PATTERN}/anthologies/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/anthologies/([^/?#]+)"
|
||||
example = "https://dynasty-scans.com/anthologies/TITLE"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -94,13 +94,13 @@ BASE_PATTERN = E621Extractor.update({
|
||||
|
||||
class E621TagExtractor(E621Extractor, danbooru.DanbooruTagExtractor):
|
||||
"""Extractor for e621 posts from tag searches"""
|
||||
pattern = rf"{BASE_PATTERN}/posts?(?:\?[^#]*?tags=|/index/\d+/)([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"/posts?(?:\?[^#]*?tags=|/index/\d+/)([^&#]*)"
|
||||
example = "https://e621.net/posts?tags=TAG"
|
||||
|
||||
|
||||
class E621PoolExtractor(E621Extractor, danbooru.DanbooruPoolExtractor):
|
||||
"""Extractor for e621 pools"""
|
||||
pattern = rf"{BASE_PATTERN}/pool(?:s|/show)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/pool(?:s|/show)/(\d+)"
|
||||
example = "https://e621.net/pools/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -125,7 +125,7 @@ class E621PoolExtractor(E621Extractor, danbooru.DanbooruPoolExtractor):
|
||||
|
||||
class E621PostExtractor(E621Extractor, danbooru.DanbooruPostExtractor):
|
||||
"""Extractor for single e621 posts"""
|
||||
pattern = rf"{BASE_PATTERN}/post(?:s|/show)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post(?:s|/show)/(\d+)"
|
||||
example = "https://e621.net/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -135,7 +135,7 @@ class E621PostExtractor(E621Extractor, danbooru.DanbooruPostExtractor):
|
||||
|
||||
class E621PopularExtractor(E621Extractor, danbooru.DanbooruPopularExtractor):
|
||||
"""Extractor for popular images from e621"""
|
||||
pattern = rf"{BASE_PATTERN}/explore/posts/popular(?:\?([^#]*))?"
|
||||
pattern = BASE_PATTERN + r"/explore/posts/popular(?:\?([^#]*))?"
|
||||
example = "https://e621.net/explore/posts/popular"
|
||||
|
||||
def posts(self):
|
||||
@@ -166,7 +166,7 @@ class E621FavoriteExtractor(E621Extractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "Favorites", "{user_id}")
|
||||
archive_fmt = "f_{user_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/favorites(?:\?([^#]*))?"
|
||||
pattern = BASE_PATTERN + r"/favorites(?:\?([^#]*))?"
|
||||
example = "https://e621.net/favorites"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -64,7 +64,7 @@ class EromeExtractor(Extractor):
|
||||
class EromeAlbumExtractor(EromeExtractor):
|
||||
"""Extractor for albums on erome.com"""
|
||||
subcategory = "album"
|
||||
pattern = rf"{BASE_PATTERN}/a/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/a/(\w+)"
|
||||
example = "https://www.erome.com/a/ID"
|
||||
|
||||
def items(self):
|
||||
@@ -121,7 +121,7 @@ class EromeAlbumExtractor(EromeExtractor):
|
||||
|
||||
class EromeUserExtractor(EromeExtractor):
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?!a/|search\?)([^/?#]+)(?:/?\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/(?!a/|search\?)([^/?#]+)(?:/?\?([^#]+))?"
|
||||
example = "https://www.erome.com/USER"
|
||||
|
||||
def albums(self):
|
||||
@@ -137,7 +137,7 @@ class EromeUserExtractor(EromeExtractor):
|
||||
|
||||
class EromeSearchExtractor(EromeExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search/?\?(q=[^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/?\?(q=[^#]+)"
|
||||
example = "https://www.erome.com/search?q=QUERY"
|
||||
|
||||
def albums(self):
|
||||
|
||||
@@ -45,7 +45,7 @@ class EveriaPostExtractor(EveriaExtractor):
|
||||
subcategory = "post"
|
||||
directory_fmt = ("{category}", "{title}")
|
||||
archive_fmt = "{post_url}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}(/\d{{4}}/\d{{2}}/\d{{2}}/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/\d{4}/\d{2}/\d{2}/[^/?#]+)"
|
||||
example = "https://everia.club/0000/00/00/TITLE"
|
||||
|
||||
def items(self):
|
||||
@@ -72,26 +72,26 @@ class EveriaPostExtractor(EveriaExtractor):
|
||||
|
||||
class EveriaTagExtractor(EveriaExtractor):
|
||||
subcategory = "tag"
|
||||
pattern = rf"{BASE_PATTERN}(/tag/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/tag/[^/?#]+)"
|
||||
example = "https://everia.club/tag/TAG"
|
||||
|
||||
|
||||
class EveriaCategoryExtractor(EveriaExtractor):
|
||||
subcategory = "category"
|
||||
pattern = rf"{BASE_PATTERN}(/category/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/category/[^/?#]+)"
|
||||
example = "https://everia.club/category/CATEGORY"
|
||||
|
||||
|
||||
class EveriaDateExtractor(EveriaExtractor):
|
||||
subcategory = "date"
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"(/\d{{4}}(?:/\d{{2}})?(?:/\d{{2}})?)(?:/page/\d+)?/?$")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"(/\d{4}(?:/\d{2})?(?:/\d{2})?)(?:/page/\d+)?/?$")
|
||||
example = "https://everia.club/0000/00/00"
|
||||
|
||||
|
||||
class EveriaSearchExtractor(EveriaExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/(?:page/\d+/)?\?s=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:page/\d+/)?\?s=([^&#]+)"
|
||||
example = "https://everia.club/?s=SEARCH"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -115,9 +115,9 @@ class ExhentaiExtractor(Extractor):
|
||||
class ExhentaiGalleryExtractor(ExhentaiExtractor):
|
||||
"""Extractor for image galleries from exhentai.org"""
|
||||
subcategory = "gallery"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
rf"g/(\d+)/([\da-f]{{10}})|"
|
||||
rf"s/([\da-f]{{10}})/(\d+)-(\d+))")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"(?:/g/(\d+)/([\da-f]{10})"
|
||||
r"|/s/([\da-f]{10})/(\d+)-(\d+))")
|
||||
example = "https://e-hentai.org/g/12345/67890abcde/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -563,7 +563,7 @@ class ExhentaiGalleryExtractor(ExhentaiExtractor):
|
||||
class ExhentaiSearchExtractor(ExhentaiExtractor):
|
||||
"""Extractor for exhentai search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/(?:\?([^#]*)|tag/([^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"/(?:\?([^#]*)|tag/([^/?#]+))"
|
||||
example = "https://e-hentai.org/?f_search=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -620,7 +620,7 @@ class ExhentaiSearchExtractor(ExhentaiExtractor):
|
||||
class ExhentaiFavoriteExtractor(ExhentaiSearchExtractor):
|
||||
"""Extractor for favorited exhentai galleries"""
|
||||
subcategory = "favorite"
|
||||
pattern = rf"{BASE_PATTERN}/favorites\.php(?:\?([^#]*)())?"
|
||||
pattern = BASE_PATTERN + r"/favorites\.php(?:\?([^#]*)())?"
|
||||
example = "https://e-hentai.org/favorites.php"
|
||||
|
||||
def _init(self):
|
||||
|
||||
@@ -11,9 +11,9 @@ from .. import text, util, exception
|
||||
from ..cache import memcache
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?(?:[\w-]+\.)?facebook\.com"
|
||||
USER_PATTERN = (rf"{BASE_PATTERN}/"
|
||||
rf"(?!media/|photo/|photo.php|watch/|permalink.php)"
|
||||
rf"(?:profile\.php\?id=|people/[^/?#]+/)?([^/?&#]+)")
|
||||
USER_PATTERN = (BASE_PATTERN +
|
||||
r"/(?!media/|photo/|photo.php|watch/|permalink.php)"
|
||||
r"(?:profile\.php\?id=|people/[^/?#]+/)?([^/?&#]+)")
|
||||
|
||||
|
||||
class FacebookExtractor(Extractor):
|
||||
@@ -389,9 +389,9 @@ class FacebookExtractor(Extractor):
|
||||
class FacebookPhotoExtractor(FacebookExtractor):
|
||||
"""Base class for Facebook Photo extractors"""
|
||||
subcategory = "photo"
|
||||
pattern = (rf"{BASE_PATTERN}/"
|
||||
rf"(?:[^/?#]+/photos/[^/?#]+/|photo(?:.php)?/?\?"
|
||||
rf"(?:[^&#]+&)*fbid=)([^/?&#]+)[^/?#]*(?<!&setextract)$")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/(?:[^/?#]+/photos/[^/?#]+/|photo(?:.php)?/?\?"
|
||||
r"(?:[^&#]+&)*fbid=)([^/?&#]+)[^/?#]*(?<!&setextract)$")
|
||||
example = "https://www.facebook.com/photo/?fbid=PHOTO_ID"
|
||||
|
||||
def items(self):
|
||||
@@ -427,11 +427,12 @@ class FacebookSetExtractor(FacebookExtractor):
|
||||
"""Base class for Facebook Set extractors"""
|
||||
subcategory = "set"
|
||||
pattern = (
|
||||
rf"{BASE_PATTERN}/"
|
||||
rf"(?:(?:media/set|photo)/?\?(?:[^&#]+&)*set=([^&#]+)"
|
||||
rf"[^/?#]*(?<!&setextract)$"
|
||||
rf"|([^/?#]+/posts/[^/?#]+)"
|
||||
rf"|photo/\?(?:[^&#]+&)*fbid=([^/?&#]+)&set=([^/?&#]+)&setextract)")
|
||||
BASE_PATTERN +
|
||||
r"/(?:(?:media/set|photo)/?\?(?:[^&#]+&)*set=([^&#]+)"
|
||||
r"[^/?#]*(?<!&setextract)$"
|
||||
r"|([^/?#]+/posts/[^/?#]+)"
|
||||
r"|photo/\?(?:[^&#]+&)*fbid=([^/?&#]+)&set=([^/?&#]+)&setextract)"
|
||||
)
|
||||
example = "https://www.facebook.com/media/set/?set=SET_ID"
|
||||
|
||||
def items(self):
|
||||
@@ -454,7 +455,7 @@ class FacebookVideoExtractor(FacebookExtractor):
|
||||
"""Base class for Facebook Video extractors"""
|
||||
subcategory = "video"
|
||||
directory_fmt = ("{category}", "{username}", "{subcategory}")
|
||||
pattern = rf"{BASE_PATTERN}/(?:[^/?#]+/videos/|watch/?\?v=)([^/?&#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:[^/?#]+/videos/|watch/?\?v=)([^/?&#]+)"
|
||||
example = "https://www.facebook.com/watch/?v=VIDEO_ID"
|
||||
|
||||
def items(self):
|
||||
@@ -481,7 +482,7 @@ class FacebookInfoExtractor(FacebookExtractor):
|
||||
"""Extractor for Facebook Profile data"""
|
||||
subcategory = "info"
|
||||
directory_fmt = ("{category}", "{username}")
|
||||
pattern = rf"{USER_PATTERN}/info"
|
||||
pattern = USER_PATTERN + r"/info"
|
||||
example = "https://www.facebook.com/USERNAME/info"
|
||||
|
||||
def items(self):
|
||||
@@ -492,7 +493,7 @@ class FacebookInfoExtractor(FacebookExtractor):
|
||||
class FacebookAlbumsExtractor(FacebookExtractor):
|
||||
"""Extractor for Facebook Profile albums"""
|
||||
subcategory = "albums"
|
||||
pattern = rf"{USER_PATTERN}/photos_albums(?:/([^/?#]+))?"
|
||||
pattern = USER_PATTERN + r"/photos_albums(?:/([^/?#]+))?"
|
||||
example = "https://www.facebook.com/USERNAME/photos_albums"
|
||||
|
||||
def items(self):
|
||||
@@ -525,7 +526,7 @@ class FacebookAlbumsExtractor(FacebookExtractor):
|
||||
class FacebookPhotosExtractor(FacebookExtractor):
|
||||
"""Extractor for Facebook Profile Photos"""
|
||||
subcategory = "photos"
|
||||
pattern = rf"{USER_PATTERN}/photos(?:_by)?"
|
||||
pattern = USER_PATTERN + r"/photos(?:_by)?"
|
||||
example = "https://www.facebook.com/USERNAME/photos"
|
||||
|
||||
def items(self):
|
||||
@@ -542,7 +543,7 @@ class FacebookPhotosExtractor(FacebookExtractor):
|
||||
class FacebookAvatarExtractor(FacebookExtractor):
|
||||
"""Extractor for Facebook Profile Avatars"""
|
||||
subcategory = "avatar"
|
||||
pattern = rf"{USER_PATTERN}/avatar"
|
||||
pattern = USER_PATTERN + r"/avatar"
|
||||
example = "https://www.facebook.com/USERNAME/avatar"
|
||||
|
||||
def items(self):
|
||||
@@ -564,7 +565,7 @@ class FacebookAvatarExtractor(FacebookExtractor):
|
||||
|
||||
class FacebookUserExtractor(Dispatch, FacebookExtractor):
|
||||
"""Extractor for Facebook Profiles"""
|
||||
pattern = rf"{USER_PATTERN}/?(?:$|\?|#)"
|
||||
pattern = USER_PATTERN + r"/?(?:$|\?|#)"
|
||||
example = "https://www.facebook.com/USERNAME"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -355,7 +355,7 @@ class FanboxExtractor(Extractor):
|
||||
class FanboxCreatorExtractor(FanboxExtractor):
|
||||
"""Extractor for a Fanbox creator's works"""
|
||||
subcategory = "creator"
|
||||
pattern = rf"{USER_PATTERN}(?:/posts)?/?$"
|
||||
pattern = USER_PATTERN + r"(?:/posts)?/?$"
|
||||
example = "https://USER.fanbox.cc/"
|
||||
|
||||
def posts(self):
|
||||
@@ -384,7 +384,7 @@ class FanboxCreatorExtractor(FanboxExtractor):
|
||||
class FanboxPostExtractor(FanboxExtractor):
|
||||
"""Extractor for media from a single Fanbox post"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{USER_PATTERN}/posts/(\d+)"
|
||||
pattern = USER_PATTERN + r"/posts/(\d+)"
|
||||
example = "https://USER.fanbox.cc/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -394,7 +394,7 @@ class FanboxPostExtractor(FanboxExtractor):
|
||||
class FanboxHomeExtractor(FanboxExtractor):
|
||||
"""Extractor for your Fanbox home feed"""
|
||||
subcategory = "home"
|
||||
pattern = rf"{BASE_PATTERN}/?$"
|
||||
pattern = BASE_PATTERN + r"/?$"
|
||||
example = "https://fanbox.cc/"
|
||||
|
||||
def posts(self):
|
||||
@@ -405,7 +405,7 @@ class FanboxHomeExtractor(FanboxExtractor):
|
||||
class FanboxSupportingExtractor(FanboxExtractor):
|
||||
"""Extractor for your supported Fanbox users feed"""
|
||||
subcategory = "supporting"
|
||||
pattern = rf"{BASE_PATTERN}/home/supporting"
|
||||
pattern = BASE_PATTERN + r"/home/supporting"
|
||||
example = "https://fanbox.cc/home/supporting"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -20,7 +20,7 @@ class FapelloPostExtractor(Extractor):
|
||||
directory_fmt = ("{category}", "{model}")
|
||||
filename_fmt = "{model}_{id}.{extension}"
|
||||
archive_fmt = "{type}_{model}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?!search/|popular_videos/)([^/?#]+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?!search/|popular_videos/)([^/?#]+)/(\d+)"
|
||||
example = "https://fapello.com/MODEL/12345/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -52,9 +52,9 @@ class FapelloModelExtractor(Extractor):
|
||||
"""Extractor for all posts from a fapello model"""
|
||||
category = "fapello"
|
||||
subcategory = "model"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!top-(?:likes|followers)|popular_videos"
|
||||
rf"|videos|trending|search/?$)"
|
||||
rf"([^/?#]+)/?$")
|
||||
pattern = (BASE_PATTERN + r"/(?!top-(?:likes|followers)|popular_videos"
|
||||
r"|videos|trending|search/?$)"
|
||||
r"([^/?#]+)/?$")
|
||||
example = "https://fapello.com/model/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -85,9 +85,9 @@ class FapelloPathExtractor(Extractor):
|
||||
"""Extractor for models and posts from fapello.com paths"""
|
||||
category = "fapello"
|
||||
subcategory = "path"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!search/?$)"
|
||||
rf"(top-(?:likes|followers)|videos|trending"
|
||||
rf"|popular_videos/[^/?#]+)/?$")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/(?!search/?$)(top-(?:likes|followers)|videos|trending"
|
||||
r"|popular_videos/[^/?#]+)/?$")
|
||||
example = "https://fapello.com/trending/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -124,7 +124,7 @@ class FlickrAlbumExtractor(FlickrExtractor):
|
||||
directory_fmt = ("{category}", "{user[username]}",
|
||||
"Albums", "{album[id]} {album[title]}")
|
||||
archive_fmt = "a_{album[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/photos/([^/?#]+)/(?:album|set)s(?:/(\d+))?"
|
||||
pattern = BASE_PATTERN + r"/photos/([^/?#]+)/(?:album|set)s(?:/(\d+))?"
|
||||
example = "https://www.flickr.com/photos/USER/albums/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -166,7 +166,7 @@ class FlickrGalleryExtractor(FlickrExtractor):
|
||||
directory_fmt = ("{category}", "{user[username]}",
|
||||
"Galleries", "{gallery[gallery_id]} {gallery[title]}")
|
||||
archive_fmt = "g_{gallery[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/photos/([^/?#]+)/galleries/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/photos/([^/?#]+)/galleries/(\d+)"
|
||||
example = "https://www.flickr.com/photos/USER/galleries/12345/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -184,7 +184,7 @@ class FlickrGroupExtractor(FlickrExtractor):
|
||||
subcategory = "group"
|
||||
directory_fmt = ("{category}", "Groups", "{group[groupname]}")
|
||||
archive_fmt = "G_{group[nsid]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/groups/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/groups/([^/?#]+)"
|
||||
example = "https://www.flickr.com/groups/NAME/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -199,7 +199,7 @@ class FlickrUserExtractor(FlickrExtractor):
|
||||
"""Extractor for the photostream of a flickr user"""
|
||||
subcategory = "user"
|
||||
archive_fmt = "u_{user[nsid]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/photos/([^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"/photos/([^/?#]+)/?$"
|
||||
example = "https://www.flickr.com/photos/USER/"
|
||||
|
||||
def photos(self):
|
||||
@@ -211,7 +211,7 @@ class FlickrFavoriteExtractor(FlickrExtractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{user[username]}", "Favorites")
|
||||
archive_fmt = "f_{user[nsid]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/photos/([^/?#]+)/favorites"
|
||||
pattern = BASE_PATTERN + r"/photos/([^/?#]+)/favorites"
|
||||
example = "https://www.flickr.com/photos/USER/favorites"
|
||||
|
||||
def photos(self):
|
||||
@@ -223,7 +223,7 @@ class FlickrSearchExtractor(FlickrExtractor):
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "Search", "{search[text]}")
|
||||
archive_fmt = "s_{search}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/search/?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/?\?([^#]+)"
|
||||
example = "https://flickr.com/search/?text=QUERY"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -147,7 +147,7 @@ class FoolfuukaThreadExtractor(FoolfuukaExtractor):
|
||||
subcategory = "thread"
|
||||
directory_fmt = ("{category}", "{board[shortname]}",
|
||||
"{thread_num} {title|comment[:50]}")
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/thread/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/thread/(\d+)"
|
||||
example = "https://archived.moe/a/thread/12345/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -174,7 +174,7 @@ class FoolfuukaThreadExtractor(FoolfuukaExtractor):
|
||||
class FoolfuukaBoardExtractor(FoolfuukaExtractor):
|
||||
"""Base extractor for FoolFuuka based boards/archives"""
|
||||
subcategory = "board"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)(?:/(?:page/)?(\d*))?$"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)(?:/(?:page/)?(\d*))?$"
|
||||
example = "https://archived.moe/a/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -210,7 +210,7 @@ class FoolfuukaSearchExtractor(FoolfuukaExtractor):
|
||||
"""Base extractor for search results on FoolFuuka based boards/archives"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "search", "{search}")
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/search((?:/[^/?#]+/[^/?#]+)+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/search((?:/[^/?#]+/[^/?#]+)+)"
|
||||
example = "https://archived.moe/_/search/text/QUERY/"
|
||||
request_interval = (0.5, 1.5)
|
||||
|
||||
@@ -265,7 +265,7 @@ class FoolfuukaGalleryExtractor(FoolfuukaExtractor):
|
||||
"""Base extractor for FoolFuuka galleries"""
|
||||
subcategory = "gallery"
|
||||
directory_fmt = ("{category}", "{board}", "gallery")
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/gallery(?:/(\d+))?"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/gallery(?:/(\d+))?"
|
||||
example = "https://archived.moe/a/gallery"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -47,7 +47,7 @@ class FoolslideChapterExtractor(FoolslideExtractor):
|
||||
filename_fmt = (
|
||||
"{manga}_c{chapter:>03}{chapter_minor:?//}_{page:>03}.{extension}")
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}(/read/[^/?#]+/[a-z-]+/\d+/\d+(?:/\d+)?)"
|
||||
pattern = BASE_PATTERN + r"(/read/[^/?#]+/[a-z-]+/\d+/\d+(?:/\d+)?)"
|
||||
example = "https://read.powermanga.org/read/MANGA/en/0/123/"
|
||||
|
||||
def items(self):
|
||||
@@ -91,7 +91,7 @@ class FoolslideMangaExtractor(FoolslideExtractor):
|
||||
"""Base class for manga extractors for FoOlSlide based sites"""
|
||||
subcategory = "manga"
|
||||
categorytransfer = True
|
||||
pattern = rf"{BASE_PATTERN}(/series/[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/series/[^/?#]+)"
|
||||
example = "https://read.powermanga.org/series/MANGA/"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -231,7 +231,7 @@ class FuraffinityExtractor(Extractor):
|
||||
class FuraffinityGalleryExtractor(FuraffinityExtractor):
|
||||
"""Extractor for a furaffinity user's gallery"""
|
||||
subcategory = "gallery"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/([^/?#]+)(?:$|/(?!folder/))"
|
||||
pattern = BASE_PATTERN + r"/gallery/([^/?#]+)(?:$|/(?!folder/))"
|
||||
example = "https://www.furaffinity.net/gallery/USER/"
|
||||
|
||||
def posts(self):
|
||||
@@ -243,7 +243,7 @@ class FuraffinityFolderExtractor(FuraffinityExtractor):
|
||||
subcategory = "folder"
|
||||
directory_fmt = ("{category}", "{user!l}",
|
||||
"Folders", "{folder_id}{folder_name:? //}")
|
||||
pattern = rf"{BASE_PATTERN}/gallery/([^/?#]+)/folder/(\d+)(?:/([^/?#]+))?"
|
||||
pattern = BASE_PATTERN + r"/gallery/([^/?#]+)/folder/(\d+)(?:/([^/?#]+))?"
|
||||
example = "https://www.furaffinity.net/gallery/USER/folder/12345/FOLDER"
|
||||
|
||||
def metadata(self):
|
||||
@@ -260,7 +260,7 @@ class FuraffinityScrapsExtractor(FuraffinityExtractor):
|
||||
"""Extractor for a furaffinity user's scraps"""
|
||||
subcategory = "scraps"
|
||||
directory_fmt = ("{category}", "{user!l}", "Scraps")
|
||||
pattern = rf"{BASE_PATTERN}/scraps/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/scraps/([^/?#]+)"
|
||||
example = "https://www.furaffinity.net/scraps/USER/"
|
||||
|
||||
def posts(self):
|
||||
@@ -271,7 +271,7 @@ class FuraffinityFavoriteExtractor(FuraffinityExtractor):
|
||||
"""Extractor for a furaffinity user's favorites"""
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{user!l}", "Favorites")
|
||||
pattern = rf"{BASE_PATTERN}/favorites/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/favorites/([^/?#]+)"
|
||||
example = "https://www.furaffinity.net/favorites/USER/"
|
||||
|
||||
def posts(self):
|
||||
@@ -287,7 +287,7 @@ class FuraffinitySearchExtractor(FuraffinityExtractor):
|
||||
"""Extractor for furaffinity search results"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "Search", "{search}")
|
||||
pattern = rf"{BASE_PATTERN}/search(?:/([^/?#]+))?/?[?&]([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search(?:/([^/?#]+))?/?[?&]([^#]+)"
|
||||
example = "https://www.furaffinity.net/search/?q=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -306,7 +306,7 @@ class FuraffinitySearchExtractor(FuraffinityExtractor):
|
||||
class FuraffinityPostExtractor(FuraffinityExtractor):
|
||||
"""Extractor for individual posts on furaffinity"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/(?:view|full)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?:view|full)/(\d+)"
|
||||
example = "https://www.furaffinity.net/view/12345/"
|
||||
|
||||
def posts(self):
|
||||
@@ -317,7 +317,7 @@ class FuraffinityPostExtractor(FuraffinityExtractor):
|
||||
|
||||
class FuraffinityUserExtractor(Dispatch, FuraffinityExtractor):
|
||||
"""Extractor for furaffinity user profiles"""
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)"
|
||||
example = "https://www.furaffinity.net/user/USER/"
|
||||
|
||||
def items(self):
|
||||
@@ -333,7 +333,7 @@ class FuraffinityUserExtractor(Dispatch, FuraffinityExtractor):
|
||||
class FuraffinityFollowingExtractor(FuraffinityExtractor):
|
||||
"""Extractor for a furaffinity user's watched users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/watchlist/by/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + "/watchlist/by/([^/?#]+)"
|
||||
example = "https://www.furaffinity.net/watchlist/by/USER/"
|
||||
|
||||
def items(self):
|
||||
@@ -355,7 +355,7 @@ class FuraffinityFollowingExtractor(FuraffinityExtractor):
|
||||
class FuraffinitySubmissionsExtractor(FuraffinityExtractor):
|
||||
"""Extractor for new furaffinity submissions"""
|
||||
subcategory = "submissions"
|
||||
pattern = rf"{BASE_PATTERN}(/msg/submissions(?:/[^/?#]+)?)"
|
||||
pattern = BASE_PATTERN + r"(/msg/submissions(?:/[^/?#]+)?)"
|
||||
example = "https://www.furaffinity.net/msg/submissions"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -97,7 +97,7 @@ class Furry34Extractor(BooruExtractor):
|
||||
class Furry34PostExtractor(Furry34Extractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post/(\d+)"
|
||||
example = "https://furry34.com/post/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -108,7 +108,7 @@ class Furry34PlaylistExtractor(Furry34Extractor):
|
||||
subcategory = "playlist"
|
||||
directory_fmt = ("{category}", "{playlist_id}")
|
||||
archive_fmt = "p_{playlist_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/playlists/view/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/playlists/view/(\d+)"
|
||||
example = "https://furry34.com/playlists/view/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -123,7 +123,7 @@ class Furry34TagExtractor(Furry34Extractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:([^/?#]+))?(?:/?\?([^#]+))?(?:$|#)"
|
||||
pattern = BASE_PATTERN + r"/(?:([^/?#]+))?(?:/?\?([^#]+))?(?:$|#)"
|
||||
example = "https://furry34.com/TAG"
|
||||
|
||||
def _init(self):
|
||||
|
||||
@@ -148,7 +148,7 @@ class GelbooruBase():
|
||||
class GelbooruTagExtractor(GelbooruBase,
|
||||
gelbooru_v02.GelbooruV02TagExtractor):
|
||||
"""Extractor for images from gelbooru.com based on search-tags"""
|
||||
pattern = rf"{BASE_PATTERN}page=post&s=list&tags=([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"page=post&s=list&tags=([^&#]*)"
|
||||
example = "https://gelbooru.com/index.php?page=post&s=list&tags=TAG"
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ class GelbooruPoolExtractor(GelbooruBase,
|
||||
gelbooru_v02.GelbooruV02PoolExtractor):
|
||||
"""Extractor for gelbooru pools"""
|
||||
per_page = 45
|
||||
pattern = rf"{BASE_PATTERN}page=pool&s=show&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"page=pool&s=show&id=(\d+)"
|
||||
example = "https://gelbooru.com/index.php?page=pool&s=show&id=12345"
|
||||
|
||||
skip = GelbooruBase._skip_offset
|
||||
@@ -187,7 +187,7 @@ class GelbooruFavoriteExtractor(GelbooruBase,
|
||||
gelbooru_v02.GelbooruV02FavoriteExtractor):
|
||||
"""Extractor for gelbooru favorites"""
|
||||
per_page = 100
|
||||
pattern = rf"{BASE_PATTERN}page=favorites&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"page=favorites&s=view&id=(\d+)"
|
||||
example = "https://gelbooru.com/index.php?page=favorites&s=view&id=12345"
|
||||
|
||||
skip = GelbooruBase._skip_offset
|
||||
@@ -284,10 +284,10 @@ class GelbooruFavoriteExtractor(GelbooruBase,
|
||||
class GelbooruPostExtractor(GelbooruBase,
|
||||
gelbooru_v02.GelbooruV02PostExtractor):
|
||||
"""Extractor for single images from gelbooru.com"""
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"(?=(?:[^#]+&)?page=post(?:&|#|$))"
|
||||
rf"(?=(?:[^#]+&)?s=view(?:&|#|$))"
|
||||
rf"(?:[^#]+&)?id=(\d+)")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"(?=(?:[^#]+&)?page=post(?:&|#|$))"
|
||||
r"(?=(?:[^#]+&)?s=view(?:&|#|$))"
|
||||
r"(?:[^#]+&)?id=(\d+)")
|
||||
example = "https://gelbooru.com/index.php?page=post&s=view&id=12345"
|
||||
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ class GelbooruV01TagExtractor(GelbooruV01Extractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=list&tags=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=list&tags=([^&#]+)"
|
||||
example = "https://allgirl.booru.org/index.php?page=post&s=list&tags=TAG"
|
||||
|
||||
def metadata(self):
|
||||
@@ -104,7 +104,7 @@ class GelbooruV01FavoriteExtractor(GelbooruV01Extractor):
|
||||
directory_fmt = ("{category}", "favorites", "{favorite_id}")
|
||||
archive_fmt = "f_{favorite_id}_{id}"
|
||||
per_page = 50
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
example = "https://allgirl.booru.org/index.php?page=favorites&s=view&id=1"
|
||||
|
||||
def metadata(self):
|
||||
@@ -120,7 +120,7 @@ class GelbooruV01FavoriteExtractor(GelbooruV01Extractor):
|
||||
class GelbooruV01PostExtractor(GelbooruV01Extractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=view&id=(\d+)"
|
||||
example = "https://allgirl.booru.org/index.php?page=post&s=view&id=12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -190,7 +190,7 @@ class GelbooruV02TagExtractor(GelbooruV02Extractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=list&tags=([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=list&tags=([^&#]*)"
|
||||
example = "https://safebooru.org/index.php?page=post&s=list&tags=TAG"
|
||||
|
||||
def posts(self):
|
||||
@@ -206,7 +206,7 @@ class GelbooruV02PoolExtractor(GelbooruV02Extractor):
|
||||
subcategory = "pool"
|
||||
directory_fmt = ("{category}", "pool", "{pool}")
|
||||
archive_fmt = "p_{pool}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=pool&s=show&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=pool&s=show&id=(\d+)"
|
||||
example = "https://safebooru.org/index.php?page=pool&s=show&id=12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -257,7 +257,7 @@ class GelbooruV02FavoriteExtractor(GelbooruV02Extractor):
|
||||
directory_fmt = ("{category}", "favorites", "{favorite_id}")
|
||||
archive_fmt = "f_{favorite_id}_{id}"
|
||||
per_page = 50
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
example = "https://safebooru.org/index.php?page=favorites&s=view&id=12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -275,7 +275,7 @@ class GelbooruV02FavoriteExtractor(GelbooruV02Extractor):
|
||||
class GelbooruV02PostExtractor(GelbooruV02Extractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=view&id=(\d+)"
|
||||
example = "https://safebooru.org/index.php?page=post&s=view&id=12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -41,7 +41,7 @@ class GirlsreleasedExtractor(Extractor):
|
||||
class GirlsreleasedSetExtractor(GirlsreleasedExtractor):
|
||||
"""Extractor for girlsreleased galleries"""
|
||||
subcategory = "set"
|
||||
pattern = rf"{BASE_PATTERN}/set/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/set/(\d+)"
|
||||
example = "https://girlsreleased.com/set/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -65,12 +65,12 @@ class GirlsreleasedSetExtractor(GirlsreleasedExtractor):
|
||||
class GirlsreleasedModelExtractor(GirlsreleasedExtractor):
|
||||
"""Extractor for girlsreleased models"""
|
||||
subcategory = _path = "model"
|
||||
pattern = rf"{BASE_PATTERN}/model/(\d+(?:/.+)?)"
|
||||
pattern = BASE_PATTERN + r"/model/(\d+(?:/.+)?)"
|
||||
example = "https://girlsreleased.com/model/12345/MODEL"
|
||||
|
||||
|
||||
class GirlsreleasedSiteExtractor(GirlsreleasedExtractor):
|
||||
"""Extractor for girlsreleased sites"""
|
||||
subcategory = _path = "site"
|
||||
pattern = rf"{BASE_PATTERN}/site/([^/?#]+(?:/model/\d+/?.*)?)"
|
||||
pattern = BASE_PATTERN + r"/site/([^/?#]+(?:/model/\d+/?.*)?)"
|
||||
example = "https://girlsreleased.com/site/SITE"
|
||||
|
||||
@@ -60,7 +60,7 @@ class GirlswithmuscleExtractor(Extractor):
|
||||
class GirlswithmusclePostExtractor(GirlswithmuscleExtractor):
|
||||
"""Extractor for individual posts on girlswithmuscle.com"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(\d+)"
|
||||
example = "https://www.girlswithmuscle.com/12345/"
|
||||
|
||||
def items(self):
|
||||
@@ -143,7 +143,7 @@ class GirlswithmusclePostExtractor(GirlswithmuscleExtractor):
|
||||
class GirlswithmuscleSearchExtractor(GirlswithmuscleExtractor):
|
||||
"""Extractor for search results on girlswithmuscle.com"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/images/(.*)"
|
||||
pattern = BASE_PATTERN + r"/images/(.*)"
|
||||
example = "https://www.girlswithmuscle.com/images/?name=MODEL"
|
||||
|
||||
def pages(self):
|
||||
|
||||
@@ -123,7 +123,7 @@ class HatenablogEntriesExtractor(HatenablogExtractor):
|
||||
class HatenablogEntryExtractor(HatenablogExtractor):
|
||||
"""Extractor for a single entry URL"""
|
||||
subcategory = "entry"
|
||||
pattern = rf"{BASE_PATTERN}/entry/([^?#]+){QUERY_RE}"
|
||||
pattern = BASE_PATTERN + r"/entry/([^?#]+)" + QUERY_RE
|
||||
example = "https://BLOG.hatenablog.com/entry/PATH"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -146,21 +146,21 @@ class HatenablogEntryExtractor(HatenablogExtractor):
|
||||
class HatenablogHomeExtractor(HatenablogEntriesExtractor):
|
||||
"""Extractor for a blog's home page"""
|
||||
subcategory = "home"
|
||||
pattern = rf"{BASE_PATTERN}(/?){QUERY_RE}"
|
||||
pattern = BASE_PATTERN + r"(/?)" + QUERY_RE
|
||||
example = "https://BLOG.hatenablog.com"
|
||||
|
||||
|
||||
class HatenablogArchiveExtractor(HatenablogEntriesExtractor):
|
||||
"""Extractor for a blog's archive page"""
|
||||
subcategory = "archive"
|
||||
pattern = (rf"{BASE_PATTERN}(/archive(?:/\d+(?:/\d+(?:/\d+)?)?"
|
||||
rf"|/category/[^?#]+)?){QUERY_RE}")
|
||||
pattern = (BASE_PATTERN + r"(/archive(?:/\d+(?:/\d+(?:/\d+)?)?"
|
||||
r"|/category/[^?#]+)?)" + QUERY_RE)
|
||||
example = "https://BLOG.hatenablog.com/archive/2024"
|
||||
|
||||
|
||||
class HatenablogSearchExtractor(HatenablogEntriesExtractor):
|
||||
"""Extractor for a blog's search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}(/search){QUERY_RE}"
|
||||
pattern = BASE_PATTERN + r"(/search)" + QUERY_RE
|
||||
example = "https://BLOG.hatenablog.com/search?q=QUERY"
|
||||
allowed_parameters = ("q",)
|
||||
|
||||
@@ -38,7 +38,7 @@ class HentaicosplaysGalleryExtractor(
|
||||
directory_fmt = ("{site}", "{title}")
|
||||
filename_fmt = "{filename}.{extension}"
|
||||
archive_fmt = "{title}_{filename}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:image|story)/([\w-]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:image|story)/([\w-]+)"
|
||||
example = "https://hentai-cosplay-xxx.com/image/TITLE/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -214,7 +214,7 @@ class HentaifoundryExtractor(Extractor):
|
||||
|
||||
class HentaifoundryUserExtractor(Dispatch, HentaifoundryExtractor):
|
||||
"""Extractor for a hentaifoundry user profile"""
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/profile"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/profile"
|
||||
example = "https://www.hentai-foundry.com/user/USER/profile"
|
||||
|
||||
def items(self):
|
||||
@@ -235,7 +235,7 @@ class HentaifoundryUserExtractor(Dispatch, HentaifoundryExtractor):
|
||||
class HentaifoundryPicturesExtractor(HentaifoundryExtractor):
|
||||
"""Extractor for all pictures of a hentaifoundry user"""
|
||||
subcategory = "pictures"
|
||||
pattern = rf"{BASE_PATTERN}/pictures/user/([^/?#]+)(?:/page/(\d+))?/?$"
|
||||
pattern = BASE_PATTERN + r"/pictures/user/([^/?#]+)(?:/page/(\d+))?/?$"
|
||||
example = "https://www.hentai-foundry.com/pictures/user/USER"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -247,7 +247,7 @@ class HentaifoundryScrapsExtractor(HentaifoundryExtractor):
|
||||
"""Extractor for scraps of a hentaifoundry user"""
|
||||
subcategory = "scraps"
|
||||
directory_fmt = ("{category}", "{user}", "Scraps")
|
||||
pattern = rf"{BASE_PATTERN}/pictures/user/([^/?#]+)/scraps"
|
||||
pattern = BASE_PATTERN + r"/pictures/user/([^/?#]+)/scraps"
|
||||
example = "https://www.hentai-foundry.com/pictures/user/USER/scraps"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -260,7 +260,7 @@ class HentaifoundryFavoriteExtractor(HentaifoundryExtractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{user}", "Favorites")
|
||||
archive_fmt = "f_{user}_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/faves/pictures"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/faves/pictures"
|
||||
example = "https://www.hentai-foundry.com/user/USER/faves/pictures"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -273,7 +273,7 @@ class HentaifoundryTagExtractor(HentaifoundryExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/pictures/tagged/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/pictures/tagged/([^/?#]+)"
|
||||
example = "https://www.hentai-foundry.com/pictures/tagged/TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -289,7 +289,7 @@ class HentaifoundryRecentExtractor(HentaifoundryExtractor):
|
||||
subcategory = "recent"
|
||||
directory_fmt = ("{category}", "Recent Pictures", "{date}")
|
||||
archive_fmt = "r_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/pictures/recent/(\d\d\d\d-\d\d-\d\d)"
|
||||
pattern = BASE_PATTERN + r"/pictures/recent/(\d\d\d\d-\d\d-\d\d)"
|
||||
example = "https://www.hentai-foundry.com/pictures/recent/1970-01-01"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -305,7 +305,7 @@ class HentaifoundryPopularExtractor(HentaifoundryExtractor):
|
||||
subcategory = "popular"
|
||||
directory_fmt = ("{category}", "Popular Pictures")
|
||||
archive_fmt = "p_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/pictures/popular()"
|
||||
pattern = BASE_PATTERN + r"/pictures/popular()"
|
||||
example = "https://www.hentai-foundry.com/pictures/popular"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -339,7 +339,7 @@ class HentaifoundryStoriesExtractor(HentaifoundryExtractor):
|
||||
"""Extractor for stories of a hentaifoundry user"""
|
||||
subcategory = "stories"
|
||||
archive_fmt = "s_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/stories/user/([^/?#]+)(?:/page/(\d+))?/?$"
|
||||
pattern = BASE_PATTERN + r"/stories/user/([^/?#]+)(?:/page/(\d+))?/?$"
|
||||
example = "https://www.hentai-foundry.com/stories/user/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -358,7 +358,7 @@ class HentaifoundryStoryExtractor(HentaifoundryExtractor):
|
||||
"""Extractor for a hentaifoundry story"""
|
||||
subcategory = "story"
|
||||
archive_fmt = "s_{index}"
|
||||
pattern = rf"{BASE_PATTERN}/stories/user/([^/?#]+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/stories/user/([^/?#]+)/(\d+)"
|
||||
example = "https://www.hentai-foundry.com/stories/user/USER/12345/TITLE"
|
||||
|
||||
skip = Extractor.skip
|
||||
|
||||
@@ -67,7 +67,7 @@ class HiperdexBase():
|
||||
|
||||
class HiperdexChapterExtractor(HiperdexBase, ChapterExtractor):
|
||||
"""Extractor for hiperdex manga chapters"""
|
||||
pattern = rf"{BASE_PATTERN}(/mangas?/([^/?#]+)/([^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"(/mangas?/([^/?#]+)/([^/?#]+))"
|
||||
example = "https://hiperdex.com/manga/MANGA/CHAPTER/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -89,7 +89,7 @@ class HiperdexChapterExtractor(HiperdexBase, ChapterExtractor):
|
||||
class HiperdexMangaExtractor(HiperdexBase, MangaExtractor):
|
||||
"""Extractor for hiperdex manga"""
|
||||
chapterclass = HiperdexChapterExtractor
|
||||
pattern = rf"{BASE_PATTERN}(/mangas?/([^/?#]+))/?$"
|
||||
pattern = BASE_PATTERN + r"(/mangas?/([^/?#]+))/?$"
|
||||
example = "https://hiperdex.com/manga/MANGA/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -125,7 +125,7 @@ class HiperdexArtistExtractor(HiperdexBase, MangaExtractor):
|
||||
categorytransfer = False
|
||||
chapterclass = HiperdexMangaExtractor
|
||||
reverse = False
|
||||
pattern = rf"{BASE_PATTERN}(/manga-a(?:rtist|uthor)/(?:[^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"(/manga-a(?:rtist|uthor)/(?:[^/?#]+))"
|
||||
example = "https://hiperdex.com/manga-artist/NAME/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -61,7 +61,7 @@ def decode_video_url(url):
|
||||
class HotleakPostExtractor(HotleakExtractor):
|
||||
"""Extractor for individual posts on hotleak"""
|
||||
subcategory = "post"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!(?:hot|creators|videos|photos)(?:$|/))"
|
||||
pattern = (BASE_PATTERN + r"/(?!(?:hot|creators|videos|photos)(?:$|/))"
|
||||
r"([^/]+)/(photo|video)/(\d+)")
|
||||
example = "https://hotleak.vip/MODEL/photo/12345"
|
||||
|
||||
@@ -96,7 +96,7 @@ class HotleakPostExtractor(HotleakExtractor):
|
||||
class HotleakCreatorExtractor(HotleakExtractor):
|
||||
"""Extractor for all posts from a hotleak creator"""
|
||||
subcategory = "creator"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!(?:hot|creators|videos|photos)(?:$|/))"
|
||||
pattern = (BASE_PATTERN + r"/(?!(?:hot|creators|videos|photos)(?:$|/))"
|
||||
r"([^/?#]+)/?$")
|
||||
example = "https://hotleak.vip/MODEL"
|
||||
|
||||
@@ -150,7 +150,7 @@ class HotleakCreatorExtractor(HotleakExtractor):
|
||||
class HotleakCategoryExtractor(HotleakExtractor):
|
||||
"""Extractor for hotleak categories"""
|
||||
subcategory = "category"
|
||||
pattern = rf"{BASE_PATTERN}/(hot|creators|videos|photos)(?:/?\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/(hot|creators|videos|photos)(?:/?\?([^#]+))?"
|
||||
example = "https://hotleak.vip/photos"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -172,7 +172,7 @@ class HotleakCategoryExtractor(HotleakExtractor):
|
||||
class HotleakSearchExtractor(HotleakExtractor):
|
||||
"""Extractor for hotleak search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search(?:/?\?([^#]+))"
|
||||
pattern = BASE_PATTERN + r"/search(?:/?\?([^#]+))"
|
||||
example = "https://hotleak.vip/search?search=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -29,17 +29,17 @@ class IdolcomplexBase():
|
||||
|
||||
class IdolcomplexTagExtractor(IdolcomplexBase, sankaku.SankakuTagExtractor):
|
||||
"""Extractor for idolcomplex tag searches"""
|
||||
pattern = rf"{BASE_PATTERN}(?:/posts)?/?\?([^#]*)"
|
||||
pattern = BASE_PATTERN + r"(?:/posts)?/?\?([^#]*)"
|
||||
example = "https://www.idolcomplex.com/en/posts?tags=TAGS"
|
||||
|
||||
|
||||
class IdolcomplexPoolExtractor(IdolcomplexBase, sankaku.SankakuPoolExtractor):
|
||||
"""Extractor for idolcomplex pools"""
|
||||
pattern = rf"{BASE_PATTERN}/pools?/(?:show/)?(\w+)"
|
||||
pattern = BASE_PATTERN + r"/pools?/(?:show/)?(\w+)"
|
||||
example = "https://www.idolcomplex.com/en/pools/0123456789abcdef"
|
||||
|
||||
|
||||
class IdolcomplexPostExtractor(IdolcomplexBase, sankaku.SankakuPostExtractor):
|
||||
"""Extractor for individual idolcomplex posts"""
|
||||
pattern = rf"{BASE_PATTERN}/posts?(?:/show)?/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/posts?(?:/show)?/(\w+)"
|
||||
example = "https://www.idolcomplex.com/en/posts/0123456789abcdef"
|
||||
|
||||
@@ -19,7 +19,7 @@ class ImagechestGalleryExtractor(GalleryExtractor):
|
||||
"""Extractor for image galleries from imgchest.com"""
|
||||
category = "imagechest"
|
||||
root = "https://imgchest.com"
|
||||
pattern = rf"{BASE_PATTERN}/p/([A-Za-z0-9]{{11}})"
|
||||
pattern = BASE_PATTERN + r"/p/([A-Za-z0-9]{11})"
|
||||
example = "https://imgchest.com/p/abcdefghijk"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -78,7 +78,7 @@ class ImagechestUserExtractor(Extractor):
|
||||
category = "imagechest"
|
||||
subcategory = "user"
|
||||
root = "https://imgchest.com"
|
||||
pattern = rf"{BASE_PATTERN}/u/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/u/([^/?#]+)"
|
||||
example = "https://imgchest.com/u/USER"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -39,7 +39,7 @@ class ImagefapExtractor(Extractor):
|
||||
class ImagefapGalleryExtractor(ImagefapExtractor):
|
||||
"""Extractor for image galleries from imagefap.com"""
|
||||
subcategory = "gallery"
|
||||
pattern = rf"{BASE_PATTERN}/(?:gallery\.php\?gid=|gallery/|pictures/)(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?:gallery\.php\?gid=|gallery/|pictures/)(\d+)"
|
||||
example = "https://www.imagefap.com/gallery/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -110,7 +110,7 @@ class ImagefapGalleryExtractor(ImagefapExtractor):
|
||||
class ImagefapImageExtractor(ImagefapExtractor):
|
||||
"""Extractor for single images from imagefap.com"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/photo/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/photo/(\d+)"
|
||||
example = "https://www.imagefap.com/photo/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -148,9 +148,9 @@ class ImagefapImageExtractor(ImagefapExtractor):
|
||||
class ImagefapFolderExtractor(ImagefapExtractor):
|
||||
"""Extractor for imagefap user folders"""
|
||||
subcategory = "folder"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:organizer/|"
|
||||
rf"(?:usergallery\.php\?user(id)?=([^&#]+)&"
|
||||
rf"|profile/([^/?#]+)/galleries\?)folderid=)(\d+|-1)")
|
||||
pattern = (BASE_PATTERN + r"/(?:organizer/|"
|
||||
r"(?:usergallery\.php\?user(id)?=([^&#]+)&"
|
||||
r"|profile/([^/?#]+)/galleries\?)folderid=)(\d+|-1)")
|
||||
example = "https://www.imagefap.com/organizer/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -206,9 +206,9 @@ class ImagefapFolderExtractor(ImagefapExtractor):
|
||||
class ImagefapUserExtractor(ImagefapExtractor):
|
||||
"""Extractor for an imagefap user profile"""
|
||||
subcategory = "user"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
rf"profile(?:\.php\?user=|/)([^/?#]+)(?:/galleries)?|"
|
||||
rf"usergallery\.php\?userid=(\d+))(?:$|#)")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/(?:profile(?:\.php\?user=|/)([^/?#]+)(?:/galleries)?"
|
||||
r"|usergallery\.php\?userid=(\d+))(?:$|#)")
|
||||
example = "https://www.imagefap.com/profile/USER"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -67,7 +67,7 @@ class ImgurImageExtractor(ImgurExtractor):
|
||||
subcategory = "image"
|
||||
filename_fmt = "{category}_{id}{title:?_//}.{extension}"
|
||||
archive_fmt = "{id}"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!gallery|search)"
|
||||
pattern = (BASE_PATTERN + r"/(?!gallery|search)"
|
||||
r"(?:r/\w+/)?(?:[^/?#]+-)?(\w{7}|\w{5})[sbtmlh]?")
|
||||
example = "https://imgur.com/abcdefg"
|
||||
|
||||
@@ -93,7 +93,7 @@ class ImgurAlbumExtractor(ImgurExtractor):
|
||||
directory_fmt = ("{category}", "{album[id]}{album[title]:? - //}")
|
||||
filename_fmt = "{category}_{album[id]}_{num:>03}_{id}.{extension}"
|
||||
archive_fmt = "{album[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/a/(?:[^/?#]+-)?(\w{{7}}|\w{{5}})"
|
||||
pattern = BASE_PATTERN + r"/a/(?:[^/?#]+-)?(\w{7}|\w{5})"
|
||||
example = "https://imgur.com/a/abcde"
|
||||
|
||||
def items(self):
|
||||
@@ -126,8 +126,7 @@ class ImgurAlbumExtractor(ImgurExtractor):
|
||||
class ImgurGalleryExtractor(ImgurExtractor):
|
||||
"""Extractor for imgur galleries"""
|
||||
subcategory = "gallery"
|
||||
pattern = (rf"{BASE_PATTERN}/"
|
||||
rf"(?:gallery|t/\w+)/(?:[^/?#]+-)?(\w{{7}}|\w{{5}})")
|
||||
pattern = BASE_PATTERN + r"/(?:gallery|t/\w+)/(?:[^/?#]+-)?(\w{7}|\w{5})"
|
||||
example = "https://imgur.com/gallery/abcde"
|
||||
|
||||
def items(self):
|
||||
@@ -143,7 +142,7 @@ class ImgurGalleryExtractor(ImgurExtractor):
|
||||
class ImgurUserExtractor(ImgurExtractor):
|
||||
"""Extractor for all images posted by a user"""
|
||||
subcategory = "user"
|
||||
pattern = (rf"{BASE_PATTERN}/user/(?!me(?:/|$|\?|#))"
|
||||
pattern = (BASE_PATTERN + r"/user/(?!me(?:/|$|\?|#))"
|
||||
r"([^/?#]+)(?:/posts|/submitted)?/?$")
|
||||
example = "https://imgur.com/user/USER"
|
||||
|
||||
@@ -154,7 +153,7 @@ class ImgurUserExtractor(ImgurExtractor):
|
||||
class ImgurFavoriteExtractor(ImgurExtractor):
|
||||
"""Extractor for a user's favorites"""
|
||||
subcategory = "favorite"
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/favorites/?$"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/favorites/?$"
|
||||
example = "https://imgur.com/user/USER/favorites"
|
||||
|
||||
def items(self):
|
||||
@@ -164,7 +163,7 @@ class ImgurFavoriteExtractor(ImgurExtractor):
|
||||
class ImgurFavoriteFolderExtractor(ImgurExtractor):
|
||||
"""Extractor for a user's favorites folder"""
|
||||
subcategory = "favorite-folder"
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/favorites/folder/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/favorites/folder/(\d+)"
|
||||
example = "https://imgur.com/user/USER/favorites/folder/12345/TITLE"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -179,7 +178,7 @@ class ImgurFavoriteFolderExtractor(ImgurExtractor):
|
||||
class ImgurMeExtractor(ImgurExtractor):
|
||||
"""Extractor for your personal uploads"""
|
||||
subcategory = "me"
|
||||
pattern = rf"{BASE_PATTERN}/user/me(?:/posts)?(/hidden)?"
|
||||
pattern = BASE_PATTERN + r"/user/me(?:/posts)?(/hidden)?"
|
||||
example = "https://imgur.com/user/me"
|
||||
|
||||
def items(self):
|
||||
@@ -196,7 +195,7 @@ class ImgurMeExtractor(ImgurExtractor):
|
||||
class ImgurSubredditExtractor(ImgurExtractor):
|
||||
"""Extractor for a subreddits's imgur links"""
|
||||
subcategory = "subreddit"
|
||||
pattern = rf"{BASE_PATTERN}/r/([^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"/r/([^/?#]+)/?$"
|
||||
example = "https://imgur.com/r/SUBREDDIT"
|
||||
|
||||
def items(self):
|
||||
@@ -206,7 +205,7 @@ class ImgurSubredditExtractor(ImgurExtractor):
|
||||
class ImgurTagExtractor(ImgurExtractor):
|
||||
"""Extractor for imgur tag searches"""
|
||||
subcategory = "tag"
|
||||
pattern = rf"{BASE_PATTERN}/t/([^/?#]+)$"
|
||||
pattern = BASE_PATTERN + r"/t/([^/?#]+)$"
|
||||
example = "https://imgur.com/t/TAG"
|
||||
|
||||
def items(self):
|
||||
@@ -216,7 +215,7 @@ class ImgurTagExtractor(ImgurExtractor):
|
||||
class ImgurSearchExtractor(ImgurExtractor):
|
||||
"""Extractor for imgur search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search(?:/[^?#]+)?/?\?q=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/search(?:/[^?#]+)?/?\?q=([^&#]+)"
|
||||
example = "https://imgur.com/search?q=UERY"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -79,7 +79,7 @@ BASE_PATTERN = ImhentaiExtractor.update({
|
||||
|
||||
class ImhentaiGalleryExtractor(ImhentaiExtractor, GalleryExtractor):
|
||||
"""Extractor for imhentai galleries"""
|
||||
pattern = rf"{BASE_PATTERN}/(?:gallery|view)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?:gallery|view)/(\d+)"
|
||||
example = "https://imhentai.xxx/gallery/12345/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -141,7 +141,7 @@ class ImhentaiGalleryExtractor(ImhentaiExtractor, GalleryExtractor):
|
||||
class ImhentaiTagExtractor(ImhentaiExtractor):
|
||||
"""Extractor for imhentai tag searches"""
|
||||
subcategory = "tag"
|
||||
pattern = (rf"{BASE_PATTERN}(/(?:"
|
||||
pattern = (BASE_PATTERN + r"(/(?:"
|
||||
r"artist|category|character|group|language|parody|tag"
|
||||
r")/([^/?#]+))")
|
||||
example = "https://imhentai.xxx/tag/TAG/"
|
||||
@@ -154,7 +154,7 @@ class ImhentaiTagExtractor(ImhentaiExtractor):
|
||||
class ImhentaiSearchExtractor(ImhentaiExtractor):
|
||||
"""Extractor for imhentai search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}(/(?:advanced-)?search/?\?[^#]+|/[^/?#]+/?)"
|
||||
pattern = BASE_PATTERN + r"(/(?:advanced-)?search/?\?[^#]+|/[^/?#]+/?)"
|
||||
example = "https://imhentai.xxx/search/?key=QUERY"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -71,7 +71,7 @@ class InkbunnyExtractor(Extractor):
|
||||
class InkbunnyUserExtractor(InkbunnyExtractor):
|
||||
"""Extractor for inkbunny user profiles"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?!s/)(gallery/|scraps/)?(\w+)(?:$|[/?#])"
|
||||
pattern = BASE_PATTERN + r"/(?!s/)(gallery/|scraps/)?(\w+)(?:$|[/?#])"
|
||||
example = "https://inkbunny.net/USER"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -101,7 +101,7 @@ class InkbunnyUserExtractor(InkbunnyExtractor):
|
||||
class InkbunnyPoolExtractor(InkbunnyExtractor):
|
||||
"""Extractor for inkbunny pools"""
|
||||
subcategory = "pool"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"poolview_process\.php\?pool_id=(\d+)|"
|
||||
r"submissionsviewall\.php"
|
||||
r"\?((?:[^#]+&)?mode=pool(?:&[^#]+)?))")
|
||||
@@ -132,7 +132,7 @@ class InkbunnyFavoriteExtractor(InkbunnyExtractor):
|
||||
"""Extractor for inkbunny user favorites"""
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{favs_username!l}", "Favorites")
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"userfavorites_process\.php\?favs_user_id=(\d+)|"
|
||||
r"submissionsviewall\.php"
|
||||
r"\?((?:[^#]+&)?mode=userfavs(?:&[^#]+)?))")
|
||||
@@ -175,7 +175,7 @@ class InkbunnyFavoriteExtractor(InkbunnyExtractor):
|
||||
class InkbunnyUnreadExtractor(InkbunnyExtractor):
|
||||
"""Extractor for unread inkbunny submissions"""
|
||||
subcategory = "unread"
|
||||
pattern = (rf"{BASE_PATTERN}/submissionsviewall\.php"
|
||||
pattern = (BASE_PATTERN + r"/submissionsviewall\.php"
|
||||
r"\?((?:[^#]+&)?mode=unreadsubs(?:&[^#]+)?)")
|
||||
example = ("https://inkbunny.net/submissionsviewall.php"
|
||||
"?text=&mode=unreadsubs&type=")
|
||||
@@ -195,7 +195,7 @@ class InkbunnyUnreadExtractor(InkbunnyExtractor):
|
||||
class InkbunnySearchExtractor(InkbunnyExtractor):
|
||||
"""Extractor for inkbunny search results"""
|
||||
subcategory = "search"
|
||||
pattern = (rf"{BASE_PATTERN}/submissionsviewall\.php"
|
||||
pattern = (BASE_PATTERN + r"/submissionsviewall\.php"
|
||||
r"\?((?:[^#]+&)?mode=search(?:&[^#]+)?)")
|
||||
example = ("https://inkbunny.net/submissionsviewall.php"
|
||||
"?text=TAG&mode=search&type=")
|
||||
@@ -229,7 +229,7 @@ class InkbunnySearchExtractor(InkbunnyExtractor):
|
||||
class InkbunnyFollowingExtractor(InkbunnyExtractor):
|
||||
"""Extractor for inkbunny user watches"""
|
||||
subcategory = "following"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"watchlist_process\.php\?mode=watching&user_id=(\d+)|"
|
||||
r"usersviewall\.php"
|
||||
r"\?((?:[^#]+&)?mode=watching(?:&[^#]+)?))")
|
||||
@@ -268,7 +268,7 @@ class InkbunnyFollowingExtractor(InkbunnyExtractor):
|
||||
class InkbunnyPostExtractor(InkbunnyExtractor):
|
||||
"""Extractor for individual Inkbunny posts"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/s/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/s/(\d+)"
|
||||
example = "https://inkbunny.net/s/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -16,7 +16,7 @@ import itertools
|
||||
import binascii
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?(?:www\.)?instagram\.com"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/(?!(?:p|tv|reel|explore|stories)/)([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/(?!(?:p|tv|reel|explore|stories)/)([^/?#]+)"
|
||||
|
||||
|
||||
class InstagramExtractor(Extractor):
|
||||
@@ -505,7 +505,7 @@ class InstagramPostExtractor(InstagramExtractor):
|
||||
|
||||
class InstagramUserExtractor(Dispatch, InstagramExtractor):
|
||||
"""Extractor for an Instagram user profile"""
|
||||
pattern = rf"{USER_PATTERN}/?(?:$|[?#])"
|
||||
pattern = USER_PATTERN + r"/?(?:$|[?#])"
|
||||
example = "https://www.instagram.com/USER/"
|
||||
|
||||
def items(self):
|
||||
@@ -525,7 +525,7 @@ class InstagramUserExtractor(Dispatch, InstagramExtractor):
|
||||
class InstagramPostsExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's posts"""
|
||||
subcategory = "posts"
|
||||
pattern = rf"{USER_PATTERN}/posts"
|
||||
pattern = USER_PATTERN + r"/posts"
|
||||
example = "https://www.instagram.com/USER/posts/"
|
||||
|
||||
def posts(self):
|
||||
@@ -542,7 +542,7 @@ class InstagramPostsExtractor(InstagramExtractor):
|
||||
class InstagramReelsExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's reels"""
|
||||
subcategory = "reels"
|
||||
pattern = rf"{USER_PATTERN}/reels"
|
||||
pattern = USER_PATTERN + r"/reels"
|
||||
example = "https://www.instagram.com/USER/reels/"
|
||||
|
||||
def posts(self):
|
||||
@@ -559,7 +559,7 @@ class InstagramReelsExtractor(InstagramExtractor):
|
||||
class InstagramTaggedExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's tagged posts"""
|
||||
subcategory = "tagged"
|
||||
pattern = rf"{USER_PATTERN}/tagged"
|
||||
pattern = USER_PATTERN + r"/tagged"
|
||||
example = "https://www.instagram.com/USER/tagged/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -585,7 +585,7 @@ class InstagramTaggedExtractor(InstagramExtractor):
|
||||
class InstagramGuideExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram guide"""
|
||||
subcategory = "guide"
|
||||
pattern = rf"{USER_PATTERN}/guide/[^/?#]+/(\d+)"
|
||||
pattern = USER_PATTERN + r"/guide/[^/?#]+/(\d+)"
|
||||
example = "https://www.instagram.com/USER/guide/NAME/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -602,7 +602,7 @@ class InstagramGuideExtractor(InstagramExtractor):
|
||||
class InstagramSavedExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's saved media"""
|
||||
subcategory = "saved"
|
||||
pattern = rf"{USER_PATTERN}/saved(?:/all-posts)?/?$"
|
||||
pattern = USER_PATTERN + r"/saved(?:/all-posts)?/?$"
|
||||
example = "https://www.instagram.com/USER/saved/"
|
||||
|
||||
def posts(self):
|
||||
@@ -612,7 +612,7 @@ class InstagramSavedExtractor(InstagramExtractor):
|
||||
class InstagramCollectionExtractor(InstagramExtractor):
|
||||
"""Extractor for Instagram collection"""
|
||||
subcategory = "collection"
|
||||
pattern = rf"{USER_PATTERN}/saved/([^/?#]+)/([^/?#]+)"
|
||||
pattern = USER_PATTERN + r"/saved/([^/?#]+)/([^/?#]+)"
|
||||
example = "https://www.instagram.com/USER/saved/COLLECTION/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -696,7 +696,7 @@ class InstagramStoriesExtractor(InstagramExtractor):
|
||||
class InstagramHighlightsExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's story highlights"""
|
||||
subcategory = "highlights"
|
||||
pattern = rf"{USER_PATTERN}/highlights"
|
||||
pattern = USER_PATTERN + r"/highlights"
|
||||
example = "https://www.instagram.com/USER/highlights/"
|
||||
|
||||
def posts(self):
|
||||
@@ -707,7 +707,7 @@ class InstagramHighlightsExtractor(InstagramExtractor):
|
||||
class InstagramFollowersExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's followers"""
|
||||
subcategory = "followers"
|
||||
pattern = rf"{USER_PATTERN}/followers"
|
||||
pattern = USER_PATTERN + r"/followers"
|
||||
example = "https://www.instagram.com/USER/followers/"
|
||||
|
||||
def items(self):
|
||||
@@ -721,7 +721,7 @@ class InstagramFollowersExtractor(InstagramExtractor):
|
||||
class InstagramFollowingExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's followed users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{USER_PATTERN}/following"
|
||||
pattern = USER_PATTERN + r"/following"
|
||||
example = "https://www.instagram.com/USER/following/"
|
||||
|
||||
def items(self):
|
||||
@@ -736,7 +736,7 @@ class InstagramTagExtractor(InstagramExtractor):
|
||||
"""Extractor for Instagram tags"""
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{subcategory}", "{tag}")
|
||||
pattern = rf"{BASE_PATTERN}/explore/tags/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/explore/tags/([^/?#]+)"
|
||||
example = "https://www.instagram.com/explore/tags/TAG/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -749,7 +749,7 @@ class InstagramTagExtractor(InstagramExtractor):
|
||||
class InstagramInfoExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's profile data"""
|
||||
subcategory = "info"
|
||||
pattern = rf"{USER_PATTERN}/info"
|
||||
pattern = USER_PATTERN + r"/info"
|
||||
example = "https://www.instagram.com/USER/info/"
|
||||
|
||||
def items(self):
|
||||
@@ -765,7 +765,7 @@ class InstagramInfoExtractor(InstagramExtractor):
|
||||
class InstagramAvatarExtractor(InstagramExtractor):
|
||||
"""Extractor for an Instagram user's avatar"""
|
||||
subcategory = "avatar"
|
||||
pattern = rf"{USER_PATTERN}/avatar"
|
||||
pattern = USER_PATTERN + r"/avatar"
|
||||
example = "https://www.instagram.com/USER/avatar/"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -13,7 +13,7 @@ from ..cache import memcache
|
||||
from .. import text, util
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?itaku\.ee"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/profile/([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/profile/([^/?#]+)"
|
||||
|
||||
|
||||
class ItakuExtractor(Extractor):
|
||||
@@ -86,7 +86,7 @@ class ItakuExtractor(Extractor):
|
||||
class ItakuGalleryExtractor(ItakuExtractor):
|
||||
"""Extractor for an itaku user's gallery"""
|
||||
subcategory = "gallery"
|
||||
pattern = rf"{USER_PATTERN}/gallery(?:/(\d+))?"
|
||||
pattern = USER_PATTERN + r"/gallery(?:/(\d+))?"
|
||||
example = "https://itaku.ee/profile/USER/gallery"
|
||||
|
||||
def images(self):
|
||||
@@ -104,7 +104,7 @@ class ItakuPostsExtractor(ItakuExtractor):
|
||||
"{id}{title:? //}")
|
||||
filename_fmt = "{file[id]}{file[title]:? //}.{extension}"
|
||||
archive_fmt = "{id}_{file[id]}"
|
||||
pattern = rf"{USER_PATTERN}/posts(?:/(\d+))?"
|
||||
pattern = USER_PATTERN + r"/posts(?:/(\d+))?"
|
||||
example = "https://itaku.ee/profile/USER/posts"
|
||||
|
||||
def posts(self):
|
||||
@@ -118,7 +118,7 @@ class ItakuPostsExtractor(ItakuExtractor):
|
||||
class ItakuStarsExtractor(ItakuExtractor):
|
||||
"""Extractor for an itaku user's starred images"""
|
||||
subcategory = "stars"
|
||||
pattern = rf"{USER_PATTERN}/stars(?:/(\d+))?"
|
||||
pattern = USER_PATTERN + r"/stars(?:/(\d+))?"
|
||||
example = "https://itaku.ee/profile/USER/stars"
|
||||
|
||||
def images(self):
|
||||
@@ -132,7 +132,7 @@ class ItakuStarsExtractor(ItakuExtractor):
|
||||
|
||||
class ItakuFollowingExtractor(ItakuExtractor):
|
||||
subcategory = "following"
|
||||
pattern = rf"{USER_PATTERN}/following"
|
||||
pattern = USER_PATTERN + r"/following"
|
||||
example = "https://itaku.ee/profile/USER/following"
|
||||
|
||||
def users(self):
|
||||
@@ -143,7 +143,7 @@ class ItakuFollowingExtractor(ItakuExtractor):
|
||||
|
||||
class ItakuFollowersExtractor(ItakuExtractor):
|
||||
subcategory = "followers"
|
||||
pattern = rf"{USER_PATTERN}/followers"
|
||||
pattern = USER_PATTERN + r"/followers"
|
||||
example = "https://itaku.ee/profile/USER/followers"
|
||||
|
||||
def users(self):
|
||||
@@ -155,7 +155,7 @@ class ItakuFollowersExtractor(ItakuExtractor):
|
||||
class ItakuBookmarksExtractor(ItakuExtractor):
|
||||
"""Extractor for an itaku bookmarks folder"""
|
||||
subcategory = "bookmarks"
|
||||
pattern = rf"{USER_PATTERN}/bookmarks/(image|user)/(\d+)"
|
||||
pattern = USER_PATTERN + r"/bookmarks/(image|user)/(\d+)"
|
||||
example = "https://itaku.ee/profile/USER/bookmarks/image/12345"
|
||||
|
||||
def _init(self):
|
||||
@@ -176,7 +176,7 @@ class ItakuBookmarksExtractor(ItakuExtractor):
|
||||
|
||||
class ItakuUserExtractor(Dispatch, ItakuExtractor):
|
||||
"""Extractor for itaku user profiles"""
|
||||
pattern = rf"{USER_PATTERN}/?(?:$|\?|#)"
|
||||
pattern = USER_PATTERN + r"/?(?:$|\?|#)"
|
||||
example = "https://itaku.ee/profile/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -192,7 +192,7 @@ class ItakuUserExtractor(Dispatch, ItakuExtractor):
|
||||
|
||||
class ItakuImageExtractor(ItakuExtractor):
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/images/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/images/(\d+)"
|
||||
example = "https://itaku.ee/images/12345"
|
||||
|
||||
def images(self):
|
||||
@@ -205,7 +205,7 @@ class ItakuPostExtractor(ItakuExtractor):
|
||||
"{id}{title:? //}")
|
||||
filename_fmt = "{file[id]}{file[title]:? //}.{extension}"
|
||||
archive_fmt = "{id}_{file[id]}"
|
||||
pattern = rf"{BASE_PATTERN}/posts/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/posts/(\d+)"
|
||||
example = "https://itaku.ee/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -214,7 +214,7 @@ class ItakuPostExtractor(ItakuExtractor):
|
||||
|
||||
class ItakuSearchExtractor(ItakuExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/home/images/?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/home/images/?\?([^#]+)"
|
||||
example = "https://itaku.ee/home/images?tags=SEARCH"
|
||||
|
||||
def images(self):
|
||||
|
||||
@@ -30,7 +30,7 @@ class JschanThreadExtractor(JschanExtractor):
|
||||
"{threadId} {subject|nomarkup[:50]}")
|
||||
filename_fmt = "{postId}{num:?-//} {filename}.{extension}"
|
||||
archive_fmt = "{board}_{postId}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/thread/(\d+)\.html"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/thread/(\d+)\.html"
|
||||
example = "https://94chan.org/a/thread/12345.html"
|
||||
|
||||
def items(self):
|
||||
@@ -56,7 +56,7 @@ class JschanThreadExtractor(JschanExtractor):
|
||||
class JschanBoardExtractor(JschanExtractor):
|
||||
"""Extractor for jschan boards"""
|
||||
subcategory = "board"
|
||||
pattern = (rf"{BASE_PATTERN}/([^/?#]+)"
|
||||
pattern = (BASE_PATTERN + r"/([^/?#]+)"
|
||||
r"(?:/index\.html|/catalog\.html|/\d+\.html|/?$)")
|
||||
example = "https://94chan.org/a/"
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class KomikcastBase():
|
||||
|
||||
class KomikcastChapterExtractor(KomikcastBase, ChapterExtractor):
|
||||
"""Extractor for komikcast manga chapters"""
|
||||
pattern = rf"{BASE_PATTERN}(/chapter/[^/?#]+/)"
|
||||
pattern = BASE_PATTERN + r"(/chapter/[^/?#]+/)"
|
||||
example = "https://komikcast.li/chapter/TITLE/"
|
||||
|
||||
def metadata(self, page):
|
||||
@@ -64,7 +64,7 @@ class KomikcastChapterExtractor(KomikcastBase, ChapterExtractor):
|
||||
class KomikcastMangaExtractor(KomikcastBase, MangaExtractor):
|
||||
"""Extractor for komikcast manga"""
|
||||
chapterclass = KomikcastChapterExtractor
|
||||
pattern = rf"{BASE_PATTERN}(/(?:komik/)?[^/?#]+/?)$"
|
||||
pattern = BASE_PATTERN + r"(/(?:komik/)?[^/?#]+/?)$"
|
||||
example = "https://komikcast.li/komik/TITLE"
|
||||
|
||||
def chapters(self, page):
|
||||
|
||||
@@ -81,7 +81,7 @@ class LeakgalleryUserExtractor(LeakgalleryExtractor):
|
||||
class LeakgalleryTrendingExtractor(LeakgalleryExtractor):
|
||||
"""Extractor for trending posts on leakgallery.com"""
|
||||
subcategory = "trending"
|
||||
pattern = rf"{BASE_PATTERN}/trending-medias(?:/([\w-]+))?"
|
||||
pattern = BASE_PATTERN + r"/trending-medias(?:/([\w-]+))?"
|
||||
example = "https://leakgallery.com/trending-medias/Week"
|
||||
|
||||
def items(self):
|
||||
@@ -93,7 +93,7 @@ class LeakgalleryTrendingExtractor(LeakgalleryExtractor):
|
||||
class LeakgalleryMostlikedExtractor(LeakgalleryExtractor):
|
||||
"""Extractor for most liked posts on leakgallery.com"""
|
||||
subcategory = "mostliked"
|
||||
pattern = rf"{BASE_PATTERN}/most-liked"
|
||||
pattern = BASE_PATTERN + r"/most-liked"
|
||||
example = "https://leakgallery.com/most-liked"
|
||||
|
||||
def items(self):
|
||||
@@ -104,7 +104,7 @@ class LeakgalleryMostlikedExtractor(LeakgalleryExtractor):
|
||||
class LeakgalleryPostExtractor(LeakgalleryExtractor):
|
||||
"""Extractor for individual posts on leakgallery.com"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/(\d+)"
|
||||
example = "https://leakgallery.com/CREATOR/12345"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -31,7 +31,7 @@ class LensdumpBase():
|
||||
|
||||
class LensdumpAlbumExtractor(LensdumpBase, GalleryExtractor):
|
||||
subcategory = "album"
|
||||
pattern = rf"{BASE_PATTERN}/a/(\w+)(?:/?\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/a/(\w+)(?:/?\?([^#]+))?"
|
||||
example = "https://lensdump.com/a/ID"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -76,7 +76,7 @@ class LensdumpAlbumExtractor(LensdumpBase, GalleryExtractor):
|
||||
class LensdumpAlbumsExtractor(LensdumpBase, Extractor):
|
||||
"""Extractor for album list from lensdump.com"""
|
||||
subcategory = "albums"
|
||||
pattern = rf"{BASE_PATTERN}/(?![ai]/)([^/?#]+)(?:/?\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"/(?![ai]/)([^/?#]+)(?:/?\?([^#]+))?"
|
||||
example = "https://lensdump.com/USER"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -25,7 +25,7 @@ BASE_PATTERN = LolisafeExtractor.update({
|
||||
|
||||
class LolisafeAlbumExtractor(LolisafeExtractor):
|
||||
subcategory = "album"
|
||||
pattern = rf"{BASE_PATTERN}/a/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + "/a/([^/?#]+)"
|
||||
example = "https://xbunkr.com/a/ID"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -39,7 +39,7 @@ class LynxchanThreadExtractor(LynxchanExtractor):
|
||||
"{threadId} {subject|message[:50]}")
|
||||
filename_fmt = "{postId}{num:?-//} {filename}.{extension}"
|
||||
archive_fmt = "{boardUri}_{postId}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)/res/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)/res/(\d+)"
|
||||
example = "https://endchan.org/a/res/12345.html"
|
||||
|
||||
def items(self):
|
||||
@@ -63,7 +63,7 @@ class LynxchanThreadExtractor(LynxchanExtractor):
|
||||
class LynxchanBoardExtractor(LynxchanExtractor):
|
||||
"""Extractor for LynxChan boards"""
|
||||
subcategory = "board"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)(?:/index|/catalog|/\d+|/?$)"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)(?:/index|/catalog|/\d+|/?$)"
|
||||
example = "https://endchan.org/a/"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -18,8 +18,8 @@ class MangafoxChapterExtractor(ChapterExtractor):
|
||||
"""Extractor for manga chapters from fanfox.net"""
|
||||
category = "mangafox"
|
||||
root = "https://m.fanfox.net"
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"(/manga/[^/?#]+/((?:v([^/?#]+)/)?c(\d+)([^/?#]*)))")
|
||||
pattern = BASE_PATTERN + \
|
||||
r"(/manga/[^/?#]+/((?:v([^/?#]+)/)?c(\d+)([^/?#]*)))"
|
||||
example = "https://fanfox.net/manga/TITLE/v01/c001/1.html"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -62,7 +62,7 @@ class MangafoxMangaExtractor(MangaExtractor):
|
||||
category = "mangafox"
|
||||
root = "https://m.fanfox.net"
|
||||
chapterclass = MangafoxChapterExtractor
|
||||
pattern = rf"{BASE_PATTERN}(/manga/[^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"(/manga/[^/?#]+)/?$"
|
||||
example = "https://fanfox.net/manga/TITLE"
|
||||
|
||||
def chapters(self, page):
|
||||
|
||||
@@ -39,7 +39,7 @@ BASE_PATTERN = ManganeloExtractor.update({
|
||||
|
||||
class ManganeloChapterExtractor(ManganeloExtractor, ChapterExtractor):
|
||||
"""Extractor for manganelo manga chapters"""
|
||||
pattern = rf"{BASE_PATTERN}(/manga/[^/?#]+/chapter-[^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"(/manga/[^/?#]+/chapter-[^/?#]+)"
|
||||
example = "https://www.mangakakalot.gg/manga/MANGA_NAME/chapter-123"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -86,7 +86,7 @@ class ManganeloChapterExtractor(ManganeloExtractor, ChapterExtractor):
|
||||
class ManganeloMangaExtractor(ManganeloExtractor, MangaExtractor):
|
||||
"""Extractor for manganelo manga"""
|
||||
chapterclass = ManganeloChapterExtractor
|
||||
pattern = rf"{BASE_PATTERN}(/manga/[^/?#]+)$"
|
||||
pattern = BASE_PATTERN + r"(/manga/[^/?#]+)$"
|
||||
example = "https://www.mangakakalot.gg/manga/MANGA_NAME"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -70,8 +70,8 @@ class MangaparkBase():
|
||||
|
||||
class MangaparkChapterExtractor(MangaparkBase, ChapterExtractor):
|
||||
"""Extractor for manga-chapters from mangapark.net"""
|
||||
pattern = (rf"{BASE_PATTERN}/"
|
||||
rf"(?:title/[^/?#]+/|comic/\d+/[^/?#]+/[^/?#]+-i)(\d+)")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/(?:title/[^/?#]+/|comic/\d+/[^/?#]+/[^/?#]+-i)(\d+)")
|
||||
example = "https://mangapark.net/title/MANGA/12345-en-ch.01"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -111,7 +111,7 @@ class MangaparkChapterExtractor(MangaparkBase, ChapterExtractor):
|
||||
class MangaparkMangaExtractor(MangaparkBase, Extractor):
|
||||
"""Extractor for manga from mangapark.net"""
|
||||
subcategory = "manga"
|
||||
pattern = rf"{BASE_PATTERN}/(?:title|comic)/(\d+)(?:[/-][^/?#]*)?/?$"
|
||||
pattern = BASE_PATTERN + r"/(?:title|comic)/(\d+)(?:[/-][^/?#]*)?/?$"
|
||||
example = "https://mangapark.net/title/12345-MANGA"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -118,7 +118,7 @@ BASE_PATTERN = MastodonExtractor.update({
|
||||
class MastodonUserExtractor(MastodonExtractor):
|
||||
"""Extractor for all images of an account/user"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?:@|users/)([^/?#]+)(?:/media)?/?$"
|
||||
pattern = BASE_PATTERN + r"/(?:@|users/)([^/?#]+)(?:/media)?/?$"
|
||||
example = "https://mastodon.social/@USER"
|
||||
|
||||
def statuses(self):
|
||||
@@ -138,7 +138,7 @@ class MastodonUserExtractor(MastodonExtractor):
|
||||
class MastodonBookmarkExtractor(MastodonExtractor):
|
||||
"""Extractor for mastodon bookmarks"""
|
||||
subcategory = "bookmark"
|
||||
pattern = rf"{BASE_PATTERN}/bookmarks"
|
||||
pattern = BASE_PATTERN + r"/bookmarks"
|
||||
example = "https://mastodon.social/bookmarks"
|
||||
|
||||
def statuses(self):
|
||||
@@ -148,7 +148,7 @@ class MastodonBookmarkExtractor(MastodonExtractor):
|
||||
class MastodonFavoriteExtractor(MastodonExtractor):
|
||||
"""Extractor for mastodon favorites"""
|
||||
subcategory = "favorite"
|
||||
pattern = rf"{BASE_PATTERN}/favourites"
|
||||
pattern = BASE_PATTERN + r"/favourites"
|
||||
example = "https://mastodon.social/favourites"
|
||||
|
||||
def statuses(self):
|
||||
@@ -158,7 +158,7 @@ class MastodonFavoriteExtractor(MastodonExtractor):
|
||||
class MastodonListExtractor(MastodonExtractor):
|
||||
"""Extractor for mastodon lists"""
|
||||
subcategory = "list"
|
||||
pattern = rf"{BASE_PATTERN}/lists/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/lists/(\w+)"
|
||||
example = "https://mastodon.social/lists/12345"
|
||||
|
||||
def statuses(self):
|
||||
@@ -168,7 +168,7 @@ class MastodonListExtractor(MastodonExtractor):
|
||||
class MastodonHashtagExtractor(MastodonExtractor):
|
||||
"""Extractor for mastodon hashtags"""
|
||||
subcategory = "hashtag"
|
||||
pattern = rf"{BASE_PATTERN}/tags/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/tags/(\w+)"
|
||||
example = "https://mastodon.social/tags/NAME"
|
||||
|
||||
def statuses(self):
|
||||
@@ -178,7 +178,7 @@ class MastodonHashtagExtractor(MastodonExtractor):
|
||||
class MastodonFollowingExtractor(MastodonExtractor):
|
||||
"""Extractor for followed mastodon users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/(?:@|users/)([^/?#]+)/following"
|
||||
pattern = BASE_PATTERN + r"/(?:@|users/)([^/?#]+)/following"
|
||||
example = "https://mastodon.social/@USER/following"
|
||||
|
||||
def items(self):
|
||||
@@ -193,7 +193,7 @@ class MastodonFollowingExtractor(MastodonExtractor):
|
||||
class MastodonStatusExtractor(MastodonExtractor):
|
||||
"""Extractor for images from a status"""
|
||||
subcategory = "status"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:@[^/?#]+|(?:users/[^/?#]+/)?"
|
||||
pattern = (BASE_PATTERN + r"/(?:@[^/?#]+|(?:users/[^/?#]+/)?"
|
||||
r"(?:statuses|notice|objects()))/(?!following)([^/?#]+)")
|
||||
example = "https://mastodon.social/@USER/12345"
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ BASE_PATTERN = MisskeyExtractor.update({
|
||||
class MisskeyUserExtractor(Dispatch, MisskeyExtractor):
|
||||
"""Extractor for all images of a Misskey user"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/?$"
|
||||
example = "https://misskey.io/@USER"
|
||||
|
||||
def items(self):
|
||||
@@ -118,7 +118,7 @@ class MisskeyUserExtractor(Dispatch, MisskeyExtractor):
|
||||
class MisskeyNotesExtractor(MisskeyExtractor):
|
||||
"""Extractor for a Misskey user's notes"""
|
||||
subcategory = "notes"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/notes"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/notes"
|
||||
example = "https://misskey.io/@USER/notes"
|
||||
|
||||
def notes(self):
|
||||
@@ -129,7 +129,7 @@ class MisskeyNotesExtractor(MisskeyExtractor):
|
||||
class MisskeyInfoExtractor(MisskeyExtractor):
|
||||
"""Extractor for a Misskey user's profile data"""
|
||||
subcategory = "info"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/info"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/info"
|
||||
example = "https://misskey.io/@USER/info"
|
||||
|
||||
def items(self):
|
||||
@@ -140,7 +140,7 @@ class MisskeyInfoExtractor(MisskeyExtractor):
|
||||
class MisskeyAvatarExtractor(MisskeyExtractor):
|
||||
"""Extractor for a Misskey user's avatar"""
|
||||
subcategory = "avatar"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/avatar"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/avatar"
|
||||
example = "https://misskey.io/@USER/avatar"
|
||||
|
||||
def notes(self):
|
||||
@@ -152,7 +152,7 @@ class MisskeyAvatarExtractor(MisskeyExtractor):
|
||||
class MisskeyBackgroundExtractor(MisskeyExtractor):
|
||||
"""Extractor for a Misskey user's banner image"""
|
||||
subcategory = "background"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/ba(?:nner|ckground)"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/ba(?:nner|ckground)"
|
||||
example = "https://misskey.io/@USER/banner"
|
||||
|
||||
def notes(self):
|
||||
@@ -164,7 +164,7 @@ class MisskeyBackgroundExtractor(MisskeyExtractor):
|
||||
class MisskeyFollowingExtractor(MisskeyExtractor):
|
||||
"""Extractor for followed Misskey users"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/@([^/?#]+)/following"
|
||||
pattern = BASE_PATTERN + r"/@([^/?#]+)/following"
|
||||
example = "https://misskey.io/@USER/following"
|
||||
|
||||
def items(self):
|
||||
@@ -181,7 +181,7 @@ class MisskeyFollowingExtractor(MisskeyExtractor):
|
||||
class MisskeyNoteExtractor(MisskeyExtractor):
|
||||
"""Extractor for images from a Note"""
|
||||
subcategory = "note"
|
||||
pattern = rf"{BASE_PATTERN}/notes/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/notes/(\w+)"
|
||||
example = "https://misskey.io/notes/98765"
|
||||
|
||||
def notes(self):
|
||||
@@ -191,7 +191,7 @@ class MisskeyNoteExtractor(MisskeyExtractor):
|
||||
class MisskeyFavoriteExtractor(MisskeyExtractor):
|
||||
"""Extractor for favorited notes"""
|
||||
subcategory = "favorite"
|
||||
pattern = rf"{BASE_PATTERN}/(?:my|api/i)/favorites"
|
||||
pattern = BASE_PATTERN + r"/(?:my|api/i)/favorites"
|
||||
example = "https://misskey.io/my/favorites"
|
||||
|
||||
def notes(self):
|
||||
|
||||
@@ -92,7 +92,7 @@ class MoebooruTagExtractor(MoebooruExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post\?(?:[^&#]*&)*tags=([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"/post\?(?:[^&#]*&)*tags=([^&#]*)"
|
||||
example = "https://yande.re/post?tags=TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -111,7 +111,7 @@ class MoebooruPoolExtractor(MoebooruExtractor):
|
||||
subcategory = "pool"
|
||||
directory_fmt = ("{category}", "pool", "{pool}")
|
||||
archive_fmt = "p_{pool}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/pool/show/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/pool/show/(\d+)"
|
||||
example = "https://yande.re/pool/show/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -135,7 +135,7 @@ class MoebooruPoolExtractor(MoebooruExtractor):
|
||||
class MoebooruPostExtractor(MoebooruExtractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post/show/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post/show/(\d+)"
|
||||
example = "https://yande.re/post/show/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -147,8 +147,8 @@ class MoebooruPopularExtractor(MoebooruExtractor):
|
||||
subcategory = "popular"
|
||||
directory_fmt = ("{category}", "popular", "{scale}", "{date}")
|
||||
archive_fmt = "P_{scale[0]}_{date}_{id}"
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"/post/popular_(by_(?:day|week|month)|recent)(?:\?([^#]*))?")
|
||||
pattern = BASE_PATTERN + \
|
||||
r"/post/popular_(by_(?:day|week|month)|recent)(?:\?([^#]*))?"
|
||||
example = "https://yande.re/post/popular_by_month?year=YYYY&month=MM"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -152,9 +152,9 @@ class MotherlessExtractor(Extractor):
|
||||
class MotherlessMediaExtractor(MotherlessExtractor):
|
||||
"""Extractor for a single image/video from motherless.com"""
|
||||
subcategory = "media"
|
||||
pattern = (rf"{BASE_PATTERN}/("
|
||||
rf"(?:g/[^/?#]+/|G[IV]?[A-Z0-9]+/)?"
|
||||
rf"(?!G)[A-Z0-9]+)")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"/((?:g/[^/?#]+/|G[IV]?[A-Z0-9]+/)?"
|
||||
r"(?!G)[A-Z0-9]+)")
|
||||
example = "https://motherless.com/ABC123"
|
||||
|
||||
def items(self):
|
||||
@@ -170,7 +170,7 @@ class MotherlessGalleryExtractor(MotherlessExtractor):
|
||||
directory_fmt = ("{category}", "{uploader}",
|
||||
"{gallery_id} {gallery_title}")
|
||||
archive_fmt = "{gallery_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/G([IVG])?([A-Z0-9]+)/?$"
|
||||
pattern = BASE_PATTERN + "/G([IVG])?([A-Z0-9]+)/?$"
|
||||
example = "https://motherless.com/GABC123"
|
||||
|
||||
def items(self):
|
||||
@@ -206,7 +206,7 @@ class MotherlessGroupExtractor(MotherlessExtractor):
|
||||
directory_fmt = ("{category}", "{uploader}",
|
||||
"{group_id} {group_title}")
|
||||
archive_fmt = "{group_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/g([iv]?)/?([a-z0-9_]+)/?$"
|
||||
pattern = BASE_PATTERN + "/g([iv]?)/?([a-z0-9_]+)/?$"
|
||||
example = "https://motherless.com/g/abc123"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -27,7 +27,7 @@ class NaverWebtoonEpisodeExtractor(NaverWebtoonBase, GalleryExtractor):
|
||||
directory_fmt = ("{category}", "{comic}")
|
||||
filename_fmt = "{episode:>03}-{num:>02}.{extension}"
|
||||
archive_fmt = "{title_id}_{episode}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/detail(?:\.nhn)?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/detail(?:\.nhn)?\?([^#]+)"
|
||||
example = "https://comic.naver.com/webtoon/detail?titleId=12345&no=1"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -66,7 +66,7 @@ class NaverWebtoonEpisodeExtractor(NaverWebtoonBase, GalleryExtractor):
|
||||
class NaverWebtoonComicExtractor(NaverWebtoonBase, Extractor):
|
||||
subcategory = "comic"
|
||||
categorytransfer = True
|
||||
pattern = rf"{BASE_PATTERN}/list(?:\.nhn)?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/list(?:\.nhn)?\?([^#]+)"
|
||||
example = "https://comic.naver.com/webtoon/list?titleId=12345"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -12,7 +12,7 @@ from .common import Extractor, Message
|
||||
from .. import text
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?nekohouse\.su"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/([^/?#]+)/user/([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/([^/?#]+)/user/([^/?#]+)"
|
||||
|
||||
|
||||
class NekohouseExtractor(Extractor):
|
||||
@@ -27,7 +27,7 @@ class NekohousePostExtractor(NekohouseExtractor):
|
||||
"{post_id} {date} {title[b:230]}")
|
||||
filename_fmt = "{num:>02} {id|filename}.{extension}"
|
||||
archive_fmt = "{service}_{user_id}_{post_id}_{hash}"
|
||||
pattern = rf"{USER_PATTERN}/post/([^/?#]+)"
|
||||
pattern = USER_PATTERN + r"/post/([^/?#]+)"
|
||||
example = "https://nekohouse.su/SERVICE/user/12345/post/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -98,7 +98,7 @@ class NekohousePostExtractor(NekohouseExtractor):
|
||||
|
||||
class NekohouseUserExtractor(NekohouseExtractor):
|
||||
subcategory = "user"
|
||||
pattern = rf"{USER_PATTERN}/?(?:\?([^#]+))?(?:$|\?|#)"
|
||||
pattern = USER_PATTERN + r"/?(?:\?([^#]+))?(?:$|\?|#)"
|
||||
example = "https://nekohouse.su/SERVICE/user/12345"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -412,7 +412,7 @@ class NewgroundsImageExtractor(NewgroundsExtractor):
|
||||
class NewgroundsMediaExtractor(NewgroundsExtractor):
|
||||
"""Extractor for a media file from newgrounds.com"""
|
||||
subcategory = "media"
|
||||
pattern = rf"{BASE_PATTERN}(/(?:portal/view|audio/listen)/\d+)"
|
||||
pattern = BASE_PATTERN + r"(/(?:portal/view|audio/listen)/\d+)"
|
||||
example = "https://www.newgrounds.com/portal/view/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -427,34 +427,34 @@ class NewgroundsMediaExtractor(NewgroundsExtractor):
|
||||
class NewgroundsArtExtractor(NewgroundsExtractor):
|
||||
"""Extractor for all images of a newgrounds user"""
|
||||
subcategory = _path = "art"
|
||||
pattern = rf"{USER_PATTERN}/art(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
pattern = USER_PATTERN + r"/art(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
example = "https://USER.newgrounds.com/art"
|
||||
|
||||
|
||||
class NewgroundsAudioExtractor(NewgroundsExtractor):
|
||||
"""Extractor for all audio submissions of a newgrounds user"""
|
||||
subcategory = _path = "audio"
|
||||
pattern = rf"{USER_PATTERN}/audio(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
pattern = USER_PATTERN + r"/audio(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
example = "https://USER.newgrounds.com/audio"
|
||||
|
||||
|
||||
class NewgroundsMoviesExtractor(NewgroundsExtractor):
|
||||
"""Extractor for all movies of a newgrounds user"""
|
||||
subcategory = _path = "movies"
|
||||
pattern = rf"{USER_PATTERN}/movies(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
pattern = USER_PATTERN + r"/movies(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
example = "https://USER.newgrounds.com/movies"
|
||||
|
||||
|
||||
class NewgroundsGamesExtractor(NewgroundsExtractor):
|
||||
"""Extractor for a newgrounds user's games"""
|
||||
subcategory = _path = "games"
|
||||
pattern = rf"{USER_PATTERN}/games(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
pattern = USER_PATTERN + r"/games(?:(?:/page/|/?\?page=)(\d+))?/?$"
|
||||
example = "https://USER.newgrounds.com/games"
|
||||
|
||||
|
||||
class NewgroundsUserExtractor(Dispatch, NewgroundsExtractor):
|
||||
"""Extractor for a newgrounds user profile"""
|
||||
pattern = rf"{USER_PATTERN}/?$"
|
||||
pattern = USER_PATTERN + r"/?$"
|
||||
example = "https://USER.newgrounds.com"
|
||||
|
||||
def items(self):
|
||||
@@ -471,7 +471,7 @@ class NewgroundsFavoriteExtractor(NewgroundsExtractor):
|
||||
"""Extractor for posts favorited by a newgrounds user"""
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "{user}", "Favorites")
|
||||
pattern = (rf"{USER_PATTERN}/favorites(?!/following)(?:/(art|audio|movies)"
|
||||
pattern = (USER_PATTERN + r"/favorites(?!/following)(?:/(art|audio|movies)"
|
||||
r"(?:(?:/page/|/?\?page=)(\d+))?)?")
|
||||
example = "https://USER.newgrounds.com/favorites"
|
||||
|
||||
@@ -517,7 +517,7 @@ class NewgroundsFavoriteExtractor(NewgroundsExtractor):
|
||||
class NewgroundsFollowingExtractor(NewgroundsFavoriteExtractor):
|
||||
"""Extractor for a newgrounds user's favorited users"""
|
||||
subcategory = "following"
|
||||
pattern = (rf"{USER_PATTERN}/favorites/(following)"
|
||||
pattern = (USER_PATTERN + r"/favorites/(following)"
|
||||
r"(?:(?:/page/|/?\?page=)(\d+))?")
|
||||
|
||||
example = "https://USER.newgrounds.com/favorites/following"
|
||||
@@ -539,7 +539,7 @@ class NewgroundsSearchExtractor(NewgroundsExtractor):
|
||||
"""Extractor for newgrounds.com search reesults"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "search", "{search_tags}")
|
||||
pattern = rf"{BASE_PATTERN}/search/conduct/([^/?#]+)/?\?([^#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/conduct/([^/?#]+)/?\?([^#]+)"
|
||||
example = "https://www.newgrounds.com/search/conduct/art?terms=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -178,7 +178,7 @@ BASE_PATTERN = NijieExtractor.update({
|
||||
|
||||
class NijieUserExtractor(Dispatch, NijieExtractor):
|
||||
"""Extractor for nijie user profiles"""
|
||||
pattern = rf"{BASE_PATTERN}/members\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/members\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/members.php?id=12345"
|
||||
|
||||
def items(self):
|
||||
@@ -194,7 +194,7 @@ class NijieUserExtractor(Dispatch, NijieExtractor):
|
||||
class NijieIllustrationExtractor(NijieExtractor):
|
||||
"""Extractor for all illustrations of a nijie-user"""
|
||||
subcategory = "illustration"
|
||||
pattern = rf"{BASE_PATTERN}/members_illust\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/members_illust\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/members_illust.php?id=12345"
|
||||
|
||||
def image_ids(self):
|
||||
@@ -204,7 +204,7 @@ class NijieIllustrationExtractor(NijieExtractor):
|
||||
class NijieDoujinExtractor(NijieExtractor):
|
||||
"""Extractor for doujin entries of a nijie user"""
|
||||
subcategory = "doujin"
|
||||
pattern = rf"{BASE_PATTERN}/members_dojin\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/members_dojin\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/members_dojin.php?id=12345"
|
||||
|
||||
def image_ids(self):
|
||||
@@ -216,7 +216,7 @@ class NijieFavoriteExtractor(NijieExtractor):
|
||||
subcategory = "favorite"
|
||||
directory_fmt = ("{category}", "bookmarks", "{user_id}")
|
||||
archive_fmt = "f_{user_id}_{image_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/user_like_illust_view\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/user_like_illust_view\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/user_like_illust_view.php?id=12345"
|
||||
|
||||
def image_ids(self):
|
||||
@@ -234,7 +234,7 @@ class NijieNuitaExtractor(NijieExtractor):
|
||||
subcategory = "nuita"
|
||||
directory_fmt = ("{category}", "nuita", "{user_id}")
|
||||
archive_fmt = "n_{user_id}_{image_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/history_nuita\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/history_nuita\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/history_nuita.php?id=12345"
|
||||
|
||||
def image_ids(self):
|
||||
@@ -253,7 +253,7 @@ class NijieNuitaExtractor(NijieExtractor):
|
||||
class NijieFeedExtractor(NijieExtractor):
|
||||
"""Extractor for nijie liked user feed"""
|
||||
subcategory = "feed"
|
||||
pattern = rf"{BASE_PATTERN}/like_user_view\.php"
|
||||
pattern = BASE_PATTERN + r"/like_user_view\.php"
|
||||
example = "https://nijie.info/like_user_view.php"
|
||||
|
||||
def image_ids(self):
|
||||
@@ -266,7 +266,7 @@ class NijieFeedExtractor(NijieExtractor):
|
||||
class NijieFollowedExtractor(NijieExtractor):
|
||||
"""Extractor for followed nijie users"""
|
||||
subcategory = "followed"
|
||||
pattern = rf"{BASE_PATTERN}/like_my\.php"
|
||||
pattern = BASE_PATTERN + r"/like_my\.php"
|
||||
example = "https://nijie.info/like_my.php"
|
||||
|
||||
def items(self):
|
||||
@@ -292,7 +292,7 @@ class NijieFollowedExtractor(NijieExtractor):
|
||||
class NijieImageExtractor(NijieExtractor):
|
||||
"""Extractor for a nijie work/image"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/view(?:_popup)?\.php\?id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/view(?:_popup)?\.php\?id=(\d+)"
|
||||
example = "https://nijie.info/view.php?id=12345"
|
||||
|
||||
def image_ids(self):
|
||||
|
||||
@@ -229,12 +229,12 @@ class NitterExtractor(BaseExtractor):
|
||||
BASE_PATTERN = NitterExtractor.update({
|
||||
})
|
||||
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/(i(?:/user/|d:)(\d+)|[^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/(i(?:/user/|d:)(\d+)|[^/?#]+)"
|
||||
|
||||
|
||||
class NitterTweetsExtractor(NitterExtractor):
|
||||
subcategory = "tweets"
|
||||
pattern = rf"{USER_PATTERN}(?:/tweets)?(?:$|\?|#)"
|
||||
pattern = USER_PATTERN + r"(?:/tweets)?(?:$|\?|#)"
|
||||
example = "https://nitter.net/USER"
|
||||
|
||||
def tweets(self):
|
||||
@@ -243,7 +243,7 @@ class NitterTweetsExtractor(NitterExtractor):
|
||||
|
||||
class NitterRepliesExtractor(NitterExtractor):
|
||||
subcategory = "replies"
|
||||
pattern = rf"{USER_PATTERN}/with_replies"
|
||||
pattern = USER_PATTERN + r"/with_replies"
|
||||
example = "https://nitter.net/USER/with_replies"
|
||||
|
||||
def tweets(self):
|
||||
@@ -252,7 +252,7 @@ class NitterRepliesExtractor(NitterExtractor):
|
||||
|
||||
class NitterMediaExtractor(NitterExtractor):
|
||||
subcategory = "media"
|
||||
pattern = rf"{USER_PATTERN}/media"
|
||||
pattern = USER_PATTERN + r"/media"
|
||||
example = "https://nitter.net/USER/media"
|
||||
|
||||
def tweets(self):
|
||||
@@ -261,7 +261,7 @@ class NitterMediaExtractor(NitterExtractor):
|
||||
|
||||
class NitterSearchExtractor(NitterExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{USER_PATTERN}/search"
|
||||
pattern = USER_PATTERN + r"/search"
|
||||
example = "https://nitter.net/USER/search"
|
||||
|
||||
def tweets(self):
|
||||
@@ -274,7 +274,7 @@ class NitterTweetExtractor(NitterExtractor):
|
||||
directory_fmt = ("{category}", "{user[name]}")
|
||||
filename_fmt = "{tweet_id}_{num}.{extension}"
|
||||
archive_fmt = "{tweet_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/(i/web|[^/?#]+)/status/(\d+())"
|
||||
pattern = BASE_PATTERN + r"/(i/web|[^/?#]+)/status/(\d+())"
|
||||
example = "https://nitter.net/USER/status/12345"
|
||||
|
||||
def tweets(self):
|
||||
|
||||
@@ -21,7 +21,7 @@ class NudostarExtractor(GalleryExtractor):
|
||||
class NudostarModelExtractor(NudostarExtractor):
|
||||
"""Extractor for NudoStar models"""
|
||||
subcategory = "model"
|
||||
pattern = rf"{BASE_PATTERN}(/models/([^/?#]+)/?)$"
|
||||
pattern = BASE_PATTERN + r"(/models/([^/?#]+)/?)$"
|
||||
example = "https://nudostar.tv/models/MODEL/"
|
||||
|
||||
def metadata(self, page):
|
||||
@@ -53,7 +53,7 @@ class NudostarModelExtractor(NudostarExtractor):
|
||||
class NudostarImageExtractor(NudostarExtractor):
|
||||
"""Extractor for NudoStar images"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}(/models/([^/?#]+)/(\d+)/)"
|
||||
pattern = BASE_PATTERN + r"(/models/([^/?#]+)/(\d+)/)"
|
||||
example = "https://nudostar.tv/models/MODEL/123/"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -62,7 +62,7 @@ class PexelsCollectionExtractor(PexelsExtractor):
|
||||
"""Extractor for a pexels.com collection"""
|
||||
subcategory = "collection"
|
||||
directory_fmt = ("{category}", "Collections", "{collection}")
|
||||
pattern = rf"{BASE_PATTERN}/collections/((?:[^/?#]*-)?(\w+))"
|
||||
pattern = BASE_PATTERN + r"/collections/((?:[^/?#]*-)?(\w+))"
|
||||
example = "https://www.pexels.com/collections/SLUG-a1b2c3/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -77,7 +77,7 @@ class PexelsSearchExtractor(PexelsExtractor):
|
||||
"""Extractor for pexels.com search results"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "Searches", "{search_tags}")
|
||||
pattern = rf"{BASE_PATTERN}/search/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/([^/?#]+)"
|
||||
example = "https://www.pexels.com/search/QUERY/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -91,7 +91,7 @@ class PexelsUserExtractor(PexelsExtractor):
|
||||
"""Extractor for pexels.com user galleries"""
|
||||
subcategory = "user"
|
||||
directory_fmt = ("{category}", "@{user[slug]}")
|
||||
pattern = rf"{BASE_PATTERN}/(@(?:(?:[^/?#]*-)?(\d+)|[^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"/(@(?:(?:[^/?#]*-)?(\d+)|[^/?#]+))"
|
||||
example = "https://www.pexels.com/@USER-12345/"
|
||||
|
||||
def posts(self):
|
||||
@@ -100,7 +100,7 @@ class PexelsUserExtractor(PexelsExtractor):
|
||||
|
||||
class PexelsImageExtractor(PexelsExtractor):
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/photo/((?:[^/?#]*-)?\d+)"
|
||||
pattern = BASE_PATTERN + r"/photo/((?:[^/?#]*-)?\d+)"
|
||||
example = "https://www.pexels.com/photo/SLUG-12345/"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -61,7 +61,7 @@ BASE_PATTERN = PhilomenaExtractor.update({
|
||||
class PhilomenaPostExtractor(PhilomenaExtractor):
|
||||
"""Extractor for single posts on a Philomena booru"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/(?:images/)?(\d+)"
|
||||
pattern = BASE_PATTERN + r"/(?:images/)?(\d+)"
|
||||
example = "https://derpibooru.org/images/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -72,7 +72,7 @@ class PhilomenaSearchExtractor(PhilomenaExtractor):
|
||||
"""Extractor for Philomena search results"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
pattern = rf"{BASE_PATTERN}/(?:search/?\?([^#]+)|tags/([^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"/(?:search/?\?([^#]+)|tags/([^/?#]+))"
|
||||
example = "https://derpibooru.org/search?q=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -106,7 +106,7 @@ class PhilomenaGalleryExtractor(PhilomenaExtractor):
|
||||
subcategory = "gallery"
|
||||
directory_fmt = ("{category}", "galleries",
|
||||
"{gallery[id]} {gallery[title]}")
|
||||
pattern = rf"{BASE_PATTERN}/galleries/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/galleries/(\d+)"
|
||||
example = "https://derpibooru.org/galleries/12345"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -18,7 +18,7 @@ class PhotovogueUserExtractor(Extractor):
|
||||
directory_fmt = ("{category}", "{photographer[id]} {photographer[name]}")
|
||||
filename_fmt = "{id} {title}.{extension}"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/photographers/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/photographers/(\d+)"
|
||||
example = "https://www.vogue.com/photovogue/photographers/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -24,7 +24,7 @@ class PictoaExtractor(Extractor):
|
||||
class PictoaImageExtractor(PictoaExtractor):
|
||||
"""Extractor for single images from pictoa.com"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/albums/(?:[\w-]+-)?(\d+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/albums/(?:[\w-]+-)?(\d+)/(\d+)"
|
||||
example = "https://www.pictoa.com/albums/NAME-12345/12345.html"
|
||||
|
||||
def items(self):
|
||||
@@ -50,7 +50,7 @@ class PictoaImageExtractor(PictoaExtractor):
|
||||
class PictoaAlbumExtractor(PictoaExtractor):
|
||||
"""Extractor for image albums from pictoa.com"""
|
||||
subcategory = "album"
|
||||
pattern = rf"{BASE_PATTERN}/albums/(?:[\w-]+-)?(\d+).html"
|
||||
pattern = BASE_PATTERN + r"/albums/(?:[\w-]+-)?(\d+).html"
|
||||
example = "https://www.pictoa.com/albums/NAME-12345.html"
|
||||
|
||||
def items(self):
|
||||
|
||||
@@ -66,7 +66,7 @@ class PiczelExtractor(Extractor):
|
||||
class PiczelUserExtractor(PiczelExtractor):
|
||||
"""Extractor for all images from a user's gallery"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/([^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"/gallery/([^/?#]+)/?$"
|
||||
example = "https://piczel.tv/gallery/USER"
|
||||
|
||||
def posts(self):
|
||||
@@ -79,7 +79,7 @@ class PiczelFolderExtractor(PiczelExtractor):
|
||||
subcategory = "folder"
|
||||
directory_fmt = ("{category}", "{user[username]}", "{folder[name]}")
|
||||
archive_fmt = "f{folder[id]}_{id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/(?!image/)[^/?#]+/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/gallery/(?!image/)[^/?#]+/(\d+)"
|
||||
example = "https://piczel.tv/gallery/USER/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -90,7 +90,7 @@ class PiczelFolderExtractor(PiczelExtractor):
|
||||
class PiczelImageExtractor(PiczelExtractor):
|
||||
"""Extractor for individual images"""
|
||||
subcategory = "image"
|
||||
pattern = rf"{BASE_PATTERN}/gallery/image/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/gallery/image/(\d+)"
|
||||
example = "https://piczel.tv/gallery/image/12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -119,7 +119,7 @@ class PillowfortExtractor(Extractor):
|
||||
class PillowfortPostExtractor(PillowfortExtractor):
|
||||
"""Extractor for a single pillowfort post"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/posts/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/posts/(\d+)"
|
||||
example = "https://www.pillowfort.social/posts/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -130,7 +130,7 @@ class PillowfortPostExtractor(PillowfortExtractor):
|
||||
class PillowfortUserExtractor(PillowfortExtractor):
|
||||
"""Extractor for all posts of a pillowfort user"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?!posts/)([^/?#]+(?:/tagged/[^/?#]+)?)"
|
||||
pattern = BASE_PATTERN + r"/(?!posts/)([^/?#]+(?:/tagged/[^/?#]+)?)"
|
||||
example = "https://www.pillowfort.social/USER"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -207,7 +207,7 @@ class PinterestExtractor(Extractor):
|
||||
class PinterestUserExtractor(PinterestExtractor):
|
||||
"""Extractor for a user's boards"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)(?:/_saved)?/?$"
|
||||
pattern = BASE_PATTERN + r"/(?!pin/)([^/?#]+)(?:/_saved)?/?$"
|
||||
example = "https://www.pinterest.com/USER/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -225,7 +225,7 @@ class PinterestAllpinsExtractor(PinterestExtractor):
|
||||
"""Extractor for a user's 'All Pins' feed"""
|
||||
subcategory = "allpins"
|
||||
directory_fmt = ("{category}", "{user}")
|
||||
pattern = rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)/pins/?$"
|
||||
pattern = BASE_PATTERN + r"/(?!pin/)([^/?#]+)/pins/?$"
|
||||
example = "https://www.pinterest.com/USER/pins/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -243,7 +243,7 @@ class PinterestCreatedExtractor(PinterestExtractor):
|
||||
"""Extractor for a user's created pins"""
|
||||
subcategory = "created"
|
||||
directory_fmt = ("{category}", "{user}")
|
||||
pattern = rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)/_created/?$"
|
||||
pattern = BASE_PATTERN + r"/(?!pin/)([^/?#]+)/_created/?$"
|
||||
example = "https://www.pinterest.com/USER/_created/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -263,7 +263,7 @@ class PinterestSectionExtractor(PinterestExtractor):
|
||||
directory_fmt = ("{category}", "{board[owner][username]}",
|
||||
"{board[name]}", "{section[title]}")
|
||||
archive_fmt = "{board[id]}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)/([^/?#]+)/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?!pin/)([^/?#]+)/([^/?#]+)/([^/?#]+)"
|
||||
example = "https://www.pinterest.com/USER/BOARD/SECTION"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -291,7 +291,7 @@ class PinterestSearchExtractor(PinterestExtractor):
|
||||
"""Extractor for Pinterest search results"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "Search", "{search}")
|
||||
pattern = rf"{BASE_PATTERN}/search/pins/?\?q=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/search/pins/?\?q=([^&#]+)"
|
||||
example = "https://www.pinterest.com/search/pins/?q=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -308,7 +308,7 @@ class PinterestSearchExtractor(PinterestExtractor):
|
||||
class PinterestPinExtractor(PinterestExtractor):
|
||||
"""Extractor for images from a single pin from pinterest.com"""
|
||||
subcategory = "pin"
|
||||
pattern = rf"{BASE_PATTERN}/pin/([^/?#]+)(?!.*#related$)"
|
||||
pattern = BASE_PATTERN + r"/pin/([^/?#]+)(?!.*#related$)"
|
||||
example = "https://www.pinterest.com/pin/12345/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -329,7 +329,7 @@ class PinterestBoardExtractor(PinterestExtractor):
|
||||
subcategory = "board"
|
||||
directory_fmt = ("{category}", "{board[owner][username]}", "{board[name]}")
|
||||
archive_fmt = "{board[id]}_{id}"
|
||||
pattern = (rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)"
|
||||
pattern = (BASE_PATTERN + r"/(?!pin/)([^/?#]+)"
|
||||
r"/([^/?#]+)/?(?!.*#related$)")
|
||||
example = "https://www.pinterest.com/USER/BOARD/"
|
||||
|
||||
@@ -361,7 +361,7 @@ class PinterestRelatedPinExtractor(PinterestPinExtractor):
|
||||
"""Extractor for related pins of another pin from pinterest.com"""
|
||||
subcategory = "related-pin"
|
||||
directory_fmt = ("{category}", "related {original_pin[id]}")
|
||||
pattern = rf"{BASE_PATTERN}/pin/([^/?#]+).*#related$"
|
||||
pattern = BASE_PATTERN + r"/pin/([^/?#]+).*#related$"
|
||||
example = "https://www.pinterest.com/pin/12345/#related"
|
||||
|
||||
def metadata(self):
|
||||
@@ -376,7 +376,7 @@ class PinterestRelatedBoardExtractor(PinterestBoardExtractor):
|
||||
subcategory = "related-board"
|
||||
directory_fmt = ("{category}", "{board[owner][username]}",
|
||||
"{board[name]}", "related")
|
||||
pattern = rf"{BASE_PATTERN}/(?!pin/)([^/?#]+)/([^/?#]+)/?#related$"
|
||||
pattern = BASE_PATTERN + r"/(?!pin/)([^/?#]+)/([^/?#]+)/?#related$"
|
||||
example = "https://www.pinterest.com/USER/BOARD/#related"
|
||||
|
||||
def pins(self):
|
||||
|
||||
@@ -29,7 +29,7 @@ class PixeldrainFileExtractor(PixeldrainExtractor):
|
||||
"""Extractor for pixeldrain files"""
|
||||
subcategory = "file"
|
||||
filename_fmt = "{filename[:230]} ({id}).{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:u|api/file)/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/(?:u|api/file)/(\w+)"
|
||||
example = "https://pixeldrain.com/u/abcdefgh"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -54,7 +54,7 @@ class PixeldrainAlbumExtractor(PixeldrainExtractor):
|
||||
directory_fmt = ("{category}",
|
||||
"{album[date]:%Y-%m-%d} {album[title]} ({album[id]})")
|
||||
filename_fmt = "{num:>03} {filename[:230]} ({id}).{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:l|api/list)/(\w+)(?:#item=(\d+))?"
|
||||
pattern = BASE_PATTERN + r"/(?:l|api/list)/(\w+)(?:#item=(\d+))?"
|
||||
example = "https://pixeldrain.com/l/abcdefgh"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -97,7 +97,7 @@ class PixeldrainFolderExtractor(PixeldrainExtractor):
|
||||
subcategory = "folder"
|
||||
filename_fmt = "{filename[:230]}.{extension}"
|
||||
archive_fmt = "{path}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:d|api/filesystem)/([^?]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:d|api/filesystem)/([^?]+)"
|
||||
example = "https://pixeldrain.com/d/abcdefgh"
|
||||
|
||||
def metadata(self, data):
|
||||
|
||||
@@ -15,7 +15,7 @@ import itertools
|
||||
import hashlib
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?(?:www\.|touch\.)?ph?ixiv\.net"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/(?:en/)?users/(\d+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/(?:en/)?users/(\d+)"
|
||||
|
||||
|
||||
class PixivExtractor(Extractor):
|
||||
@@ -393,7 +393,7 @@ class PixivExtractor(Extractor):
|
||||
|
||||
class PixivUserExtractor(Dispatch, PixivExtractor):
|
||||
"""Extractor for a pixiv user profile"""
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"(?:en/)?u(?:sers)?/|member\.php\?id=|(?:mypage\.php)?#id="
|
||||
r")(\d+)(?:$|[?#])")
|
||||
example = "https://www.pixiv.net/en/users/12345"
|
||||
@@ -416,7 +416,7 @@ class PixivUserExtractor(Dispatch, PixivExtractor):
|
||||
class PixivArtworksExtractor(PixivExtractor):
|
||||
"""Extractor for artworks of a pixiv user"""
|
||||
subcategory = "artworks"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"(?:en/)?users/(\d+)/(?:artworks|illustrations|manga)"
|
||||
r"(?:/([^/?#]+))?/?(?:$|[?#])"
|
||||
r"|member_illust\.php\?id=(\d+)(?:&([^#]+))?)")
|
||||
@@ -505,7 +505,7 @@ class PixivAvatarExtractor(PixivExtractor):
|
||||
subcategory = "avatar"
|
||||
filename_fmt = "avatar{date:?_//%Y-%m-%d}.{extension}"
|
||||
archive_fmt = "avatar_{user[id]}_{date}"
|
||||
pattern = rf"{USER_PATTERN}/avatar"
|
||||
pattern = USER_PATTERN + r"/avatar"
|
||||
example = "https://www.pixiv.net/en/users/12345/avatar"
|
||||
|
||||
def _init(self):
|
||||
@@ -523,7 +523,7 @@ class PixivBackgroundExtractor(PixivExtractor):
|
||||
subcategory = "background"
|
||||
filename_fmt = "background{date:?_//%Y-%m-%d}.{extension}"
|
||||
archive_fmt = "background_{user[id]}_{date}"
|
||||
pattern = rf"{USER_PATTERN}/background"
|
||||
pattern = USER_PATTERN + "/background"
|
||||
example = "https://www.pixiv.net/en/users/12345/background"
|
||||
|
||||
def _init(self):
|
||||
@@ -585,7 +585,7 @@ class PixivWorkExtractor(PixivExtractor):
|
||||
class PixivUnlistedExtractor(PixivExtractor):
|
||||
"""Extractor for a unlisted pixiv illustrations"""
|
||||
subcategory = "unlisted"
|
||||
pattern = rf"{BASE_PATTERN}/(?:en/)?artworks/unlisted/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/(?:en/)?artworks/unlisted/(\w+)"
|
||||
example = "https://www.pixiv.net/en/artworks/unlisted/a1b2c3d4e5f6g7h8i9j0"
|
||||
|
||||
def _extract_files(self, work):
|
||||
@@ -604,7 +604,7 @@ class PixivFavoriteExtractor(PixivExtractor):
|
||||
directory_fmt = ("{category}", "bookmarks",
|
||||
"{user_bookmark[id]} {user_bookmark[account]}")
|
||||
archive_fmt = "f_{user_bookmark[id]}_{id}{num}.{extension}"
|
||||
pattern = (rf"{BASE_PATTERN}/(?:(?:en/)?"
|
||||
pattern = (BASE_PATTERN + r"/(?:(?:en/)?"
|
||||
r"users/(\d+)/(bookmarks/artworks|following)(?:/([^/?#]+))?"
|
||||
r"|bookmark\.php)(?:\?([^#]*))?")
|
||||
example = "https://www.pixiv.net/en/users/12345/bookmarks/artworks"
|
||||
@@ -667,7 +667,7 @@ class PixivRankingExtractor(PixivExtractor):
|
||||
archive_fmt = "r_{ranking[mode]}_{ranking[date]}_{id}{num}.{extension}"
|
||||
directory_fmt = ("{category}", "rankings",
|
||||
"{ranking[mode]}", "{ranking[date]}")
|
||||
pattern = rf"{BASE_PATTERN}/ranking\.php(?:\?([^#]*))?"
|
||||
pattern = BASE_PATTERN + r"/ranking\.php(?:\?([^#]*))?"
|
||||
example = "https://www.pixiv.net/ranking.php"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -736,7 +736,7 @@ class PixivSearchExtractor(PixivExtractor):
|
||||
subcategory = "search"
|
||||
archive_fmt = "s_{search[word]}_{id}{num}.{extension}"
|
||||
directory_fmt = ("{category}", "search", "{search[word]}")
|
||||
pattern = (rf"{BASE_PATTERN}/(?:(?:en/)?tags/([^/?#]+)(?:/[^/?#]+)?/?"
|
||||
pattern = (BASE_PATTERN + r"/(?:(?:en/)?tags/([^/?#]+)(?:/[^/?#]+)?/?"
|
||||
r"|search\.php)(?:\?([^#]+))?")
|
||||
example = "https://www.pixiv.net/en/tags/TAG"
|
||||
|
||||
@@ -802,7 +802,7 @@ class PixivFollowExtractor(PixivExtractor):
|
||||
subcategory = "follow"
|
||||
archive_fmt = "F_{user_follow[id]}_{id}{num}.{extension}"
|
||||
directory_fmt = ("{category}", "following")
|
||||
pattern = rf"{BASE_PATTERN}/bookmark_new_illust\.php"
|
||||
pattern = BASE_PATTERN + r"/bookmark_new_illust\.php"
|
||||
example = "https://www.pixiv.net/bookmark_new_illust.php"
|
||||
|
||||
def works(self):
|
||||
@@ -851,7 +851,7 @@ class PixivSeriesExtractor(PixivExtractor):
|
||||
directory_fmt = ("{category}", "{user[id]} {user[account]}",
|
||||
"{series[id]} {series[title]}")
|
||||
filename_fmt = "{num_series:>03}_{id}_p{num}.{extension}"
|
||||
pattern = rf"{BASE_PATTERN}/user/(\d+)/series/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/user/(\d+)/series/(\d+)"
|
||||
example = "https://www.pixiv.net/user/12345/series/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -1042,7 +1042,7 @@ class PixivNovelExtractor(PixivExtractor):
|
||||
class PixivNovelNovelExtractor(PixivNovelExtractor):
|
||||
"""Extractor for pixiv novels"""
|
||||
subcategory = "novel"
|
||||
pattern = rf"{BASE_PATTERN}/n(?:ovel/show\.php\?id=|/)(\d+)"
|
||||
pattern = BASE_PATTERN + r"/n(?:ovel/show\.php\?id=|/)(\d+)"
|
||||
example = "https://www.pixiv.net/novel/show.php?id=12345"
|
||||
|
||||
def novels(self):
|
||||
@@ -1056,7 +1056,7 @@ class PixivNovelNovelExtractor(PixivNovelExtractor):
|
||||
class PixivNovelUserExtractor(PixivNovelExtractor):
|
||||
"""Extractor for pixiv users' novels"""
|
||||
subcategory = "user"
|
||||
pattern = rf"{USER_PATTERN}/novels"
|
||||
pattern = USER_PATTERN + r"/novels"
|
||||
example = "https://www.pixiv.net/en/users/12345/novels"
|
||||
|
||||
def novels(self):
|
||||
@@ -1066,7 +1066,7 @@ class PixivNovelUserExtractor(PixivNovelExtractor):
|
||||
class PixivNovelSeriesExtractor(PixivNovelExtractor):
|
||||
"""Extractor for pixiv novel series"""
|
||||
subcategory = "series"
|
||||
pattern = rf"{BASE_PATTERN}/novel/series/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/novel/series/(\d+)"
|
||||
example = "https://www.pixiv.net/novel/series/12345"
|
||||
|
||||
def novels(self):
|
||||
@@ -1076,7 +1076,7 @@ class PixivNovelSeriesExtractor(PixivNovelExtractor):
|
||||
class PixivNovelBookmarkExtractor(PixivNovelExtractor):
|
||||
"""Extractor for bookmarked pixiv novels"""
|
||||
subcategory = "bookmark"
|
||||
pattern = (rf"{USER_PATTERN}/bookmarks/novels"
|
||||
pattern = (USER_PATTERN + r"/bookmarks/novels"
|
||||
r"(?:/([^/?#]+))?(?:/?\?([^#]+))?")
|
||||
example = "https://www.pixiv.net/en/users/12345/bookmarks/novels"
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class PixnetImageExtractor(PixnetExtractor):
|
||||
subcategory = "image"
|
||||
filename_fmt = "{id}.{extension}"
|
||||
directory_fmt = ("{category}", "{blog}")
|
||||
pattern = rf"{BASE_PATTERN}/album/photo/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/album/photo/(\d+)"
|
||||
example = "https://USER.pixnet.net/album/photo/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -92,7 +92,7 @@ class PixnetSetExtractor(PixnetExtractor):
|
||||
subcategory = "set"
|
||||
directory_fmt = ("{category}", "{blog}",
|
||||
"{folder_id} {folder_title}", "{set_id} {set_title}")
|
||||
pattern = rf"{BASE_PATTERN}/album/set/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/album/set/(\d+)"
|
||||
example = "https://USER.pixnet.net/album/set/12345"
|
||||
|
||||
def items(self):
|
||||
@@ -137,7 +137,7 @@ class PixnetFolderExtractor(PixnetExtractor):
|
||||
"""Extractor for all sets in a pixnet folder"""
|
||||
subcategory = "folder"
|
||||
url_fmt = "{}/album/folder/{}"
|
||||
pattern = rf"{BASE_PATTERN}/album/folder/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/album/folder/(\d+)"
|
||||
example = "https://USER.pixnet.net/album/folder/12345"
|
||||
|
||||
|
||||
@@ -145,5 +145,5 @@ class PixnetUserExtractor(PixnetExtractor):
|
||||
"""Extractor for all sets and folders of a pixnet user"""
|
||||
subcategory = "user"
|
||||
url_fmt = "{}{}/album/list"
|
||||
pattern = rf"{BASE_PATTERN}()(?:/blog|/album(?:/list)?)?/?(?:$|[?#])"
|
||||
pattern = BASE_PATTERN + r"()(?:/blog|/album(?:/list)?)?/?(?:$|[?#])"
|
||||
example = "https://USER.pixnet.net/"
|
||||
|
||||
@@ -104,7 +104,7 @@ class PoringaExtractor(Extractor):
|
||||
class PoringaPostExtractor(PoringaExtractor):
|
||||
"""Extractor for posts on poringa.net"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/posts/imagenes/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/posts/imagenes/(\d+)"
|
||||
example = "http://www.poringa.net/posts/imagenes/12345/TITLE.html"
|
||||
|
||||
def posts(self):
|
||||
@@ -113,7 +113,7 @@ class PoringaPostExtractor(PoringaExtractor):
|
||||
|
||||
class PoringaUserExtractor(PoringaExtractor):
|
||||
subcategory = "user"
|
||||
pattern = rf"{BASE_PATTERN}/(\w+)$"
|
||||
pattern = BASE_PATTERN + r"/(\w+)$"
|
||||
example = "http://www.poringa.net/USER"
|
||||
|
||||
def posts(self):
|
||||
@@ -124,7 +124,7 @@ class PoringaUserExtractor(PoringaExtractor):
|
||||
|
||||
class PoringaSearchExtractor(PoringaExtractor):
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/buscar/\?&?q=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/buscar/\?&?q=([^&#]+)"
|
||||
example = "http://www.poringa.net/buscar/?q=QUERY"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -54,7 +54,7 @@ class PornhubGalleryExtractor(PornhubExtractor):
|
||||
directory_fmt = ("{category}", "{user}", "{gallery[id]} {gallery[title]}")
|
||||
filename_fmt = "{num:>03}_{id}.{extension}"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/album/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/album/(\d+)"
|
||||
example = "https://www.pornhub.com/album/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -134,7 +134,7 @@ class PornhubGifExtractor(PornhubExtractor):
|
||||
directory_fmt = ("{category}", "{user}", "gifs")
|
||||
filename_fmt = "{id} {title}.{extension}"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/gif/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/gif/(\d+)"
|
||||
example = "https://www.pornhub.com/gif/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -163,7 +163,7 @@ class PornhubGifExtractor(PornhubExtractor):
|
||||
|
||||
class PornhubUserExtractor(Dispatch, PornhubExtractor):
|
||||
"""Extractor for a pornhub user"""
|
||||
pattern = rf"{BASE_PATTERN}/((?:users|model|pornstar)/[^/?#]+)/?$"
|
||||
pattern = BASE_PATTERN + r"/((?:users|model|pornstar)/[^/?#]+)/?$"
|
||||
example = "https://www.pornhub.com/model/USER"
|
||||
|
||||
def items(self):
|
||||
@@ -177,7 +177,7 @@ class PornhubUserExtractor(Dispatch, PornhubExtractor):
|
||||
class PornhubPhotosExtractor(PornhubExtractor):
|
||||
"""Extractor for all galleries of a pornhub user"""
|
||||
subcategory = "photos"
|
||||
pattern = (rf"{BASE_PATTERN}/((?:users|model|pornstar)/[^/?#]+)"
|
||||
pattern = (BASE_PATTERN + r"/((?:users|model|pornstar)/[^/?#]+)"
|
||||
"/(photos(?:/[^/?#]+)?)")
|
||||
example = "https://www.pornhub.com/model/USER/photos"
|
||||
|
||||
@@ -198,7 +198,7 @@ class PornhubPhotosExtractor(PornhubExtractor):
|
||||
class PornhubGifsExtractor(PornhubExtractor):
|
||||
"""Extractor for a pornhub user's gifs"""
|
||||
subcategory = "gifs"
|
||||
pattern = (rf"{BASE_PATTERN}/((?:users|model|pornstar)/[^/?#]+)"
|
||||
pattern = (BASE_PATTERN + r"/((?:users|model|pornstar)/[^/?#]+)"
|
||||
"/(gifs(?:/[^/?#]+)?)")
|
||||
example = "https://www.pornhub.com/model/USER/gifs"
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ class PornpicsExtractor(Extractor):
|
||||
|
||||
class PornpicsGalleryExtractor(PornpicsExtractor, GalleryExtractor):
|
||||
"""Extractor for pornpics galleries"""
|
||||
pattern = rf"{BASE_PATTERN}/galleries/((?:[^/?#]+-)?(\d+))"
|
||||
pattern = BASE_PATTERN + r"/galleries/((?:[^/?#]+-)?(\d+))"
|
||||
example = "https://www.pornpics.com/galleries/TITLE-12345/"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -94,7 +94,7 @@ class PornpicsGalleryExtractor(PornpicsExtractor, GalleryExtractor):
|
||||
class PornpicsTagExtractor(PornpicsExtractor):
|
||||
"""Extractor for galleries from pornpics tag searches"""
|
||||
subcategory = "tag"
|
||||
pattern = rf"{BASE_PATTERN}/tags/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/tags/([^/?#]+)"
|
||||
example = "https://www.pornpics.com/tags/TAGS/"
|
||||
|
||||
def galleries(self):
|
||||
@@ -105,7 +105,7 @@ class PornpicsTagExtractor(PornpicsExtractor):
|
||||
class PornpicsSearchExtractor(PornpicsExtractor):
|
||||
"""Extractor for galleries from pornpics search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/(?:\?q=|pornstars/|channels/)([^/&#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?:\?q=|pornstars/|channels/)([^/&#]+)"
|
||||
example = "https://www.pornpics.com/?q=QUERY"
|
||||
|
||||
def galleries(self):
|
||||
|
||||
@@ -95,7 +95,7 @@ class PostmillSubmissionsExtractor(PostmillExtractor):
|
||||
groups[-1]).items() if self.acceptable_query(key)}
|
||||
|
||||
def items(self):
|
||||
url = self.root + self.base + self.sorting_path
|
||||
url = f"{self.root}{self.base}{self.sorting_path}"
|
||||
|
||||
while url:
|
||||
response = self.request(url, params=self.query)
|
||||
@@ -130,14 +130,14 @@ BASE_PATTERN = PostmillExtractor.update({
|
||||
}
|
||||
})
|
||||
QUERY_RE = r"(?:\?([^#]+))?$"
|
||||
SORTING_RE = (rf"(/(?:hot|new|active|top|controversial|most_commented))?"
|
||||
rf"{QUERY_RE}")
|
||||
SORTING_RE = (r"(/(?:hot|new|active|top|controversial|most_commented))?" +
|
||||
QUERY_RE)
|
||||
|
||||
|
||||
class PostmillPostExtractor(PostmillExtractor):
|
||||
"""Extractor for a single submission URL"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/f/(\w+)/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/f/(\w+)/(\d+)"
|
||||
example = "https://raddle.me/f/FORUM/123/TITLE"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -146,13 +146,13 @@ class PostmillPostExtractor(PostmillExtractor):
|
||||
self.post_id = match[4]
|
||||
|
||||
def post_urls(self):
|
||||
return (self.root + "/f/" + self.forum + "/" + self.post_id,)
|
||||
return (f"{self.root}/f/{self.forum}/{self.post_id}",)
|
||||
|
||||
|
||||
class PostmillShortURLExtractor(PostmillExtractor):
|
||||
"""Extractor for short submission URLs"""
|
||||
subcategory = "shorturl"
|
||||
pattern = rf"{BASE_PATTERN}(/\d+)$"
|
||||
pattern = BASE_PATTERN + r"(/\d+)$"
|
||||
example = "https://raddle.me/123"
|
||||
|
||||
def items(self):
|
||||
@@ -193,6 +193,6 @@ class PostmillTagExtractor(PostmillSubmissionsExtractor):
|
||||
class PostmillSearchExtractor(PostmillSubmissionsExtractor):
|
||||
"""Extractor for search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}(/search)()\?(q=[^#]+)$"
|
||||
pattern = BASE_PATTERN + r"(/search)()\?(q=[^#]+)$"
|
||||
example = "https://raddle.me/search?q=QUERY"
|
||||
whitelisted_parameters = ("q",)
|
||||
|
||||
@@ -21,7 +21,7 @@ class RawkumaBase():
|
||||
class RawkumaChapterExtractor(RawkumaBase, ChapterExtractor):
|
||||
"""Extractor for manga chapters from rawkuma.net"""
|
||||
archive_fmt = "{chapter_id}_{page}"
|
||||
pattern = rf"{BASE_PATTERN}(/manga/[^/?#]+/chapter-\d+(?:.\d+)?\.(\d+))"
|
||||
pattern = BASE_PATTERN + r"(/manga/[^/?#]+/chapter-\d+(?:.\d+)?\.(\d+))"
|
||||
example = "https://rawkuma.net/manga/7TITLE/chapter-123.321"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -54,7 +54,7 @@ class RawkumaChapterExtractor(RawkumaBase, ChapterExtractor):
|
||||
class RawkumaMangaExtractor(RawkumaBase, MangaExtractor):
|
||||
"""Extractor for manga from rawkuma.net"""
|
||||
chapterclass = RawkumaChapterExtractor
|
||||
pattern = rf"{BASE_PATTERN}/manga/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/manga/([^/?#]+)"
|
||||
example = "https://rawkuma.net/manga/TITLE/"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -171,7 +171,7 @@ class ReactorTagExtractor(ReactorExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "{search_tags}_{post_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/tag/([^/?#]+)(?:/[^/?#]+)?"
|
||||
pattern = BASE_PATTERN + r"/tag/([^/?#]+)(?:/[^/?#]+)?"
|
||||
example = "http://reactor.cc/tag/TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -187,7 +187,7 @@ class ReactorSearchExtractor(ReactorExtractor):
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "search", "{search_tags}")
|
||||
archive_fmt = "s_{search_tags}_{post_id}_{num}"
|
||||
pattern = rf"{BASE_PATTERN}/search(?:/|\?q=)([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/search(?:/|\?q=)([^/?#]+)"
|
||||
example = "http://reactor.cc/search?q=QUERY"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -202,7 +202,7 @@ class ReactorUserExtractor(ReactorExtractor):
|
||||
"""Extractor for all posts of a user on *reactor.cc sites"""
|
||||
subcategory = "user"
|
||||
directory_fmt = ("{category}", "user", "{user}")
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)"
|
||||
example = "http://reactor.cc/user/USER"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -216,7 +216,7 @@ class ReactorUserExtractor(ReactorExtractor):
|
||||
class ReactorPostExtractor(ReactorExtractor):
|
||||
"""Extractor for single posts on *reactor.cc sites"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/post/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post/(\d+)"
|
||||
example = "http://reactor.cc/post/12345"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -44,7 +44,7 @@ class ReadcomiconlineBase():
|
||||
class ReadcomiconlineIssueExtractor(ReadcomiconlineBase, ChapterExtractor):
|
||||
"""Extractor for comic-issues from readcomiconline.li"""
|
||||
subcategory = "issue"
|
||||
pattern = rf"{BASE_PATTERN}(/Comic/[^/?#]+/[^/?#]+\?)([^#]+)"
|
||||
pattern = BASE_PATTERN + r"(/Comic/[^/?#]+/[^/?#]+\?)([^#]+)"
|
||||
example = "https://readcomiconline.li/Comic/TITLE/Issue-123?id=12345"
|
||||
|
||||
def _init(self):
|
||||
@@ -98,7 +98,7 @@ class ReadcomiconlineComicExtractor(ReadcomiconlineBase, MangaExtractor):
|
||||
"""Extractor for comics from readcomiconline.li"""
|
||||
chapterclass = ReadcomiconlineIssueExtractor
|
||||
subcategory = "comic"
|
||||
pattern = rf"{BASE_PATTERN}(/Comic/[^/?#]+/?)$"
|
||||
pattern = BASE_PATTERN + r"(/Comic/[^/?#]+/?)$"
|
||||
example = "https://readcomiconline.li/Comic/TITLE"
|
||||
|
||||
def chapters(self, page):
|
||||
|
||||
@@ -85,7 +85,7 @@ class RealbooruTagExtractor(RealbooruExtractor):
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
per_page = 42
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=list&tags=([^&#]*)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=list&tags=([^&#]*)"
|
||||
example = "https://realbooru.com/index.php?page=post&s=list&tags=TAG"
|
||||
|
||||
def metadata(self):
|
||||
@@ -105,7 +105,7 @@ class RealbooruFavoriteExtractor(RealbooruExtractor):
|
||||
directory_fmt = ("{category}", "favorites", "{favorite_id}")
|
||||
archive_fmt = "f_{favorite_id}_{id}"
|
||||
per_page = 50
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=favorites&s=view&id=(\d+)"
|
||||
example = "https://realbooru.com/index.php?page=favorites&s=view&id=12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -123,7 +123,7 @@ class RealbooruPoolExtractor(RealbooruExtractor):
|
||||
subcategory = "pool"
|
||||
directory_fmt = ("{category}", "pool", "{pool} {pool_name}")
|
||||
archive_fmt = "p_{pool}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=pool&s=show&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=pool&s=show&id=(\d+)"
|
||||
example = "https://realbooru.com/index.php?page=pool&s=show&id=12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -150,7 +150,7 @@ class RealbooruPoolExtractor(RealbooruExtractor):
|
||||
class RealbooruPostExtractor(RealbooruExtractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/index\.php\?page=post&s=view&id=(\d+)"
|
||||
pattern = BASE_PATTERN + r"/index\.php\?page=post&s=view&id=(\d+)"
|
||||
example = "https://realbooru.com/index.php?page=post&s=view&id=12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -79,7 +79,7 @@ class Rule34vaultExtractor(BooruExtractor):
|
||||
class Rule34vaultPostExtractor(Rule34vaultExtractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post/(\d+)"
|
||||
example = "https://rule34vault.com/post/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -90,7 +90,7 @@ class Rule34vaultPlaylistExtractor(Rule34vaultExtractor):
|
||||
subcategory = "playlist"
|
||||
directory_fmt = ("{category}", "{playlist_id}")
|
||||
archive_fmt = "p_{playlist_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/playlists/view/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/playlists/view/(\d+)"
|
||||
example = "https://rule34vault.com/playlists/view/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -105,7 +105,7 @@ class Rule34vaultTagExtractor(Rule34vaultExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?!p(?:ost|laylists)/)([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?!p(?:ost|laylists)/)([^/?#]+)"
|
||||
example = "https://rule34vault.com/TAG"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -134,7 +134,7 @@ class Rule34xyzExtractor(BooruExtractor):
|
||||
class Rule34xyzPostExtractor(Rule34xyzExtractor):
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/post/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/post/(\d+)"
|
||||
example = "https://rule34.xyz/post/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -145,7 +145,7 @@ class Rule34xyzPlaylistExtractor(Rule34xyzExtractor):
|
||||
subcategory = "playlist"
|
||||
directory_fmt = ("{category}", "{playlist_id}")
|
||||
archive_fmt = "p_{playlist_id}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/playlists/view/(\d+)"
|
||||
pattern = BASE_PATTERN + r"/playlists/view/(\d+)"
|
||||
example = "https://rule34.xyz/playlists/view/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -160,7 +160,7 @@ class Rule34xyzTagExtractor(Rule34xyzExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/([^/?#]+)$"
|
||||
pattern = BASE_PATTERN + r"/([^/?#]+)$"
|
||||
example = "https://rule34.xyz/TAG"
|
||||
|
||||
def metadata(self):
|
||||
|
||||
@@ -18,7 +18,7 @@ class SaintAlbumExtractor(LolisafeAlbumExtractor):
|
||||
"""Extractor for saint albums"""
|
||||
category = "saint"
|
||||
root = "https://saint2.su"
|
||||
pattern = rf"{BASE_PATTERN}/a/([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/a/([^/?#]+)"
|
||||
example = "https://saint2.su/a/ID"
|
||||
|
||||
def fetch_album(self, album_id):
|
||||
@@ -58,7 +58,7 @@ class SaintMediaExtractor(SaintAlbumExtractor):
|
||||
"""Extractor for saint media links"""
|
||||
subcategory = "media"
|
||||
directory_fmt = ("{category}",)
|
||||
pattern = rf"{BASE_PATTERN}(/(embe)?d/([^/?#]+))"
|
||||
pattern = BASE_PATTERN + r"(/(embe)?d/([^/?#]+))"
|
||||
example = "https://saint2.su/embed/ID"
|
||||
|
||||
def fetch_album(self, album_id):
|
||||
|
||||
@@ -119,7 +119,7 @@ class SankakuTagExtractor(SankakuExtractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
archive_fmt = "t_{search_tags}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}(?:/posts)?/?\?([^#]*)"
|
||||
pattern = BASE_PATTERN + r"(?:/posts)?/?\?([^#]*)"
|
||||
example = "https://sankaku.app/?tags=TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
@@ -149,7 +149,7 @@ class SankakuPoolExtractor(SankakuExtractor):
|
||||
subcategory = "pool"
|
||||
directory_fmt = ("{category}", "pool", "{pool[id]} {pool[name_en]}")
|
||||
archive_fmt = "p_{pool}_{id}"
|
||||
pattern = rf"{BASE_PATTERN}/(?:books|pools?/show)/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/(?:books|pools?/show)/(\w+)"
|
||||
example = "https://sankaku.app/books/12345"
|
||||
|
||||
def metadata(self):
|
||||
@@ -171,7 +171,7 @@ class SankakuPostExtractor(SankakuExtractor):
|
||||
"""Extractor for single posts from sankaku.app"""
|
||||
subcategory = "post"
|
||||
archive_fmt = "{id}"
|
||||
pattern = rf"{BASE_PATTERN}/posts?(?:/show)?/(\w+)"
|
||||
pattern = BASE_PATTERN + r"/posts?(?:/show)?/(\w+)"
|
||||
example = "https://sankaku.app/post/show/12345"
|
||||
|
||||
def posts(self):
|
||||
@@ -181,7 +181,7 @@ class SankakuPostExtractor(SankakuExtractor):
|
||||
class SankakuBooksExtractor(SankakuExtractor):
|
||||
"""Extractor for books by tag search on sankaku.app"""
|
||||
subcategory = "books"
|
||||
pattern = rf"{BASE_PATTERN}/books/?\?([^#]*)"
|
||||
pattern = BASE_PATTERN + r"/books/?\?([^#]*)"
|
||||
example = "https://sankaku.app/books?tags=TAG"
|
||||
|
||||
def __init__(self, match):
|
||||
|
||||
@@ -136,7 +136,7 @@ class ScrolllerExtractor(Extractor):
|
||||
class ScrolllerSubredditExtractor(ScrolllerExtractor):
|
||||
"""Extractor for media from a scrolller subreddit"""
|
||||
subcategory = "subreddit"
|
||||
pattern = rf"{BASE_PATTERN}(/r/[^/?#]+)(?:/?\?([^#]+))?"
|
||||
pattern = BASE_PATTERN + r"(/r/[^/?#]+)(?:/?\?([^#]+))?"
|
||||
example = "https://scrolller.com/r/SUBREDDIT"
|
||||
|
||||
def posts(self):
|
||||
@@ -173,7 +173,7 @@ class ScrolllerSubredditExtractor(ScrolllerExtractor):
|
||||
class ScrolllerFollowingExtractor(ScrolllerExtractor):
|
||||
"""Extractor for followed scrolller subreddits"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{BASE_PATTERN}/following"
|
||||
pattern = BASE_PATTERN + r"/following"
|
||||
example = "https://scrolller.com/following"
|
||||
|
||||
def items(self):
|
||||
@@ -199,7 +199,7 @@ class ScrolllerFollowingExtractor(ScrolllerExtractor):
|
||||
class ScrolllerPostExtractor(ScrolllerExtractor):
|
||||
"""Extractor for media from a single scrolller post"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}/(?!r/|following$)([^/?#]+)"
|
||||
pattern = BASE_PATTERN + r"/(?!r/|following$)([^/?#]+)"
|
||||
example = "https://scrolller.com/TITLE-SLUG-a1b2c3d4f5"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -194,8 +194,8 @@ class SexcomPinExtractor(SexcomExtractor):
|
||||
"""Extractor for a pinned image or video on www.sex.com"""
|
||||
subcategory = "pin"
|
||||
directory_fmt = ("{category}",)
|
||||
pattern = (rf"{BASE_PATTERN}"
|
||||
rf"(/(?:\w\w/(?:pic|gif|video)s|pin)/\d+/?)(?!.*#related$)")
|
||||
pattern = (BASE_PATTERN +
|
||||
r"(/(?:\w\w/(?:pic|gif|video)s|pin)/\d+/?)(?!.*#related$)")
|
||||
example = "https://www.sex.com/pin/12345-TITLE/"
|
||||
|
||||
def pins(self):
|
||||
@@ -206,7 +206,7 @@ class SexcomRelatedPinExtractor(SexcomPinExtractor):
|
||||
"""Extractor for related pins on www.sex.com"""
|
||||
subcategory = "related-pin"
|
||||
directory_fmt = ("{category}", "related {original_pin[pin_id]}")
|
||||
pattern = rf"{BASE_PATTERN}(/pin/(\d+)/?).*#related$"
|
||||
pattern = BASE_PATTERN + r"(/pin/(\d+)/?).*#related$"
|
||||
example = "https://www.sex.com/pin/12345#related"
|
||||
|
||||
def metadata(self):
|
||||
@@ -223,7 +223,7 @@ class SexcomPinsExtractor(SexcomExtractor):
|
||||
"""Extractor for a user's pins on www.sex.com"""
|
||||
subcategory = "pins"
|
||||
directory_fmt = ("{category}", "{user}")
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/pins/"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/pins/"
|
||||
example = "https://www.sex.com/user/USER/pins/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -238,7 +238,7 @@ class SexcomLikesExtractor(SexcomExtractor):
|
||||
"""Extractor for a user's liked pins on www.sex.com"""
|
||||
subcategory = "likes"
|
||||
directory_fmt = ("{category}", "{user}", "Likes")
|
||||
pattern = rf"{BASE_PATTERN}/user/([^/?#]+)/likes/"
|
||||
pattern = BASE_PATTERN + r"/user/([^/?#]+)/likes/"
|
||||
example = "https://www.sex.com/user/USER/likes/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -253,8 +253,8 @@ class SexcomBoardExtractor(SexcomExtractor):
|
||||
"""Extractor for pins from a board on www.sex.com"""
|
||||
subcategory = "board"
|
||||
directory_fmt = ("{category}", "{user}", "{board}")
|
||||
pattern = (rf"{BASE_PATTERN}/user"
|
||||
rf"/([^/?#]+)/(?!(?:following|pins|repins|likes)/)([^/?#]+)")
|
||||
pattern = (BASE_PATTERN + r"/user"
|
||||
r"/([^/?#]+)/(?!(?:following|pins|repins|likes)/)([^/?#]+)")
|
||||
example = "https://www.sex.com/user/USER/BOARD/"
|
||||
|
||||
def metadata(self):
|
||||
@@ -290,10 +290,10 @@ class SexcomSearchExtractor(SexcomExtractor):
|
||||
"""Extractor for search results on www.sex.com"""
|
||||
subcategory = "search"
|
||||
directory_fmt = ("{category}", "search", "{search[search]}")
|
||||
pattern = (rf"{BASE_PATTERN}/(?:"
|
||||
rf"(pic|gif|video)s(?:\?(search=[^#]+)$|/([^/?#]*))"
|
||||
rf"|search/(pic|gif|video)s"
|
||||
rf")/?(?:\?([^#]+))?")
|
||||
pattern = (BASE_PATTERN + r"/(?:"
|
||||
r"(pic|gif|video)s(?:\?(search=[^#]+)$|/([^/?#]*))"
|
||||
r"|search/(pic|gif|video)s"
|
||||
r")/?(?:\?([^#]+))?")
|
||||
example = "https://www.sex.com/search/pics?query=QUERY"
|
||||
|
||||
def _init(self):
|
||||
|
||||
@@ -100,7 +100,7 @@ class Shimmie2TagExtractor(Shimmie2Extractor):
|
||||
subcategory = "tag"
|
||||
directory_fmt = ("{category}", "{search_tags}")
|
||||
file_url_fmt = "{}/_images/{}/{}%20-%20{}.{}"
|
||||
pattern = rf"{BASE_PATTERN}post/list/([^/?#]+)(?:/(\d+))?"
|
||||
pattern = BASE_PATTERN + r"post/list/([^/?#]+)(?:/(\d+))?"
|
||||
example = "https://vidya.pics/post/list/TAG/1"
|
||||
|
||||
def metadata(self):
|
||||
@@ -164,7 +164,7 @@ class Shimmie2TagExtractor(Shimmie2Extractor):
|
||||
class Shimmie2PostExtractor(Shimmie2Extractor):
|
||||
"""Extractor for single shimmie2 posts"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{BASE_PATTERN}post/view/(\d+)"
|
||||
pattern = BASE_PATTERN + r"post/view/(\d+)"
|
||||
example = "https://vidya.pics/post/view/12345"
|
||||
|
||||
def posts(self):
|
||||
|
||||
@@ -90,7 +90,7 @@ class ShopifyCollectionExtractor(ShopifyExtractor):
|
||||
"""Base class for collection extractors for Shopify based sites"""
|
||||
subcategory = "collection"
|
||||
directory_fmt = ("{category}", "{collection[title]}")
|
||||
pattern = rf"{BASE_PATTERN}(/collections/[\w-]+)/?(?:$|[?#])"
|
||||
pattern = BASE_PATTERN + r"(/collections/[\w-]+)/?(?:$|[?#])"
|
||||
example = "https://www.fashionnova.com/collections/TITLE"
|
||||
|
||||
def metadata(self):
|
||||
@@ -113,7 +113,7 @@ class ShopifyProductExtractor(ShopifyExtractor):
|
||||
"""Base class for product extractors for Shopify based sites"""
|
||||
subcategory = "product"
|
||||
directory_fmt = ("{category}", "Products")
|
||||
pattern = rf"{BASE_PATTERN}((?:/collections/[\w-]+)?/products/[\w-]+)"
|
||||
pattern = BASE_PATTERN + r"((?:/collections/[\w-]+)?/products/[\w-]+)"
|
||||
example = "https://www.fashionnova.com/collections/TITLE/products/NAME"
|
||||
|
||||
def products(self):
|
||||
|
||||
@@ -10,7 +10,7 @@ from .common import Extractor, Message, Dispatch
|
||||
from .. import text
|
||||
|
||||
BASE_PATTERN = r"(?:https?://)?skeb\.jp"
|
||||
USER_PATTERN = rf"{BASE_PATTERN}/@([^/?#]+)"
|
||||
USER_PATTERN = BASE_PATTERN + r"/@([^/?#]+)"
|
||||
|
||||
|
||||
class SkebExtractor(Extractor):
|
||||
@@ -194,7 +194,7 @@ class SkebExtractor(Extractor):
|
||||
class SkebPostExtractor(SkebExtractor):
|
||||
"""Extractor for a single skeb post"""
|
||||
subcategory = "post"
|
||||
pattern = rf"{USER_PATTERN}/works/(\d+)"
|
||||
pattern = USER_PATTERN + r"/works/(\d+)"
|
||||
example = "https://skeb.jp/@USER/works/123"
|
||||
|
||||
def posts(self):
|
||||
@@ -204,7 +204,7 @@ class SkebPostExtractor(SkebExtractor):
|
||||
class SkebWorksExtractor(SkebExtractor):
|
||||
"""Extractor for a skeb user's works"""
|
||||
subcategory = "works"
|
||||
pattern = rf"{USER_PATTERN}/works"
|
||||
pattern = USER_PATTERN + r"/works"
|
||||
example = "https://skeb.jp/@USER/works"
|
||||
|
||||
def posts(self):
|
||||
@@ -216,7 +216,7 @@ class SkebWorksExtractor(SkebExtractor):
|
||||
class SkebSentrequestsExtractor(SkebExtractor):
|
||||
"""Extractor for a skeb user's sent requests"""
|
||||
subcategory = "sentrequests"
|
||||
pattern = rf"{USER_PATTERN}/sent[ _-]?requests"
|
||||
pattern = USER_PATTERN + r"/sent[ _-]?requests"
|
||||
example = "https://skeb.jp/@USER/sentrequests"
|
||||
|
||||
def posts(self):
|
||||
@@ -227,7 +227,7 @@ class SkebSentrequestsExtractor(SkebExtractor):
|
||||
|
||||
class SkebUserExtractor(Dispatch, SkebExtractor):
|
||||
"""Extractor for a skeb user profile"""
|
||||
pattern = rf"{USER_PATTERN}/?$"
|
||||
pattern = USER_PATTERN + r"/?$"
|
||||
example = "https://skeb.jp/@USER"
|
||||
|
||||
def items(self):
|
||||
@@ -246,7 +246,7 @@ class SkebUserExtractor(Dispatch, SkebExtractor):
|
||||
class SkebSearchExtractor(SkebExtractor):
|
||||
"""Extractor for skeb search results"""
|
||||
subcategory = "search"
|
||||
pattern = rf"{BASE_PATTERN}/search\?q=([^&#]+)"
|
||||
pattern = BASE_PATTERN + r"/search\?q=([^&#]+)"
|
||||
example = "https://skeb.jp/search?q=QUERY"
|
||||
|
||||
def metadata(self):
|
||||
@@ -298,7 +298,7 @@ class SkebSearchExtractor(SkebExtractor):
|
||||
class SkebFollowingExtractor(SkebExtractor):
|
||||
"""Extractor for all creators followed by a skeb user"""
|
||||
subcategory = "following"
|
||||
pattern = rf"{USER_PATTERN}/following_creators"
|
||||
pattern = USER_PATTERN + r"/following_creators"
|
||||
example = "https://skeb.jp/@USER/following_creators"
|
||||
|
||||
items = SkebExtractor.items_users
|
||||
@@ -312,7 +312,7 @@ class SkebFollowingExtractor(SkebExtractor):
|
||||
class SkebFollowingUsersExtractor(SkebExtractor):
|
||||
"""Extractor for your followed users"""
|
||||
subcategory = "following-users"
|
||||
pattern = rf"{BASE_PATTERN}/following_users"
|
||||
pattern = BASE_PATTERN + r"/following_users"
|
||||
example = "https://skeb.jp/following_users"
|
||||
|
||||
items = SkebExtractor.items_users
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user