Revert "use f-strings when building 'pattern'"

revert d7c97d5a97.
This commit is contained in:
Mike Fährmann
2025-12-20 20:44:23 +01:00
parent 19a27a47b3
commit e006d26c8e
133 changed files with 607 additions and 607 deletions

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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):

View File

@@ -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",)

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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/"

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"

View File

@@ -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/"

View File

@@ -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):

View File

@@ -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"

View File

@@ -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):

View File

@@ -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",)

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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