diff --git a/scripts/export_tests.py b/scripts/export_tests.py
index 1a09e107..e95b0c2f 100755
--- a/scripts/export_tests.py
+++ b/scripts/export_tests.py
@@ -250,7 +250,7 @@ def collect_tests(whitelist=None):
if whitelist and extr.category not in whitelist:
continue
test = build_test(extr, data)
- tests[f"{extr.category}_{extr.subcategory}"].append(test)
+ tests[extr.category].append(test)
return tests
diff --git a/setup.cfg b/setup.cfg
index 56d71087..a66d7cf3 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
[flake8]
-exclude = build,archive
+exclude = .git,__pycache__,build,dist,archive,test/results
ignore = E203,E226,W504
per-file-ignores =
setup.py: E501
diff --git a/test/results/2chan.py b/test/results/2chan.py
new file mode 100644
index 00000000..0a1cdd69
--- /dev/null
+++ b/test/results/2chan.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.2chan")
+_2chan = getattr(gallery_dl.extractor, "2chan")
+
+
+__tests__ = (
+{
+ "#url" : "https://dec.2chan.net/70/res/14565.htm",
+ "#category": ("", "2chan", "thread"),
+ "#class" : _2chan._2chanThreadExtractor,
+ "#pattern" : r"https://dec\.2chan\.net/70/src/\d{13}\.jpg",
+ "#count" : ">= 3",
+
+ "board" : "70",
+ "board_name": "新板提案",
+ "com" : str,
+ "fsize" : r"re:\d+",
+ "name" : "名無し",
+ "no" : r"re:1[45]\d\d\d",
+ "now" : r"re:22/../..\(.\)..:..:..",
+ "post" : "無題",
+ "server" : "dec",
+ "thread" : "14565",
+ "tim" : r"re:^\d{13}$",
+ "time" : r"re:^\d{10}$",
+ "title" : "ヒロアカ板",
+},
+
+)
diff --git a/test/results/2chen.py b/test/results/2chen.py
new file mode 100644
index 00000000..589053fa
--- /dev/null
+++ b/test/results/2chen.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.2chen")
+_2chen = getattr(gallery_dl.extractor, "2chen")
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://sturdychan.help/tv/268929",
+ "#category": ("", "2chen", "thread"),
+ "#class" : _2chen._2chenThreadExtractor,
+ "#pattern" : r"https://sturdychan\.help/assets/images/src/\w{40}\.\w+$",
+ "#count" : ">= 179",
+
+ "board" : "tv",
+ "date" : datetime.datetime,
+ "hash" : r"re:[0-9a-f]{40}",
+ "name" : "Anonymous",
+ "no" : r"re:\d+",
+ "thread": "268929",
+ "time" : int,
+ "title" : "「/ttg/ #118: 🇧🇷 edition」",
+ "url" : str,
+},
+
+{
+ "#url" : "https://2chen.club/tv/1",
+ "#category": ("", "2chen", "thread"),
+ "#class" : _2chen._2chenThreadExtractor,
+},
+
+{
+ "#url" : "https://2chen.moe/jp/303786",
+ "#category": ("", "2chen", "thread"),
+ "#class" : _2chen._2chenThreadExtractor,
+},
+
+{
+ "#url" : "https://sturdychan.help/co/",
+ "#category": ("", "2chen", "board"),
+ "#class" : _2chen._2chenBoardExtractor,
+ "#pattern" : _2chen._2chenThreadExtractor.pattern,
+},
+
+{
+ "#url" : "https://2chen.moe/co",
+ "#category": ("", "2chen", "board"),
+ "#class" : _2chen._2chenBoardExtractor,
+},
+
+{
+ "#url" : "https://2chen.club/tv",
+ "#category": ("", "2chen", "board"),
+ "#class" : _2chen._2chenBoardExtractor,
+},
+
+{
+ "#url" : "https://2chen.moe/co/catalog",
+ "#category": ("", "2chen", "board"),
+ "#class" : _2chen._2chenBoardExtractor,
+},
+
+)
diff --git a/test/results/35photo.py b/test/results/35photo.py
new file mode 100644
index 00000000..b9c7673a
--- /dev/null
+++ b/test/results/35photo.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.35photo")
+_35photo = getattr(gallery_dl.extractor, "35photo")
+
+
+__tests__ = (
+{
+ "#url" : "https://35photo.pro/liya",
+ "#category": ("", "35photo", "user"),
+ "#class" : _35photo._35photoUserExtractor,
+ "#pattern" : r"https://([a-z][0-9]\.)?35photo\.pro/photos_(main|series)/.*\.jpg",
+ "#count" : 9,
+},
+
+{
+ "#url" : "https://35photo.pro/suhoveev",
+ "#category": ("", "35photo", "user"),
+ "#class" : _35photo._35photoUserExtractor,
+ "#count" : ">= 33",
+},
+
+{
+ "#url" : "https://en.35photo.pro/liya",
+ "#category": ("", "35photo", "user"),
+ "#class" : _35photo._35photoUserExtractor,
+},
+
+{
+ "#url" : "https://ru.35photo.pro/liya",
+ "#category": ("", "35photo", "user"),
+ "#class" : _35photo._35photoUserExtractor,
+},
+
+{
+ "#url" : "https://35photo.pro/tags/landscape/",
+ "#category": ("", "35photo", "tag"),
+ "#class" : _35photo._35photoTagExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+ "#archive" : False,
+},
+
+{
+ "#url" : "https://35photo.pro/genre_109/",
+ "#category": ("", "35photo", "genre"),
+ "#class" : _35photo._35photoGenreExtractor,
+},
+
+{
+ "#url" : "https://35photo.pro/photo_753340/",
+ "#category": ("", "35photo", "image"),
+ "#class" : _35photo._35photoImageExtractor,
+ "#count" : 1,
+
+ "url" : r"re:https://35photo\.pro/photos_main/.*\.jpg",
+ "id" : 753340,
+ "title" : "Winter walk",
+ "description": str,
+ "tags" : list,
+ "views" : int,
+ "favorites" : int,
+ "score" : int,
+ "type" : 0,
+ "date" : "15 авг, 2014",
+ "user" : "liya",
+ "user_id" : 20415,
+ "user_name" : "Liya Mirzaeva",
+},
+
+)
diff --git a/test/results/3dbooru.py b/test/results/3dbooru.py
new file mode 100644
index 00000000..d3d407bd
--- /dev/null
+++ b/test/results/3dbooru.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.3dbooru")
+_3dbooru = getattr(gallery_dl.extractor, "3dbooru")
+
+
+__tests__ = (
+{
+ "#url" : "http://behoimi.org/post?tags=himekawa_azuru+dress",
+ "#category": ("booru", "3dbooru", "tag"),
+ "#class" : _3dbooru._3dbooruTagExtractor,
+ "#sha1_url" : "ecb30c6aaaf8a6ff8f55255737a9840832a483c1",
+ "#sha1_content": "11cbda40c287e026c1ce4ca430810f761f2d0b2a",
+},
+
+{
+ "#url" : "http://behoimi.org/pool/show/27",
+ "#category": ("booru", "3dbooru", "pool"),
+ "#class" : _3dbooru._3dbooruPoolExtractor,
+ "#sha1_url" : "da75d2d1475449d5ef0c266cb612683b110a30f2",
+ "#sha1_content": "fd5b37c5c6c2de4b4d6f1facffdefa1e28176554",
+},
+
+{
+ "#url" : "http://behoimi.org/post/show/140852",
+ "#category": ("booru", "3dbooru", "post"),
+ "#class" : _3dbooru._3dbooruPostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_url" : "ce874ea26f01d6c94795f3cc3aaaaa9bc325f2f6",
+ "#sha1_content": "26549d55b82aa9a6c1686b96af8bfcfa50805cd4",
+
+ "tags_character": "furude_rika",
+ "tags_copyright": "higurashi_no_naku_koro_ni",
+ "tags_model" : "himekawa_azuru",
+ "tags_general" : str,
+},
+
+{
+ "#url" : "http://behoimi.org/post/popular_by_month?month=2&year=2013",
+ "#category": ("booru", "3dbooru", "popular"),
+ "#class" : _3dbooru._3dbooruPopularExtractor,
+ "#pattern" : r"http://behoimi\.org/data/../../[0-9a-f]{32}\.jpg",
+ "#count" : 20,
+},
+
+)
diff --git a/test/results/4chan.py b/test/results/4chan.py
new file mode 100644
index 00000000..c90e4107
--- /dev/null
+++ b/test/results/4chan.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.4chan")
+_4chan = getattr(gallery_dl.extractor, "4chan")
+
+
+__tests__ = (
+{
+ "#url" : "https://boards.4chan.org/tg/thread/15396072/",
+ "#category": ("", "4chan", "thread"),
+ "#class" : _4chan._4chanThreadExtractor,
+ "#sha1_url" : "39082ad166161966d7ba8e37f2173a824eb540f0",
+ "#sha1_metadata": "7ae2f4049adf0d2f835eb91b6b26b7f4ec882e0a",
+ "#sha1_content" : "20b7b51afa51c9c31a0020a0737b889532c8d7ec",
+},
+
+{
+ "#url" : "https://boards.4channel.org/tg/thread/15396072/",
+ "#category": ("", "4chan", "thread"),
+ "#class" : _4chan._4chanThreadExtractor,
+ "#sha1_url" : "39082ad166161966d7ba8e37f2173a824eb540f0",
+ "#sha1_metadata": "7ae2f4049adf0d2f835eb91b6b26b7f4ec882e0a",
+},
+
+{
+ "#url" : "https://boards.4channel.org/po/",
+ "#category": ("", "4chan", "board"),
+ "#class" : _4chan._4chanBoardExtractor,
+ "#pattern" : _4chan._4chanThreadExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+)
diff --git a/test/results/4chanarchives.py b/test/results/4chanarchives.py
new file mode 100644
index 00000000..8aa8befd
--- /dev/null
+++ b/test/results/4chanarchives.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.4chanarchives")
+_4chanarchives = getattr(gallery_dl.extractor, "4chanarchives")
+
+
+__tests__ = (
+{
+ "#url" : "https://4chanarchives.com/board/c/thread/2707110",
+ "#category": ("", "4chanarchives", "thread"),
+ "#class" : _4chanarchives._4chanarchivesThreadExtractor,
+ "#pattern" : r"https://i\.imgur\.com/(0wLGseE|qbByWDc)\.jpg",
+ "#count" : 2,
+
+ "board" : "c",
+ "com" : str,
+ "name" : "Anonymous",
+ "no" : int,
+ "thread": "2707110",
+ "time" : r"re:2016-07-1\d \d\d:\d\d:\d\d",
+ "title" : "Ren Kagami from 'Oyako Neburi'",
+},
+
+{
+ "#url" : "https://4chanarchives.com/board/c/",
+ "#category": ("", "4chanarchives", "board"),
+ "#class" : _4chanarchives._4chanarchivesBoardExtractor,
+ "#pattern" : _4chanarchives._4chanarchivesThreadExtractor.pattern,
+ "#range" : "1-40",
+ "#count" : 40,
+},
+
+{
+ "#url" : "https://4chanarchives.com/board/c",
+ "#category": ("", "4chanarchives", "board"),
+ "#class" : _4chanarchives._4chanarchivesBoardExtractor,
+},
+
+{
+ "#url" : "https://4chanarchives.com/board/c/10",
+ "#category": ("", "4chanarchives", "board"),
+ "#class" : _4chanarchives._4chanarchivesBoardExtractor,
+},
+
+)
diff --git a/test/results/4plebs.py b/test/results/4plebs.py
new file mode 100644
index 00000000..4f00027d
--- /dev/null
+++ b/test/results/4plebs.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://archive.4plebs.org/tg/thread/54059290",
+ "#category": ("foolfuuka", "4plebs", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "fd823f17b5001442b941fddcd9ec91bafedfbc79",
+},
+
+{
+ "#url" : "https://archive.4plebs.org/tg/",
+ "#category": ("foolfuuka", "4plebs", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://archive.4plebs.org/_/search/text/test/",
+ "#category": ("foolfuuka", "4plebs", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://archive.4plebs.org/tg/gallery/1",
+ "#category": ("foolfuuka", "4plebs", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/500px.py b/test/results/500px.py
new file mode 100644
index 00000000..39b618bc
--- /dev/null
+++ b/test/results/500px.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.500px")
+_500px = getattr(gallery_dl.extractor, "500px")
+
+
+__tests__ = (
+{
+ "#url" : "https://500px.com/p/light_expression_photography",
+ "#category": ("", "500px", "user"),
+ "#class" : _500px._500pxUserExtractor,
+ "#pattern" : r"https?://drscdn.500px.org/photo/\d+/m%3D4096/v2",
+ "#range" : "1-99",
+ "#count" : 99,
+},
+
+{
+ "#url" : "https://500px.com/light_expression_photography",
+ "#category": ("", "500px", "user"),
+ "#class" : _500px._500pxUserExtractor,
+},
+
+{
+ "#url" : "https://web.500px.com/light_expression_photography",
+ "#category": ("", "500px", "user"),
+ "#class" : _500px._500pxUserExtractor,
+},
+
+{
+ "#url" : "https://500px.com/p/fashvamp/galleries/lera",
+ "#category": ("", "500px", "gallery"),
+ "#class" : _500px._500pxGalleryExtractor,
+ "#count" : 3,
+ "#sha1_url": "002dc81dee5b4a655f0e31ad8349e8903b296df6",
+
+ "gallery": dict,
+ "user" : dict,
+},
+
+{
+ "#url" : "https://500px.com/fashvamp/galleries/lera",
+ "#category": ("", "500px", "gallery"),
+ "#class" : _500px._500pxGalleryExtractor,
+},
+
+{
+ "#url" : "https://500px.com/liked",
+ "#category": ("", "500px", "favorite"),
+ "#class" : _500px._500pxFavoriteExtractor,
+},
+
+{
+ "#url" : "https://500px.com/photo/222049255/queen-of-coasts",
+ "#category": ("", "500px", "image"),
+ "#class" : _500px._500pxImageExtractor,
+ "#count" : 1,
+ "#sha1_url": "fbdf7df39325cae02f5688e9f92935b0e7113315",
+
+ "camera" : "Canon EOS 600D",
+ "camera_info" : dict,
+ "comments" : list,
+ "comments_count" : int,
+ "created_at" : "2017-08-01T08:40:05+00:00",
+ "description" : str,
+ "editored_by" : None,
+ "editors_choice" : False,
+ "extension" : "jpg",
+ "feature" : "popular",
+ "feature_date" : "2017-08-01T09:58:28+00:00",
+ "focal_length" : "208",
+ "height" : 3111,
+ "id" : 222049255,
+ "image_format" : "jpg",
+ "image_url" : list,
+ "images" : list,
+ "iso" : "100",
+ "lens" : "EF-S55-250mm f/4-5.6 IS II",
+ "lens_info" : dict,
+ "liked" : None,
+ "location" : None,
+ "location_details": dict,
+ "name" : "Queen Of Coasts",
+ "nsfw" : False,
+ "privacy" : False,
+ "profile" : True,
+ "rating" : float,
+ "status" : 1,
+ "tags" : list,
+ "taken_at" : "2017-05-04T17:36:51+00:00",
+ "times_viewed" : int,
+ "url" : "/photo/222049255/Queen-Of-Coasts-by-Alice-Nabieva",
+ "user" : dict,
+ "user_id" : 12847235,
+ "votes_count" : int,
+ "watermark" : True,
+ "width" : 4637,
+},
+
+)
diff --git a/test/results/8chan.py b/test/results/8chan.py
new file mode 100644
index 00000000..43c08349
--- /dev/null
+++ b/test/results/8chan.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.8chan")
+_8chan = getattr(gallery_dl.extractor, "8chan")
+
+
+__tests__ = (
+{
+ "#url" : "https://8chan.moe/vhs/res/4.html",
+ "#category": ("", "8chan", "thread"),
+ "#class" : _8chan._8chanThreadExtractor,
+ "#pattern" : r"https://8chan\.moe/\.media/[0-9a-f]{64}\.\w+$",
+ "#count" : 14,
+
+ "archived" : False,
+ "autoSage" : False,
+ "boardDescription": "Film and Cinema",
+ "boardMarkdown" : None,
+ "boardName" : "Movies",
+ "boardUri" : "vhs",
+ "creation" : r"re:\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z",
+ "cyclic" : False,
+ "email" : None,
+ "id" : r"re:^[0-9a-f]{6}$",
+ "locked" : False,
+ "markdown" : str,
+ "maxFileCount" : 5,
+ "maxFileSize" : "32.00 MB",
+ "maxMessageLength": 8001,
+ "message" : str,
+ "mime" : str,
+ "name" : "Anonymous",
+ "num" : int,
+ "originalName" : str,
+ "path" : r"re:/.media/[0-9a-f]{64}\.\w+$",
+ "pinned" : False,
+ "postId" : int,
+ "signedRole" : None,
+ "size" : int,
+ "threadId" : 4,
+ "thumb" : r"re:/.media/t_[0-9a-f]{64}$",
+ "uniquePosters" : 9,
+ "usesCustomCss" : True,
+ "usesCustomJs" : False,
+ "?wsPort" : 8880,
+ "?wssPort" : 2087,
+},
+
+{
+ "#url" : "https://8chan.se/vhs/res/4.html",
+ "#category": ("", "8chan", "thread"),
+ "#class" : _8chan._8chanThreadExtractor,
+},
+
+{
+ "#url" : "https://8chan.cc/vhs/res/4.html",
+ "#category": ("", "8chan", "thread"),
+ "#class" : _8chan._8chanThreadExtractor,
+},
+
+{
+ "#url" : "https://8chan.moe/vhs/",
+ "#category": ("", "8chan", "board"),
+ "#class" : _8chan._8chanBoardExtractor,
+},
+
+{
+ "#url" : "https://8chan.moe/vhs/2.html",
+ "#category": ("", "8chan", "board"),
+ "#class" : _8chan._8chanBoardExtractor,
+ "#pattern" : _8chan._8chanThreadExtractor.pattern,
+ "#count" : 23,
+},
+
+{
+ "#url" : "https://8chan.se/vhs/",
+ "#category": ("", "8chan", "board"),
+ "#class" : _8chan._8chanBoardExtractor,
+},
+
+{
+ "#url" : "https://8chan.cc/vhs/",
+ "#category": ("", "8chan", "board"),
+ "#class" : _8chan._8chanBoardExtractor,
+},
+
+)
diff --git a/test/results/8kun.py b/test/results/8kun.py
new file mode 100644
index 00000000..53d16e13
--- /dev/null
+++ b/test/results/8kun.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import vichan
+
+
+__tests__ = (
+{
+ "#url" : "https://8kun.top/test/res/65248.html",
+ "#category": ("vichan", "8kun", "thread"),
+ "#class" : vichan.VichanThreadExtractor,
+ "#pattern" : r"https://media\.128ducks\.com/file_store/\w{64}\.\w+",
+ "#count" : ">= 8",
+},
+
+{
+ "#url" : "https://8kun.top/v/index.html",
+ "#category": ("vichan", "8kun", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+ "#pattern" : vichan.VichanThreadExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://8kun.top/v/2.html",
+ "#category": ("vichan", "8kun", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+},
+
+{
+ "#url" : "https://8kun.top/v/index.html?PageSpeed=noscript",
+ "#category": ("vichan", "8kun", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+},
+
+)
diff --git a/test/results/8muses.py b/test/results/8muses.py
new file mode 100644
index 00000000..da19e4ef
--- /dev/null
+++ b/test/results/8muses.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+gallery_dl = __import__("gallery_dl.extractor.8muses")
+_8muses = getattr(gallery_dl.extractor, "8muses")
+
+
+__tests__ = (
+{
+ "#url" : "https://comics.8muses.com/comics/album/Fakku-Comics/mogg/Liar",
+ "#category": ("", "8muses", "album"),
+ "#class" : _8muses._8musesAlbumExtractor,
+ "#pattern" : r"https://comics.8muses.com/image/fl/[\w-]+",
+ "#sha1_url": "6286ac33087c236c5a7e51f8a9d4e4d5548212d4",
+
+ "url" : str,
+ "hash" : str,
+ "page" : int,
+ "count": 6,
+ "album": {
+ "id" : 10467,
+ "title" : "Liar",
+ "path" : "Fakku Comics/mogg/Liar",
+ "parts" : [
+ "Fakku Comics",
+ "mogg",
+ "Liar",
+ ],
+ "private": False,
+ "url" : "https://comics.8muses.com/comics/album/Fakku-Comics/mogg/Liar",
+ "parent" : 10464,
+ "views" : int,
+ "likes" : int,
+ "date" : "dt:2018-07-10 00:00:00",
+ },
+},
+
+{
+ "#url" : "https://www.8muses.com/comics/album/Fakku-Comics/santa",
+ "#category": ("", "8muses", "album"),
+ "#class" : _8muses._8musesAlbumExtractor,
+ "#pattern" : _8muses._8musesAlbumExtractor.pattern,
+ "#count" : ">= 3",
+
+ "url" : str,
+ "name" : str,
+ "private": False,
+},
+
+{
+ "#url" : "https://www.8muses.com/comics/album/Fakku-Comics/11?sort=az",
+ "#comment" : "custom sorting",
+ "#category": ("", "8muses", "album"),
+ "#class" : _8muses._8musesAlbumExtractor,
+ "#count" : ">= 70",
+
+ "name": r"re:^[R-Zr-z]",
+},
+
+{
+ "#url" : "https://comics.8muses.com/comics/album/Various-Authors/Chessire88/From-Trainers-to-Pokmons",
+ "#comment" : "non-ASCII characters",
+ "#category": ("", "8muses", "album"),
+ "#class" : _8muses._8musesAlbumExtractor,
+ "#count" : 2,
+
+ "name": r"re:From Trainers to Pokémons",
+},
+
+)
diff --git a/test/results/94chan.py b/test/results/94chan.py
new file mode 100644
index 00000000..6e792e30
--- /dev/null
+++ b/test/results/94chan.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import jschan
+
+
+__tests__ = (
+{
+ "#url" : "https://94chan.org/art/thread/25.html",
+ "#category": ("jschan", "94chan", "thread"),
+ "#class" : jschan.JschanThreadExtractor,
+ "#pattern" : r"https://94chan.org/file/[0-9a-f]{64}(\.\w+)?",
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://94chan.org/art/",
+ "#category": ("jschan", "94chan", "board"),
+ "#class" : jschan.JschanBoardExtractor,
+ "#pattern" : jschan.JschanThreadExtractor.pattern,
+ "#count" : ">= 30",
+},
+
+{
+ "#url" : "https://94chan.org/art/2.html",
+ "#category": ("jschan", "94chan", "board"),
+ "#class" : jschan.JschanBoardExtractor,
+},
+
+{
+ "#url" : "https://94chan.org/art/catalog.html",
+ "#category": ("jschan", "94chan", "board"),
+ "#class" : jschan.JschanBoardExtractor,
+},
+
+{
+ "#url" : "https://94chan.org/art/index.html",
+ "#category": ("jschan", "94chan", "board"),
+ "#class" : jschan.JschanBoardExtractor,
+},
+
+)
diff --git a/test/results/__init__.py b/test/results/__init__.py
new file mode 100644
index 00000000..0fe87462
--- /dev/null
+++ b/test/results/__init__.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+import os
+import sys
+import functools
+
+__directory__ = os.path.dirname(__file__)
+
+
+@functools.lru_cache(maxsize=None)
+def tests(name):
+ try:
+ module = __import__(name, globals(), None, (), 1)
+ return module.__tests__
+ except Exception as exc:
+ print(exc)
+ return ()
+
+
+def all():
+ ignore = ("__init__.py", "__pycache__")
+ for filename in os.listdir(__directory__):
+ if filename not in ignore:
+ yield from tests(filename[:-3])
+
+
+def category(category):
+ return tests(category.replace(".", ""))
diff --git a/test/results/acidimg.py b/test/results/acidimg.py
new file mode 100644
index 00000000..d61a7736
--- /dev/null
+++ b/test/results/acidimg.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://acidimg.cc/img-5acb6b9de4640.html",
+ "#category": ("imagehost", "acidimg", "image"),
+ "#class" : imagehosts.AcidimgImageExtractor,
+ "#sha1_url" : "f132a630006e8d84f52d59555191ed82b3b64c04",
+ "#sha1_metadata": "135347ab4345002fc013863c0d9419ba32d98f78",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+)
diff --git a/test/results/adultempire.py b/test/results/adultempire.py
new file mode 100644
index 00000000..1a2953ef
--- /dev/null
+++ b/test/results/adultempire.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import adultempire
+
+
+__tests__ = (
+{
+ "#url" : "https://www.adultempire.com/5998/gallery.html",
+ "#category": ("", "adultempire", "gallery"),
+ "#class" : adultempire.AdultempireGalleryExtractor,
+ "#range" : "1",
+ "#sha1_metadata": "5b3266e69801db0d78c22181da23bc102886e027",
+ "#sha1_content" : "5c6beb31e5e3cdc90ee5910d5c30f9aaec977b9e",
+},
+
+{
+ "#url" : "https://www.adultdvdempire.com/5683/gallery.html",
+ "#category": ("", "adultempire", "gallery"),
+ "#class" : adultempire.AdultempireGalleryExtractor,
+ "#sha1_url" : "b12cd1a65cae8019d837505adb4d6a2c1ed4d70d",
+ "#sha1_metadata": "8d448d79c4ac5f5b10a3019d5b5129ddb43655e5",
+},
+
+)
diff --git a/test/results/aibooru.py b/test/results/aibooru.py
new file mode 100644
index 00000000..78bd7273
--- /dev/null
+++ b/test/results/aibooru.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import danbooru
+
+
+__tests__ = (
+{
+ "#url" : "https://aibooru.online/posts?tags=center_frills&z=1",
+ "#category": ("Danbooru", "aibooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#pattern" : r"https://cdn\.aibooru\.online/original/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{32}\.\w+",
+ "#count" : ">= 3",
+},
+
+{
+ "#url" : "https://safe.aibooru.online/posts?tags=center_frills",
+ "#category": ("Danbooru", "aibooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+},
+
+{
+ "#url" : "https://aibooru.online/pools/1",
+ "#category": ("Danbooru", "aibooru", "pool"),
+ "#class" : danbooru.DanbooruPoolExtractor,
+},
+
+{
+ "#url" : "https://aibooru.online/posts/1",
+ "#category": ("Danbooru", "aibooru", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+ "#sha1_content": "54d548743cd67799a62c77cbae97cfa0fec1b7e9",
+},
+
+{
+ "#url" : "https://aibooru.online/explore/posts/popular",
+ "#category": ("Danbooru", "aibooru", "popular"),
+ "#class" : danbooru.DanbooruPopularExtractor,
+},
+
+)
diff --git a/test/results/allgirlbooru.py b/test/results/allgirlbooru.py
new file mode 100644
index 00000000..e1bfc11f
--- /dev/null
+++ b/test/results/allgirlbooru.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v01
+
+
+__tests__ = (
+{
+ "#url" : "https://allgirl.booru.org/index.php?page=post&s=list&tags=dress",
+ "#category": ("gelbooru_v01", "allgirlbooru", "tag"),
+ "#class" : gelbooru_v01.GelbooruV01TagExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://allgirl.booru.org/index.php?page=favorites&s=view&id=380",
+ "#category": ("gelbooru_v01", "allgirlbooru", "favorite"),
+ "#class" : gelbooru_v01.GelbooruV01FavoriteExtractor,
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://allgirl.booru.org/index.php?page=post&s=view&id=107213",
+ "#category": ("gelbooru_v01", "allgirlbooru", "post"),
+ "#class" : gelbooru_v01.GelbooruV01PostExtractor,
+ "#sha1_url" : "b416800d2d2b072f80d3b37cfca9cb806fb25d51",
+ "#sha1_content": "3e3c65e0854a988696e11adf0de52f8fa90a51c7",
+
+ "created_at": "2021-02-13 16:27:39",
+ "date" : "dt:2021-02-13 16:27:39",
+ "file_url" : "https://img.booru.org/allgirl//images/107/2aaa0438d58fc7baa75a53b4a9621bb89a9d3fdb.jpg",
+ "height" : "1200",
+ "id" : "107213",
+ "md5" : "2aaa0438d58fc7baa75a53b4a9621bb89a9d3fdb",
+ "rating" : "s",
+ "score" : str,
+ "source" : "",
+ "tags" : "blush dress green_eyes green_hair hatsune_miku long_hair twintails vocaloid",
+ "uploader" : "Honochi31",
+ "width" : "1600",
+},
+
+)
diff --git a/test/results/animereactor.py b/test/results/animereactor.py
new file mode 100644
index 00000000..a83ac6ff
--- /dev/null
+++ b/test/results/animereactor.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import reactor
+
+
+__tests__ = (
+{
+ "#url" : "http://anime.reactor.cc/tag/Anime+Art",
+ "#category": ("reactor", "anime.reactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+},
+
+{
+ "#url" : "http://anime.reactor.cc/user/Shuster",
+ "#category": ("reactor", "anime.reactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+},
+
+{
+ "#url" : "http://anime.reactor.cc/post/3576250",
+ "#category": ("reactor", "anime.reactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+},
+
+)
diff --git a/test/results/architizer.py b/test/results/architizer.py
new file mode 100644
index 00000000..3a751556
--- /dev/null
+++ b/test/results/architizer.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import architizer
+
+
+__tests__ = (
+{
+ "#url" : "https://architizer.com/projects/house-lo/",
+ "#category": ("", "architizer", "project"),
+ "#class" : architizer.ArchitizerProjectExtractor,
+ "#pattern" : r"https://architizer-prod\.imgix\.net/media/mediadata/uploads/.+\.jpg$",
+
+ "count" : 27,
+ "description": str,
+ "firm" : "Atelier Lina Bellovicova",
+ "gid" : "225496",
+ "location" : "Czechia",
+ "num" : int,
+ "size" : "1000 sqft - 3000 sqft",
+ "slug" : "house-lo",
+ "status" : "Built",
+ "subcategory": "project",
+ "title" : "House LO",
+ "type" : "Residential › Private House",
+ "year" : "2020",
+},
+
+{
+ "#url" : "https://architizer.com/firms/olson-kundig/",
+ "#category": ("", "architizer", "firm"),
+ "#class" : architizer.ArchitizerFirmExtractor,
+ "#pattern" : architizer.ArchitizerProjectExtractor.pattern,
+ "#count" : ">= 90",
+},
+
+)
diff --git a/test/results/archivedmoe.py b/test/results/archivedmoe.py
new file mode 100644
index 00000000..90b48877
--- /dev/null
+++ b/test/results/archivedmoe.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://archived.moe/gd/thread/309639/",
+ "#category": ("foolfuuka", "archivedmoe", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url" : "fdd533840e2d535abd162c02d6dfadbc12e2dcd8",
+ "#sha1_content": "c27e2a7be3bc989b5dd859f7789cc854db3f5573",
+},
+
+{
+ "#url" : "https://archived.moe/a/thread/159767162/",
+ "#category": ("foolfuuka", "archivedmoe", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "ffec05a1a1b906b5ca85992513671c9155ee9e87",
+},
+
+{
+ "#url" : "https://archived.moe/gd/",
+ "#category": ("foolfuuka", "archivedmoe", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://archived.moe/_/search/text/test/",
+ "#category": ("foolfuuka", "archivedmoe", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://archived.moe/gd/gallery/2",
+ "#category": ("foolfuuka", "archivedmoe", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/archiveofsins.py b/test/results/archiveofsins.py
new file mode 100644
index 00000000..3f3fcb93
--- /dev/null
+++ b/test/results/archiveofsins.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://archiveofsins.com/h/thread/4668813/",
+ "#category": ("foolfuuka", "archiveofsins", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url" : "f612d287087e10a228ef69517cf811539db9a102",
+ "#sha1_content": "0dd92d0d8a7bf6e2f7d1f5ac8954c1bcf18c22a4",
+},
+
+{
+ "#url" : "https://archiveofsins.com/h/",
+ "#category": ("foolfuuka", "archiveofsins", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://archiveofsins.com/_/search/text/test/",
+ "#category": ("foolfuuka", "archiveofsins", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://archiveofsins.com/_/search/text/test/",
+ "#category": ("foolfuuka", "archiveofsins", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://archiveofsins.com/h/gallery/3",
+ "#category": ("foolfuuka", "archiveofsins", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/artstation.py b/test/results/artstation.py
new file mode 100644
index 00000000..262bad88
--- /dev/null
+++ b/test/results/artstation.py
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import artstation
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.artstation.com/sungchoi/",
+ "#category": ("", "artstation", "user"),
+ "#class" : artstation.ArtstationUserExtractor,
+ "#pattern" : r"https://\w+\.artstation\.com/p/assets/images/images/\d+/\d+/\d+/(4k|large|medium|small)/[^/]+",
+ "#range" : "1-10",
+ "#count" : ">= 10",
+},
+
+{
+ "#url" : "https://www.artstation.com/sungchoi/albums/all/",
+ "#category": ("", "artstation", "user"),
+ "#class" : artstation.ArtstationUserExtractor,
+},
+
+{
+ "#url" : "https://sungchoi.artstation.com/",
+ "#category": ("", "artstation", "user"),
+ "#class" : artstation.ArtstationUserExtractor,
+},
+
+{
+ "#url" : "https://sungchoi.artstation.com/projects/",
+ "#category": ("", "artstation", "user"),
+ "#class" : artstation.ArtstationUserExtractor,
+},
+
+{
+ "#url" : "https://www.artstation.com/huimeiye/albums/770899",
+ "#category": ("", "artstation", "album"),
+ "#class" : artstation.ArtstationAlbumExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.artstation.com/huimeiye/albums/770898",
+ "#category": ("", "artstation", "album"),
+ "#class" : artstation.ArtstationAlbumExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://huimeiye.artstation.com/albums/770899",
+ "#category": ("", "artstation", "album"),
+ "#class" : artstation.ArtstationAlbumExtractor,
+},
+
+{
+ "#url" : "https://www.artstation.com/mikf/likes",
+ "#category": ("", "artstation", "likes"),
+ "#class" : artstation.ArtstationLikesExtractor,
+ "#pattern" : r"https://\w+\.artstation\.com/p/assets/images/images/\d+/\d+/\d+/(4k|large|medium|small)/[^/]+",
+ "#count" : 6,
+},
+
+{
+ "#url" : "https://www.artstation.com/sungchoi/likes",
+ "#comment" : "no likes",
+ "#category": ("", "artstation", "likes"),
+ "#class" : artstation.ArtstationLikesExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.artstation.com/contests/thu-2017/challenges/20",
+ "#category": ("", "artstation", "challenge"),
+ "#class" : artstation.ArtstationChallengeExtractor,
+},
+
+{
+ "#url" : "https://www.artstation.com/contests/beyond-human/challenges/23?sorting=winners",
+ "#category": ("", "artstation", "challenge"),
+ "#class" : artstation.ArtstationChallengeExtractor,
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://www.artstation.com/search?query=ancient&sort_by=rank",
+ "#category": ("", "artstation", "search"),
+ "#class" : artstation.ArtstationSearchExtractor,
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.artstation.com/artwork?sorting=latest",
+ "#category": ("", "artstation", "artwork"),
+ "#class" : artstation.ArtstationArtworkExtractor,
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.artstation.com/artwork/LQVJr",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+ "#pattern" : r"https?://\w+\.artstation\.com/p/assets/images/images/008/760/279/4k/.+",
+ "#sha1_content": "7b113871465fdc09d127adfdc2767d51cf45a7e9",
+},
+
+{
+ "#url" : "https://www.artstation.com/artwork/Db3dy",
+ "#comment" : "multiple images per project",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://www.artstation.com/artwork/g4WPK",
+ "#comment" : "embedded youtube video",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+ "#options" : {"external": True},
+ "#pattern" : "ytdl:https://www.youtube.com/embed/JNFfJtwwrU0",
+ "#range" : "2",
+},
+
+{
+ "#url" : "https://www.artstation.com/artwork/3q3mXB",
+ "#comment" : "404 (#3016)",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://sungchoi.artstation.com/projects/LQVJr",
+ "#comment" : "alternate URL patterns",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+},
+
+{
+ "#url" : "https://artstn.co/p/LQVJr",
+ "#category": ("", "artstation", "image"),
+ "#class" : artstation.ArtstationImageExtractor,
+},
+
+{
+ "#url" : "https://www.artstation.com/sungchoi/following",
+ "#category": ("", "artstation", "following"),
+ "#class" : artstation.ArtstationFollowingExtractor,
+ "#pattern" : artstation.ArtstationUserExtractor.pattern,
+ "#count" : ">= 50",
+},
+
+)
diff --git a/test/results/aryion.py b/test/results/aryion.py
new file mode 100644
index 00000000..8b91e342
--- /dev/null
+++ b/test/results/aryion.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import aryion
+
+
+__tests__ = (
+{
+ "#url" : "https://aryion.com/g4/gallery/jameshoward",
+ "#category": ("", "aryion", "gallery"),
+ "#class" : aryion.AryionGalleryExtractor,
+ "#options" : {"recursive": False},
+ "#pattern" : r"https://aryion\.com/g4/data\.php\?id=\d+$",
+ "#range" : "48-52",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://aryion.com/g4/user/jameshoward",
+ "#category": ("", "aryion", "gallery"),
+ "#class" : aryion.AryionGalleryExtractor,
+},
+
+{
+ "#url" : "https://aryion.com/g4/latest.php?name=jameshoward",
+ "#category": ("", "aryion", "gallery"),
+ "#class" : aryion.AryionGalleryExtractor,
+},
+
+{
+ "#url" : "https://aryion.com/g4/tags.php?tag=star+wars&p=19",
+ "#category": ("", "aryion", "tag"),
+ "#class" : aryion.AryionTagExtractor,
+ "#count" : ">= 5",
+},
+
+{
+ "#url" : "https://aryion.com/g4/view/510079",
+ "#category": ("", "aryion", "post"),
+ "#class" : aryion.AryionPostExtractor,
+ "#sha1_url": "f233286fa5558c07ae500f7f2d5cb0799881450e",
+
+ "artist" : "jameshoward",
+ "user" : "jameshoward",
+ "filename" : "jameshoward-510079-subscribestar_150",
+ "extension" : "jpg",
+ "id" : 510079,
+ "width" : 1665,
+ "height" : 1619,
+ "size" : 784239,
+ "title" : "I'm on subscribestar now too!",
+ "description": r"re:Doesn't hurt to have a backup, right\?",
+ "tags" : [
+ "Non-Vore",
+ "subscribestar",
+ ],
+ "date" : "dt:2019-02-16 19:30:34",
+ "path" : [],
+ "views" : int,
+ "favorites" : int,
+ "comments" : int,
+ "_mtime" : "Sat, 16 Feb 2019 19:30:34 GMT",
+},
+
+{
+ "#url" : "https://aryion.com/g4/view/588928",
+ "#comment" : "x-folder (#694)",
+ "#category": ("", "aryion", "post"),
+ "#class" : aryion.AryionPostExtractor,
+ "#pattern" : aryion.AryionPostExtractor.pattern,
+ "#count" : ">= 8",
+},
+
+{
+ "#url" : "https://aryion.com/g4/view/537379",
+ "#comment" : "x-comic-folder (#945)",
+ "#category": ("", "aryion", "post"),
+ "#class" : aryion.AryionPostExtractor,
+ "#pattern" : aryion.AryionPostExtractor.pattern,
+ "#count" : 2,
+},
+
+)
diff --git a/test/results/atfbooru.py b/test/results/atfbooru.py
new file mode 100644
index 00000000..4bdd1b6d
--- /dev/null
+++ b/test/results/atfbooru.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import danbooru
+
+
+__tests__ = (
+{
+ "#url" : "https://booru.allthefallen.moe/posts?tags=yume_shokunin",
+ "#category": ("Danbooru", "atfbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#count" : 12,
+},
+
+{
+ "#url" : "https://booru.allthefallen.moe/pools/9",
+ "#category": ("Danbooru", "atfbooru", "pool"),
+ "#class" : danbooru.DanbooruPoolExtractor,
+ "#count" : 6,
+ "#sha1_url": "902549ffcdb00fe033c3f63e12bc3cb95c5fd8d5",
+},
+
+{
+ "#url" : "https://booru.allthefallen.moe/posts/22",
+ "#category": ("Danbooru", "atfbooru", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+ "#sha1_content": "21dda68e1d7e0a554078e62923f537d8e895cac8",
+},
+
+{
+ "#url" : "https://booru.allthefallen.moe/explore/posts/popular",
+ "#category": ("Danbooru", "atfbooru", "popular"),
+ "#class" : danbooru.DanbooruPopularExtractor,
+},
+
+)
diff --git a/test/results/b4k.py b/test/results/b4k.py
new file mode 100644
index 00000000..5a2c13c2
--- /dev/null
+++ b/test/results/b4k.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://arch.b4k.co/meta/thread/196/",
+ "#category": ("foolfuuka", "b4k", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "d309713d2f838797096b3e9cb44fe514a9c9d07a",
+},
+
+{
+ "#url" : "https://arch.b4k.co/meta/",
+ "#category": ("foolfuuka", "b4k", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://arch.b4k.co/meta/gallery/",
+ "#category": ("foolfuuka", "b4k", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/baraag.py b/test/results/baraag.py
new file mode 100644
index 00000000..567d12c5
--- /dev/null
+++ b/test/results/baraag.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mastodon
+
+
+__tests__ = (
+{
+ "#url" : "https://baraag.net/@pumpkinnsfw",
+ "#category": ("mastodon", "baraag", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://baraag.net/bookmarks",
+ "#category": ("mastodon", "baraag", "bookmark"),
+ "#class" : mastodon.MastodonBookmarkExtractor,
+},
+
+{
+ "#url" : "https://baraag.net/users/pumpkinnsfw/following",
+ "#category": ("mastodon", "baraag", "following"),
+ "#class" : mastodon.MastodonFollowingExtractor,
+},
+
+{
+ "#url" : "https://baraag.net/@pumpkinnsfw/104364170556898443",
+ "#category": ("mastodon", "baraag", "status"),
+ "#class" : mastodon.MastodonStatusExtractor,
+ "#sha1_content": "67748c1b828c58ad60d0fe5729b59fb29c872244",
+},
+
+)
diff --git a/test/results/bbc.py b/test/results/bbc.py
new file mode 100644
index 00000000..83b4923c
--- /dev/null
+++ b/test/results/bbc.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import bbc
+
+
+__tests__ = (
+{
+ "#url" : "https://www.bbc.co.uk/programmes/p084qtzs/p085g9kg",
+ "#category": ("", "bbc", "gallery"),
+ "#class" : bbc.BbcGalleryExtractor,
+ "#pattern" : r"https://ichef\.bbci\.co\.uk/images/ic/1920xn/\w+\.jpg",
+ "#count" : 37,
+
+ "programme": "p084qtzs",
+ "path" : [
+ "BBC One",
+ "Doctor Who",
+ "The Timeless Children",
+ ],
+},
+
+{
+ "#url" : "https://www.bbc.co.uk/programmes/p084qtzs",
+ "#category": ("", "bbc", "gallery"),
+ "#class" : bbc.BbcGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.bbc.co.uk/programmes/b006q2x0/galleries",
+ "#category": ("", "bbc", "programme"),
+ "#class" : bbc.BbcProgrammeExtractor,
+ "#pattern" : bbc.BbcGalleryExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : ">= 50",
+},
+
+{
+ "#url" : "https://www.bbc.co.uk/programmes/b006q2x0/galleries?page=40",
+ "#category": ("", "bbc", "programme"),
+ "#class" : bbc.BbcProgrammeExtractor,
+ "#pattern" : bbc.BbcGalleryExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+)
diff --git a/test/results/bbw-chan.py b/test/results/bbw-chan.py
new file mode 100644
index 00000000..74913ff9
--- /dev/null
+++ b/test/results/bbw-chan.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lynxchan
+
+
+__tests__ = (
+{
+ "#url" : "https://bbw-chan.nl/bbwdraw/res/499.html",
+ "#category": ("lynxchan", "bbw-chan", "thread"),
+ "#class" : lynxchan.LynxchanThreadExtractor,
+ "#pattern" : r"https://bbw-chan\.nl/\.media/[0-9a-f]{64}(\.\w+)?$",
+ "#count" : ">= 352",
+},
+
+{
+ "#url" : "https://bbw-chan.nl/bbwdraw/res/489.html",
+ "#category": ("lynxchan", "bbw-chan", "thread"),
+ "#class" : lynxchan.LynxchanThreadExtractor,
+},
+
+{
+ "#url" : "https://bbw-chan.nl/bbwdraw/",
+ "#category": ("lynxchan", "bbw-chan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+ "#pattern" : lynxchan.LynxchanThreadExtractor.pattern,
+ "#count" : ">= 148",
+},
+
+{
+ "#url" : "https://bbw-chan.nl/bbwdraw/2.html",
+ "#category": ("lynxchan", "bbw-chan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+},
+
+)
diff --git a/test/results/bcbnsfw.py b/test/results/bcbnsfw.py
new file mode 100644
index 00000000..8d35e36e
--- /dev/null
+++ b/test/results/bcbnsfw.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import szurubooru
+
+
+__tests__ = (
+{
+ "#url" : "https://booru.bcbnsfw.space/posts/query=simple_background",
+ "#category": ("szurubooru", "bcbnsfw", "tag"),
+ "#class" : szurubooru.SzurubooruTagExtractor,
+},
+
+{
+ "#url" : "https://booru.bcbnsfw.space/post/1599",
+ "#category": ("szurubooru", "bcbnsfw", "post"),
+ "#class" : szurubooru.SzurubooruPostExtractor,
+ "#pattern" : r"https://booru\.bcbnsfw\.space/data/posts/1599_53784518e92086bd\.png",
+ "#sha1_content": "0c38fc612ba1f03950fad31c4f80a1fccdab1096",
+},
+
+)
diff --git a/test/results/behance.py b/test/results/behance.py
new file mode 100644
index 00000000..7b39b5b4
--- /dev/null
+++ b/test/results/behance.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import behance
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.behance.net/gallery/17386197/A-Short-Story",
+ "#category": ("", "behance", "gallery"),
+ "#class" : behance.BehanceGalleryExtractor,
+ "#count" : 2,
+ "#sha1_url": "ab79bd3bef8d3ae48e6ac74fd995c1dfaec1b7d2",
+
+ "id" : 17386197,
+ "name" : r"re:\"Hi\". A short story about the important things ",
+ "owners": [
+ "Place Studio",
+ "Julio César Velazquez",
+ ],
+ "fields": [
+ "Animation",
+ "Character Design",
+ "Directing",
+ ],
+ "tags" : list,
+ "module": dict,
+ "date" : "dt:2014-06-03 15:41:51",
+},
+
+{
+ "#url" : "https://www.behance.net/gallery/21324767/Nevada-City",
+ "#category": ("", "behance", "gallery"),
+ "#class" : behance.BehanceGalleryExtractor,
+ "#count" : 6,
+ "#sha1_url": "0258fe194fe7d828d6f2c7f6086a9a0a4140db1d",
+
+ "owners": ["Alex Strohl"],
+},
+
+{
+ "#url" : "https://www.behance.net/gallery/88276087/Audi-R8-RWD",
+ "#comment" : "'media_collection' modules",
+ "#category": ("", "behance", "gallery"),
+ "#class" : behance.BehanceGalleryExtractor,
+ "#pattern" : r"https://mir-s3-cdn-cf\.behance\.net/project_modules/source/[0-9a-f]+.[0-9a-f]+\.jpg",
+ "#count" : 20,
+ "#sha1_url": "6bebff0d37f85349f9ad28bd8b76fd66627c1e2f",
+},
+
+{
+ "#url" : "https://www.behance.net/gallery/101185577/COLCCI",
+ "#comment" : "'video' modules (#1282)",
+ "#category": ("", "behance", "gallery"),
+ "#class" : behance.BehanceGalleryExtractor,
+ "#pattern" : r"https://cdn-prod-ccv\.adobe\.com/\w+/rend/\w+_720\.mp4\?",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.behance.net/gallery/177464639/Kimori",
+ "#comment" : "mature content (#4417)",
+ "#category": ("", "behance", "gallery"),
+ "#class" : behance.BehanceGalleryExtractor,
+ "#exception": exception.AuthorizationError,
+},
+
+{
+ "#url" : "https://www.behance.net/alexstrohl",
+ "#category": ("", "behance", "user"),
+ "#class" : behance.BehanceUserExtractor,
+ "#pattern" : behance.BehanceGalleryExtractor.pattern,
+ "#count" : ">= 11",
+},
+
+{
+ "#url" : "https://www.behance.net/collection/71340149/inspiration",
+ "#category": ("", "behance", "collection"),
+ "#class" : behance.BehanceCollectionExtractor,
+ "#pattern" : behance.BehanceGalleryExtractor.pattern,
+ "#count" : ">= 150",
+},
+
+)
diff --git a/test/results/bitly.py b/test/results/bitly.py
new file mode 100644
index 00000000..cbfcf0eb
--- /dev/null
+++ b/test/results/bitly.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import urlshortener
+
+
+__tests__ = (
+{
+ "#url" : "https://bit.ly/3cWIUgq",
+ "#category": ("urlshortener", "bitly", "link"),
+ "#class" : urlshortener.UrlshortenerLinkExtractor,
+ "#pattern" : "^https://gumroad.com/l/storm_b1",
+ "#count" : 1,
+},
+
+)
diff --git a/test/results/blogger.py b/test/results/blogger.py
new file mode 100644
index 00000000..214d450d
--- /dev/null
+++ b/test/results/blogger.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import blogger
+
+
+__tests__ = (
+{
+ "#url" : "https://julianbphotography.blogspot.com/2010/12/moon-rise.html",
+ "#category": ("", "blogger", "post"),
+ "#class" : blogger.BloggerPostExtractor,
+ "#pattern" : "https://3.bp.blogspot.com/.*/s0/Icy-Moonrise-.*.jpg",
+ "#sha1_url": "9928429fb62f712eb4de80f53625eccecc614aae",
+
+ "blog": {
+ "date" : "dt:2010-11-21 18:19:42",
+ "description": "",
+ "id" : "5623928067739466034",
+ "kind" : "blogger#blog",
+ "locale" : dict,
+ "name" : "Julian Bunker Photography",
+ "pages" : int,
+ "posts" : int,
+ "published" : "2010-11-21T10:19:42-08:00",
+ "updated" : str,
+ "url" : "http://julianbphotography.blogspot.com/",
+ },
+ "post": {
+ "author" : "Julian Bunker",
+ "content" : str,
+ "date" : "dt:2010-12-26 01:08:00",
+ "etag" : str,
+ "id" : "6955139236418998998",
+ "kind" : "blogger#post",
+ "published": "2010-12-25T17:08:00-08:00",
+ "replies" : "0",
+ "title" : "Moon Rise",
+ "updated" : "2011-12-06T05:21:24-08:00",
+ "url" : r"re:.+/2010/12/moon-rise.html$",
+ },
+ "num" : int,
+ "url" : str,
+},
+
+{
+ "#url" : "blogger:http://www.julianbunker.com/2010/12/moon-rise.html",
+ "#category": ("", "blogger", "post"),
+ "#class" : blogger.BloggerPostExtractor,
+},
+
+{
+ "#url" : "http://cfnmscenesinmovies.blogspot.com/2011/11/cfnm-scene-jenna-fischer-in-office.html",
+ "#comment" : "video (#587)",
+ "#category": ("", "blogger", "post"),
+ "#class" : blogger.BloggerPostExtractor,
+ "#pattern" : r"https://.+\.googlevideo\.com/videoplayback",
+},
+
+{
+ "#url" : "https://randomthingsthroughmyletterbox.blogspot.com/2022/01/bitter-flowers-by-gunnar-staalesen-blog.html",
+ "#comment" : "new image domain (#2204)",
+ "#category": ("", "blogger", "post"),
+ "#class" : blogger.BloggerPostExtractor,
+ "#pattern" : "https://blogger.googleusercontent.com/img/a/.+=s0$",
+ "#count" : 8,
+},
+
+{
+ "#url" : "https://julianbphotography.blogspot.com/",
+ "#category": ("", "blogger", "blog"),
+ "#class" : blogger.BloggerBlogExtractor,
+ "#pattern" : r"https://\d\.bp\.blogspot\.com/.*/s0/[^.]+\.jpg",
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "blogger:https://www.kefblog.com.ng/",
+ "#category": ("", "blogger", "blog"),
+ "#class" : blogger.BloggerBlogExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://julianbphotography.blogspot.com/search?q=400mm",
+ "#category": ("", "blogger", "search"),
+ "#class" : blogger.BloggerSearchExtractor,
+ "#count" : "< 10",
+
+ "query": "400mm",
+},
+
+{
+ "#url" : "https://dmmagazine.blogspot.com/search/label/D%26D",
+ "#category": ("", "blogger", "label"),
+ "#class" : blogger.BloggerLabelExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+
+ "label": "D&D",
+},
+
+)
diff --git a/test/results/booruvar.py b/test/results/booruvar.py
new file mode 100644
index 00000000..8beb45e1
--- /dev/null
+++ b/test/results/booruvar.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import danbooru
+
+
+__tests__ = (
+{
+ "#url" : "https://booru.borvar.art/posts?tags=chibi&z=1",
+ "#category": ("Danbooru", "booruvar", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#pattern" : r"https://booru\.borvar\.art/data/original/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{32}\.\w+",
+ "#count" : ">= 3",
+},
+
+{
+ "#url" : "https://booru.borvar.art/pools/2",
+ "#category": ("Danbooru", "booruvar", "pool"),
+ "#class" : danbooru.DanbooruPoolExtractor,
+ "#count" : 4,
+ "#sha1_url": "77fa3559a3fc919f72611f4e3dd0f919d19d3e0d",
+},
+
+{
+ "#url" : "https://booru.borvar.art/posts/1487",
+ "#category": ("Danbooru", "booruvar", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+ "#sha1_content": "91273ac1ea413a12be468841e2b5804656a50bff",
+},
+
+{
+ "#url" : "https://booru.borvar.art/explore/posts/popular",
+ "#category": ("Danbooru", "booruvar", "popular"),
+ "#class" : danbooru.DanbooruPopularExtractor,
+},
+
+)
diff --git a/test/results/bunkr.py b/test/results/bunkr.py
new file mode 100644
index 00000000..5a66d02c
--- /dev/null
+++ b/test/results/bunkr.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import bunkr
+
+
+__tests__ = (
+{
+ "#url" : "https://bunkrr.su/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+ "#pattern" : r"https://cdn\.bunkr\.ru/test-テスト-\"&>-QjgneIQv\.png",
+ "#sha1_content": "0c8768055e4e20e7c7259608b67799171b691140",
+
+ "album_id" : "Lktg9Keq",
+ "album_name": "test テスト \"&>",
+ "count" : 1,
+ "filename" : "test-テスト-\"&>-QjgneIQv",
+ "id" : "QjgneIQv",
+ "name" : "test-テスト-\"&>",
+ "num" : int,
+},
+
+{
+ "#url" : "https://app.bunkr.ru/a/ptRHaCn2",
+ "#comment" : "mp4 (#2239)",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+ "#pattern" : r"https://media-files\.bunkr\.ru/_-RnHoW69L\.mp4",
+ "#sha1_content": "80e61d1dbc5896ae7ef9a28734c747b28b320471",
+},
+
+{
+ "#url" : "https://bunkr.is/a/iXTTc1o2",
+ "#comment" : "cdn4",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+ "#pattern" : r"https://(cdn|media-files)4\.bunkr\.ru/",
+ "#sha1_content": "da29aae371b7adc8c5ef8e6991b66b69823791e8",
+
+ "album_id" : "iXTTc1o2",
+ "album_name" : "test2",
+ "album_size" : "691.1 KB",
+ "count" : 2,
+ "description": "072022",
+ "filename" : r"re:video-wFO9FtxG|image-sZrQUeOx",
+ "id" : r"re:wFO9FtxG|sZrQUeOx",
+ "name" : r"re:video|image",
+ "num" : int,
+},
+
+{
+ "#url" : "https://bunkrr.su/a/j1G29CnD",
+ "#comment" : "cdn12 .ru TLD (#4147)",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+ "#pattern" : r"https://(cdn12.bunkr.ru|media-files12.bunkr.la)/\w+",
+ "#count" : 8,
+},
+
+{
+ "#url" : "https://bunkrr.su/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+{
+ "#url" : "https://bunkr.la/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+{
+ "#url" : "https://bunkr.su/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+{
+ "#url" : "https://bunkr.ru/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+{
+ "#url" : "https://bunkr.is/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+{
+ "#url" : "https://bunkr.to/a/Lktg9Keq",
+ "#category": ("lolisafe", "bunkr", "album"),
+ "#class" : bunkr.BunkrAlbumExtractor,
+},
+
+)
diff --git a/test/results/catbox.py b/test/results/catbox.py
new file mode 100644
index 00000000..b977a52e
--- /dev/null
+++ b/test/results/catbox.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import catbox
+
+
+__tests__ = (
+{
+ "#url" : "https://catbox.moe/c/1igcbe",
+ "#category": ("", "catbox", "album"),
+ "#class" : catbox.CatboxAlbumExtractor,
+ "#pattern" : r"https://files\.catbox\.moe/\w+\.\w{3}$",
+ "#count" : 3,
+ "#sha1_url" : "35866a88c29462814f103bc22ec031eaeb380f8a",
+ "#sha1_content": "70ddb9de3872e2d17cc27e48e6bf395e5c8c0b32",
+
+ "album_id" : "1igcbe",
+ "album_name" : "test",
+ "date" : "dt:2022-08-18 00:00:00",
+ "description": "album test &>",
+},
+
+{
+ "#url" : "https://www.catbox.moe/c/cd90s1",
+ "#category": ("", "catbox", "album"),
+ "#class" : catbox.CatboxAlbumExtractor,
+},
+
+{
+ "#url" : "https://catbox.moe/c/w7tm47#",
+ "#category": ("", "catbox", "album"),
+ "#class" : catbox.CatboxAlbumExtractor,
+},
+
+{
+ "#url" : "https://files.catbox.moe/8ih3y7.png",
+ "#category": ("", "catbox", "file"),
+ "#class" : catbox.CatboxFileExtractor,
+ "#pattern" : r"^https://files\.catbox\.moe/8ih3y7\.png$",
+ "#count" : 1,
+ "#sha1_content": "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+{
+ "#url" : "https://litter.catbox.moe/t8v3n9.png",
+ "#category": ("", "catbox", "file"),
+ "#class" : catbox.CatboxFileExtractor,
+},
+
+{
+ "#url" : "https://de.catbox.moe/bjdmz1.jpg",
+ "#category": ("", "catbox", "file"),
+ "#class" : catbox.CatboxFileExtractor,
+},
+
+)
diff --git a/test/results/cavemanon.py b/test/results/cavemanon.py
new file mode 100644
index 00000000..4fc0af3c
--- /dev/null
+++ b/test/results/cavemanon.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shimmie2
+
+
+__tests__ = (
+{
+ "#url" : "https://booru.cavemanon.xyz/index.php?q=post/list/Amber/1",
+ "#category": ("shimmie2", "cavemanon", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+ "#pattern" : r"https://booru\.cavemanon\.xyz/index\.php\?q=image/\d+\.\w+",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://booru.cavemanon.xyz/post/list/Amber/1",
+ "#category": ("shimmie2", "cavemanon", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+},
+
+{
+ "#url" : "https://booru.cavemanon.xyz/index.php?q=post/view/8335",
+ "#category": ("shimmie2", "cavemanon", "post"),
+ "#class" : shimmie2.Shimmie2PostExtractor,
+ "#pattern" : r"https://booru\.cavemanon\.xyz/index\.php\?q=image/8335\.png",
+ "#sha1_content": "7158f7e4abbbf143bad5835eb93dbe4d68c1d4ab",
+
+ "extension": "png",
+ "file_url" : "https://booru.cavemanon.xyz/index.php?q=image/8335.png",
+ "filename" : "8335",
+ "height" : 460,
+ "id" : 8335,
+ "md5" : "",
+ "size" : 0,
+ "tags" : "Color Fang Food Pterodactyl discord_emote transparent",
+ "width" : 459,
+},
+
+)
diff --git a/test/results/chelseacrew.py b/test/results/chelseacrew.py
new file mode 100644
index 00000000..7c12613f
--- /dev/null
+++ b/test/results/chelseacrew.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://chelseacrew.com/collections/flats",
+ "#category": ("shopify", "chelseacrew", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://chelseacrew.com/collections/flats/products/dora",
+ "#category": ("shopify", "chelseacrew", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/comicvine.py b/test/results/comicvine.py
new file mode 100644
index 00000000..fa77c491
--- /dev/null
+++ b/test/results/comicvine.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import comicvine
+
+
+__tests__ = (
+{
+ "#url" : "https://comicvine.gamespot.com/jock/4040-5653/images/",
+ "#category": ("", "comicvine", "tag"),
+ "#class" : comicvine.ComicvineTagExtractor,
+ "#pattern" : r"https://comicvine\.gamespot\.com/a/uploads/original/\d+/\d+/\d+-.+\.(jpe?g|png)",
+ "#count" : ">= 140",
+},
+
+{
+ "#url" : "https://comicvine.gamespot.com/batman/4005-1699/images/?tag=Fan%20Art%20%26%20Cosplay",
+ "#category": ("", "comicvine", "tag"),
+ "#class" : comicvine.ComicvineTagExtractor,
+ "#pattern" : r"https://comicvine\.gamespot\.com/a/uploads/original/\d+/\d+/\d+-.+",
+ "#count" : ">= 450",
+},
+
+)
diff --git a/test/results/coomerparty.py b/test/results/coomerparty.py
new file mode 100644
index 00000000..dfc4a188
--- /dev/null
+++ b/test/results/coomerparty.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import kemonoparty
+
+
+__tests__ = (
+{
+ "#url" : "https://coomer.party/onlyfans/user/alinity/post/125962203",
+ "#comment" : "coomer.party (#2100)",
+ "#category": ("", "coomerparty", "onlyfans"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#pattern" : r"https://coomer\.party/data/7d/3f/7d3fd9804583dc224968c0591163ec91794552b04f00a6c2f42a15b68231d5a8\.jpg",
+},
+
+)
diff --git a/test/results/cyberdrop.py b/test/results/cyberdrop.py
new file mode 100644
index 00000000..b163ca47
--- /dev/null
+++ b/test/results/cyberdrop.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import cyberdrop
+
+
+__tests__ = (
+{
+ "#url" : "https://cyberdrop.me/a/keKRjm4t",
+ "#comment" : "images",
+ "#category": ("lolisafe", "cyberdrop", "album"),
+ "#class" : cyberdrop.CyberdropAlbumExtractor,
+ "#pattern" : r"https://fs-\d+\.cyberdrop\.to/.*\.(jpg|png|webp)$",
+
+ "album_id" : "keKRjm4t",
+ "album_name" : "Fate (SFW)",
+ "album_size" : 150069254,
+ "count" : 62,
+ "date" : "dt:2020-06-18 13:14:20",
+ "description": "",
+ "id" : r"re:\w{8}",
+},
+
+{
+ "#url" : "https://cyberdrop.to/a/l8gIAXVD",
+ "#comment" : "videos",
+ "#category": ("lolisafe", "cyberdrop", "album"),
+ "#class" : cyberdrop.CyberdropAlbumExtractor,
+ "#pattern" : r"https://fs-\d+\.cyberdrop\.to/.*\.mp4$",
+ "#count" : 31,
+
+ "album_id" : "l8gIAXVD",
+ "album_name": "Achelois17 videos",
+ "album_size": 652037121,
+ "date" : "dt:2020-06-16 15:40:44",
+},
+
+)
diff --git a/test/results/danbooru.py b/test/results/danbooru.py
new file mode 100644
index 00000000..c64c693e
--- /dev/null
+++ b/test/results/danbooru.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import danbooru
+
+
+__tests__ = (
+{
+ "#url" : "https://danbooru.donmai.us/posts?tags=bonocho",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#sha1_content": "b196fb9f1668109d7774a0a82efea3ffdda07746",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/posts?tags=mushishi",
+ "#comment" : "test page transitions",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#count" : ">= 300",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/posts?tags=pixiv_id%3A1476533",
+ "#comment" : "'external' option (#1747)",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+ "#options" : {"external": True},
+ "#pattern" : r"https://i\.pximg\.net/img-original/img/2008/08/28/02/35/48/1476533_p0\.jpg",
+},
+
+{
+ "#url" : "https://hijiribe.donmai.us/posts?tags=bonocho",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+},
+
+{
+ "#url" : "https://sonohara.donmai.us/posts?tags=bonocho",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+},
+
+{
+ "#url" : "https://safebooru.donmai.us/posts?tags=bonocho",
+ "#category": ("Danbooru", "danbooru", "tag"),
+ "#class" : danbooru.DanbooruTagExtractor,
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/pools/7659",
+ "#category": ("Danbooru", "danbooru", "pool"),
+ "#class" : danbooru.DanbooruPoolExtractor,
+ "#sha1_content": "b16bab12bea5f7ea9e0a836bf8045f280e113d99",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/pool/show/7659",
+ "#category": ("Danbooru", "danbooru", "pool"),
+ "#class" : danbooru.DanbooruPoolExtractor,
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/posts/294929",
+ "#category": ("Danbooru", "danbooru", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+ "#sha1_content": "5e255713cbf0a8e0801dc423563c34d896bb9229",
+
+ "date": "dt:2008-08-12 04:46:05",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/posts/3613024",
+ "#category": ("Danbooru", "danbooru", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+ "#options" : {"ugoira": True},
+ "#pattern" : r"https?://.+\.zip$",
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/post/show/294929",
+ "#category": ("Danbooru", "danbooru", "post"),
+ "#class" : danbooru.DanbooruPostExtractor,
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/explore/posts/popular",
+ "#category": ("Danbooru", "danbooru", "popular"),
+ "#class" : danbooru.DanbooruPopularExtractor,
+},
+
+{
+ "#url" : "https://danbooru.donmai.us/explore/posts/popular?date=2013-06-06&scale=week",
+ "#category": ("Danbooru", "danbooru", "popular"),
+ "#class" : danbooru.DanbooruPopularExtractor,
+ "#range" : "1-120",
+ "#count" : 120,
+},
+
+)
diff --git a/test/results/derpibooru.py b/test/results/derpibooru.py
new file mode 100644
index 00000000..7ca6a0de
--- /dev/null
+++ b/test/results/derpibooru.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import philomena
+
+
+__tests__ = (
+{
+ "#url" : "https://derpibooru.org/images/1",
+ "#category": ("philomena", "derpibooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+ "#count" : 1,
+ "#sha1_content": "88449eeb0c4fa5d3583d0b794f6bc1d70bf7f889",
+
+ "animated" : False,
+ "aspect_ratio" : 1.0,
+ "comment_count" : int,
+ "created_at" : "2012-01-02T03:12:33Z",
+ "date" : "dt:2012-01-02 03:12:33",
+ "deletion_reason" : None,
+ "description" : "",
+ "downvotes" : int,
+ "duplicate_of" : None,
+ "duration" : 0.04,
+ "extension" : "png",
+ "faves" : int,
+ "first_seen_at" : "2012-01-02T03:12:33Z",
+ "format" : "png",
+ "height" : 900,
+ "hidden_from_users": False,
+ "id" : 1,
+ "mime_type" : "image/png",
+ "name" : "1__safe_fluttershy_solo_cloud_happy_flying_upvotes+galore_artist-colon-speccysy_get_sunshine",
+ "orig_sha512_hash": None,
+ "processed" : True,
+ "representations" : dict,
+ "score" : int,
+ "sha512_hash" : "f16c98e2848c2f1bfff3985e8f1a54375cc49f78125391aeb80534ce011ead14e3e452a5c4bc98a66f56bdfcd07ef7800663b994f3f343c572da5ecc22a9660f",
+ "size" : 860914,
+ "source_url" : "https://www.deviantart.com/speccysy/art/Afternoon-Flight-215193985",
+ "spoilered" : False,
+ "tag_count" : int,
+ "tag_ids" : list,
+ "tags" : list,
+ "thumbnails_generated": True,
+ "updated_at" : r"re:\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ",
+ "uploader" : "Clover the Clever",
+ "uploader_id" : 211188,
+ "upvotes" : int,
+ "view_url" : str,
+ "width" : 900,
+ "wilson_score" : float,
+},
+
+{
+ "#url" : "https://derpibooru.org/1",
+ "#category": ("philomena", "derpibooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+},
+
+{
+ "#url" : "https://www.derpibooru.org/1",
+ "#category": ("philomena", "derpibooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+},
+
+{
+ "#url" : "https://www.derpibooru.org/images/1",
+ "#category": ("philomena", "derpibooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+},
+
+{
+ "#url" : "https://derpibooru.org/search?q=cute",
+ "#category": ("philomena", "derpibooru", "search"),
+ "#class" : philomena.PhilomenaSearchExtractor,
+ "#range" : "40-60",
+ "#count" : 21,
+},
+
+{
+ "#url" : "https://derpibooru.org/tags/cute",
+ "#category": ("philomena", "derpibooru", "search"),
+ "#class" : philomena.PhilomenaSearchExtractor,
+ "#range" : "40-60",
+ "#count" : 21,
+},
+
+{
+ "#url" : "https://derpibooru.org/tags/artist-colon--dash-_-fwslash--fwslash-%255Bkorroki%255D_aternak",
+ "#category": ("philomena", "derpibooru", "search"),
+ "#class" : philomena.PhilomenaSearchExtractor,
+ "#count" : ">= 2",
+},
+
+{
+ "#url" : "https://derpibooru.org/galleries/1",
+ "#category": ("philomena", "derpibooru", "gallery"),
+ "#class" : philomena.PhilomenaGalleryExtractor,
+ "#pattern" : r"https://derpicdn\.net/img/view/\d+/\d+/\d+/\d+[^/]+$",
+
+ "gallery": {
+ "description" : "Indexes start at 1 :P",
+ "id" : 1,
+ "spoiler_warning": "",
+ "thumbnail_id" : 1,
+ "title" : "The Very First Gallery",
+ "user" : "DeliciousBlackInk",
+ "user_id" : 365446,
+ },
+},
+
+)
diff --git a/test/results/desktopography.py b/test/results/desktopography.py
new file mode 100644
index 00000000..c6066692
--- /dev/null
+++ b/test/results/desktopography.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import desktopography
+
+
+__tests__ = (
+{
+ "#url" : "https://desktopography.net/",
+ "#category": ("", "desktopography", "site"),
+ "#class" : desktopography.DesktopographySiteExtractor,
+},
+
+{
+ "#url" : "https://desktopography.net/exhibition-2020/",
+ "#category": ("", "desktopography", "exhibition"),
+ "#class" : desktopography.DesktopographyExhibitionExtractor,
+},
+
+{
+ "#url" : "https://desktopography.net/portfolios/new-era/",
+ "#category": ("", "desktopography", "entry"),
+ "#class" : desktopography.DesktopographyEntryExtractor,
+},
+
+)
diff --git a/test/results/desuarchive.py b/test/results/desuarchive.py
new file mode 100644
index 00000000..8e180652
--- /dev/null
+++ b/test/results/desuarchive.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://desuarchive.org/a/thread/159542679/",
+ "#category": ("foolfuuka", "desuarchive", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "e7d624aded15a069194e38dc731ec23217a422fb",
+},
+
+{
+ "#url" : "https://desuarchive.org/a/",
+ "#category": ("foolfuuka", "desuarchive", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://desuarchive.org/_/search/text/test/",
+ "#category": ("foolfuuka", "desuarchive", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://desuarchive.org/a/gallery/5",
+ "#category": ("foolfuuka", "desuarchive", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/deviantart.py b/test/results/deviantart.py
new file mode 100644
index 00000000..87473bb8
--- /dev/null
+++ b/test/results/deviantart.py
@@ -0,0 +1,732 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import deviantart
+import datetime
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.deviantart.com/shimoda7",
+ "#category": ("", "deviantart", "user"),
+ "#class" : deviantart.DeviantartUserExtractor,
+ "#pattern" : "/shimoda7/gallery$",
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7",
+ "#category": ("", "deviantart", "user"),
+ "#class" : deviantart.DeviantartUserExtractor,
+ "#options" : {"include": "all"},
+ "#pattern" : "/shimoda7/(gallery(/scraps)?|posts(/statuses)?|favourites)$",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/",
+ "#category": ("", "deviantart", "user"),
+ "#class" : deviantart.DeviantartUserExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+ "#pattern" : r"https://(images-)?wixmp-[^.]+\.wixmp\.com/f/.+/.+\.(jpg|png)\?token=.+",
+ "#count" : ">= 30",
+
+ "allows_comments" : bool,
+ "author" : {
+ "type" : "regular",
+ "usericon": str,
+ "userid" : "9AE51FC7-0278-806C-3FFF-F4961ABF9E2B",
+ "username": "shimoda7",
+ },
+ "category_path" : str,
+ "content" : {
+ "filesize" : int,
+ "height" : int,
+ "src" : str,
+ "transparency": bool,
+ "width" : int,
+ },
+ "da_category" : str,
+ "date" : datetime.datetime,
+ "deviationid" : str,
+ "?download_filesize": int,
+ "extension" : str,
+ "index" : int,
+ "is_deleted" : bool,
+ "is_downloadable" : bool,
+ "is_favourited" : bool,
+ "is_mature" : bool,
+ "preview" : {
+ "height" : int,
+ "src" : str,
+ "transparency": bool,
+ "width" : int,
+ },
+ "published_time" : int,
+ "stats" : {
+ "comments" : int,
+ "favourites": int,
+ },
+ "target" : dict,
+ "thumbs" : list,
+ "title" : str,
+ "url" : r"re:https://www.deviantart.com/shimoda7/art/[^/]+-\d+",
+ "username" : "shimoda7",
+},
+
+{
+ "#url" : "https://www.deviantart.com/yakuzafc/gallery",
+ "#comment" : "group",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+ "#pattern" : r"https://www.deviantart.com/yakuzafc/gallery/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/",
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://www.deviantart.com/justatest235723/gallery",
+ "#comment" : "'folders' option (#276)",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+ "#options" : {
+ "metadata": 1,
+ "folders" : 1,
+ "original": 0,
+ },
+ "#count" : 3,
+
+ "description": str,
+ "folders" : list,
+ "is_watching": bool,
+ "license" : str,
+ "tags" : list,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda8/gallery/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/all",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/?catpath=/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/gallery/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/gallery/all/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/gallery/?catpath=/",
+ "#category": ("", "deviantart", "gallery"),
+ "#class" : deviantart.DeviantartGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/722019/Miscellaneous",
+ "#comment" : "user",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+ "#options" : {"original": False},
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://www.deviantart.com/yakuzafc/gallery/37412168/Crafts",
+ "#comment" : "group",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+ "#options" : {"original": False},
+ "#count" : ">= 4",
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/B38E3C6A-2029-6B45-757B-3C8D3422AD1A/misc",
+ "#comment" : "uuid",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+ "#options" : {"original": False},
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://www.deviantart.com/justatest235723/gallery/69302698/-test-b-c-d-e-f-",
+ "#comment" : "name starts with '_', special characters (#1451)",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+ "#options" : {"original": False},
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/gallery/722019/Miscellaneous",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+},
+
+{
+ "#url" : "https://yakuzafc.deviantart.com/gallery/37412168/Crafts",
+ "#category": ("", "deviantart", "folder"),
+ "#class" : deviantart.DeviantartFolderExtractor,
+},
+
+{
+ "#url" : "https://sta.sh/022c83odnaxc",
+ "#category": ("", "deviantart", "stash"),
+ "#class" : deviantart.DeviantartStashExtractor,
+ "#pattern" : r"https://wixmp-[^.]+\.wixmp\.com/f/.+/.+\.png\?token=.+",
+ "#count" : 1,
+ "#sha1_content": "057eb2f2861f6c8a96876b13cca1a4b7a408c11f",
+},
+
+{
+ "#url" : "https://sta.sh/21jf51j7pzl2",
+ "#comment" : "multiple stash items",
+ "#category": ("", "deviantart", "stash"),
+ "#class" : deviantart.DeviantartStashExtractor,
+ "#options" : {"original": False},
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://sta.sh/024t4coz16mi",
+ "#comment" : "downloadable, but no 'content' field (#307)",
+ "#category": ("", "deviantart", "stash"),
+ "#class" : deviantart.DeviantartStashExtractor,
+ "#pattern" : r"https://wixmp-[^.]+\.wixmp\.com/f/.+/.+\.rar\?token=.+",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://sta.sh/215twi387vfj",
+ "#comment" : "mixed folders and images (#659)",
+ "#category": ("", "deviantart", "stash"),
+ "#class" : deviantart.DeviantartStashExtractor,
+ "#options" : {"original": False},
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://sta.sh/abcdefghijkl",
+ "#category": ("", "deviantart", "stash"),
+ "#class" : deviantart.DeviantartStashExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.deviantart.com/h3813067/favourites/",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+ "#options" : {
+ "metadata": True,
+ "flat" : False,
+ },
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.deviantart.com/h3813067/favourites/",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+ "#sha1_content": "6a7c74dc823ebbd457bdd9b3c2838a6ee728091e",
+},
+
+{
+ "#url" : "https://www.deviantart.com/h3813067/favourites/all",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/h3813067/favourites/?catpath=/",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+},
+
+{
+ "#url" : "https://h3813067.deviantart.com/favourites/",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+},
+
+{
+ "#url" : "https://h3813067.deviantart.com/favourites/all",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+},
+
+{
+ "#url" : "https://h3813067.deviantart.com/favourites/?catpath=/",
+ "#category": ("", "deviantart", "favorite"),
+ "#class" : deviantart.DeviantartFavoriteExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/pencilshadings/favourites/70595441/3D-Favorites",
+ "#category": ("", "deviantart", "collection"),
+ "#class" : deviantart.DeviantartCollectionExtractor,
+ "#options" : {"original": False},
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://www.deviantart.com/pencilshadings/favourites/F050486B-CB62-3C66-87FB-1105A7F6379F/3D Favorites",
+ "#category": ("", "deviantart", "collection"),
+ "#class" : deviantart.DeviantartCollectionExtractor,
+ "#options" : {"original": False},
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://pencilshadings.deviantart.com/favourites/70595441/3D-Favorites",
+ "#category": ("", "deviantart", "collection"),
+ "#class" : deviantart.DeviantartCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/angrywhitewanker/posts/journals/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+ "#sha1_url": "38db2a0d3a587a7e0f9dba7ff7d274610ebefe44",
+},
+
+{
+ "#url" : "https://www.deviantart.com/angrywhitewanker/posts/journals/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+ "#options" : {"journals": "text"},
+ "#sha1_url": "b2a8e74d275664b1a4acee0fca0a6fd33298571e",
+},
+
+{
+ "#url" : "https://www.deviantart.com/angrywhitewanker/posts/journals/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+ "#options" : {"journals": "none"},
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/posts/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/journal/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/journal/?catpath=/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/journal/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/journal/?catpath=/",
+ "#category": ("", "deviantart", "journal"),
+ "#class" : deviantart.DeviantartJournalExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/t1na/posts/statuses",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.deviantart.com/justgalym/posts/statuses",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#count" : 4,
+ "#sha1_url": "bf4c44c0c60ff2648a880f4c3723464ad3e7d074",
+},
+
+{
+ "#url" : "https://www.deviantart.com/justgalym/posts/statuses",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#options" : {"journals": "none"},
+ "#pattern" : r"https://images-wixmp-\w+\.wixmp\.com/f/[^/]+/[^.]+\.jpg\?token=",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.deviantart.com/vanillaghosties/posts/statuses",
+ "#comment" : "shared sta.sh item",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#options" : {
+ "journals": "none",
+ "original": False,
+ },
+ "#range" : "5-",
+ "#count" : 1,
+
+ "index" : int,
+ "index_base36": r"re:^[0-9a-z]+$",
+ "url" : r"re:^https://sta.sh",
+},
+
+{
+ "#url" : "https://www.deviantart.com/AndrejSKalin/posts/statuses",
+ "#comment" : "'deleted' deviations in 'items'",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#options" : {
+ "journals" : "none",
+ "original" : 0,
+ "image-filter": "deviationid[:8] == '147C8B03'",
+ },
+ "#count" : 2,
+ "#archive" : False,
+
+ "deviationid": "147C8B03-7D34-AE93-9241-FA3C6DBBC655",
+},
+
+{
+ "#url" : "https://www.deviantart.com/justgalym/posts/statuses",
+ "#category": ("", "deviantart", "status"),
+ "#class" : deviantart.DeviantartStatusExtractor,
+ "#options" : {"journals": "text"},
+ "#sha1_url": "c8744f7f733a3029116607b826321233c5ca452d",
+},
+
+{
+ "#url" : "https://www.deviantart.com/?order=popular-all-time",
+ "#category": ("", "deviantart", "popular"),
+ "#class" : deviantart.DeviantartPopularExtractor,
+ "#options" : {"original": False},
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://www.deviantart.com/popular-24-hours/?q=tree+house",
+ "#category": ("", "deviantart", "popular"),
+ "#class" : deviantart.DeviantartPopularExtractor,
+ "#options" : {"original": False},
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://www.deviantart.com/artisan/popular-all-time/?q=tree",
+ "#category": ("", "deviantart", "popular"),
+ "#class" : deviantart.DeviantartPopularExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/tag/nature",
+ "#category": ("", "deviantart", "tag"),
+ "#class" : deviantart.DeviantartTagExtractor,
+ "#options" : {"original": False},
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://www.deviantart.com/watch/deviations",
+ "#category": ("", "deviantart", "watch"),
+ "#class" : deviantart.DeviantartWatchExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/notifications/watch",
+ "#category": ("", "deviantart", "watch"),
+ "#class" : deviantart.DeviantartWatchExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/watch/posts",
+ "#category": ("", "deviantart", "watch-posts"),
+ "#class" : deviantart.DeviantartWatchPostsExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/art/For-the-sake-10073852",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#options" : {"original": 0},
+ "#sha1_content": "6a7c74dc823ebbd457bdd9b3c2838a6ee728091e",
+},
+
+{
+ "#url" : "https://www.deviantart.com/zzz/art/zzz-1234567890",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.deviantart.com/myria-moon/art/Aime-Moi-261986576",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#options" : {"comments": True},
+ "#pattern" : r"https://wixmp-[^.]+\.wixmp\.com/f/.+/.+\.jpg\?token=.+",
+
+ "comments": list,
+},
+
+{
+ "#url" : "https://www.deviantart.com/citizenfresh/art/Hverarond-789295466",
+ "#comment" : "wixmp URL rewrite",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#pattern" : r"https://images-wixmp-\w+\.wixmp\.com/f/[^/]+/[^.]+\.jpg\?token=",
+},
+
+{
+ "#url" : "https://www.deviantart.com/skatergators/art/COM-Moni-781571783",
+ "#comment" : "GIF (#242)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#pattern" : r"https://wixmp-\w+\.wixmp\.com/f/03fd2413-efe9-4e5c-8734-2b72605b3fbb/dcxbsnb-1bbf0b38-42af-4070-8878-f30961955bec\.gif\?token=ey...",
+},
+
+{
+ "#url" : "https://www.deviantart.com/yuumei/art/Flash-Comic-214724929",
+ "#comment" : "Flash animation with GIF preview (#1731)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#pattern" : r"https://wixmp-[^.]+\.wixmp\.com/f/.+/.+\.swf\?token=.+",
+
+ "filename" : "flash_comic_tutorial_by_yuumei-d3juatd",
+ "extension": "swf",
+},
+
+{
+ "#url" : "https://www.deviantart.com/uotapo/art/INANAKI-Memo-590297498",
+ "#comment" : "sta.sh URLs from description (#302)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#options" : {
+ "extra" : 1,
+ "original": 0,
+ },
+ "#pattern" : deviantart.DeviantartStashExtractor.pattern,
+ "#range" : "2-",
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://www.deviantart.com/cimar-wildehopps/art/Honorary-Vixen-859809305",
+ "#comment" : "sta.sh URL from deviation['text_content']['body']['features']",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#options" : {"extra": 1},
+ "#pattern" : r"""text:
+|(?:https?://)?sta\.sh/([a-z0-9]+)""",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/journal/ARTility-583755752",
+ "#comment" : "journal",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#pattern" : """text:
+""",
+ "#sha1_url": "d34b2c9f873423e665a1b8ced20fcb75951694a3",
+},
+
+{
+ "#url" : "https://www.deviantart.com/gliitchlord/art/brashstrokes-812942668",
+ "#comment" : "journal-like post with isJournal == False (#419)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#pattern" : """text:
+""",
+ "#sha1_url": "e2e0044bd255304412179b6118536dbd9bb3bb0e",
+},
+
+{
+ "#url" : "https://deviantart.com/view/904858796/",
+ "#comment" : "/view/ URLs",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#sha1_content": "8770ec40ad1c1d60f6b602b16301d124f612948f",
+},
+
+{
+ "#url" : "http://www.deviantart.com/view/890672057",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#sha1_content": "1497e13d925caeb13a250cd666b779a640209236",
+},
+
+{
+ "#url" : "https://www.deviantart.com/view/706871727",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#sha1_content": "3f62ae0c2fca2294ac28e41888ea06bb37c22c65",
+},
+
+{
+ "#url" : "https://www.deviantart.com/view/1",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.deviantart.com/deviation/817215762",
+ "#comment" : "/deviation/ (#3558)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://fav.me/ddijrpu",
+ "#comment" : "fav.me (#3558)",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://fav.me/dddd",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/art/For-the-sake-of-a-memory-10073852",
+ "#comment" : "old-style URLs",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://myria-moon.deviantart.com/art/Aime-Moi-part-en-vadrouille-261986576",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://zzz.deviantart.com/art/zzz-1234567890",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/view.php?id=14864502",
+ "#comment" : "old /view/ URLs from the Wayback Machine",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "http://www.deviantart.com/view-full.php?id=100842",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://www.fxdeviantart.com/zzz/art/zzz-1234567890",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://www.fxdeviantart.com/view/1234567890",
+ "#category": ("", "deviantart", "deviation"),
+ "#class" : deviantart.DeviantartDeviationExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/scraps",
+ "#category": ("", "deviantart", "scraps"),
+ "#class" : deviantart.DeviantartScrapsExtractor,
+ "#count" : 12,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery/?catpath=scraps",
+ "#category": ("", "deviantart", "scraps"),
+ "#class" : deviantart.DeviantartScrapsExtractor,
+},
+
+{
+ "#url" : "https://shimoda7.deviantart.com/gallery/?catpath=scraps",
+ "#category": ("", "deviantart", "scraps"),
+ "#class" : deviantart.DeviantartScrapsExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/search?q=tree",
+ "#category": ("", "deviantart", "search"),
+ "#class" : deviantart.DeviantartSearchExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/search/deviations?order=popular-1-week",
+ "#category": ("", "deviantart", "search"),
+ "#class" : deviantart.DeviantartSearchExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery?q=memory",
+ "#category": ("", "deviantart", "gallery-search"),
+ "#class" : deviantart.DeviantartGallerySearchExtractor,
+ "#options" : {"original": 0},
+ "#sha1_content": "6a7c74dc823ebbd457bdd9b3c2838a6ee728091e",
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/gallery?q=memory&sort=popular",
+ "#category": ("", "deviantart", "gallery-search"),
+ "#class" : deviantart.DeviantartGallerySearchExtractor,
+},
+
+{
+ "#url" : "https://www.deviantart.com/shimoda7/about#watching",
+ "#category": ("", "deviantart", "following"),
+ "#class" : deviantart.DeviantartFollowingExtractor,
+ "#pattern" : deviantart.DeviantartUserExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+)
diff --git a/test/results/directlink.py b/test/results/directlink.py
new file mode 100644
index 00000000..afa43b34
--- /dev/null
+++ b/test/results/directlink.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import directlink
+
+
+__tests__ = (
+{
+ "#url" : "https://en.wikipedia.org/static/images/project-logos/enwiki.png",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+ "#sha1_url" : "18c5d00077332e98e53be9fed2ee4be66154b88d",
+ "#sha1_metadata": "105770a3f4393618ab7b811b731b22663b5d3794",
+},
+
+{
+ "#url" : "https://example.org/file.webm",
+ "#comment" : "empty path",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+ "#sha1_url" : "2d807ed7059d1b532f1bb71dc24b510b80ff943f",
+ "#sha1_metadata": "29dad729c40fb09349f83edafa498dba1297464a",
+},
+
+{
+ "#url" : "https://example.org/path/to/file.webm?que=1?&ry=2/#fragment",
+ "#comment" : "more complex example",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+ "#sha1_url" : "6fb1061390f8aada3db01cb24b51797c7ee42b31",
+ "#sha1_metadata": "3d7abc31d45ba324e59bc599c3b4862452d5f29c",
+},
+
+{
+ "#url" : "https://example.org/%27%3C%23/%23%3E%27.jpg?key=%3C%26%3E",
+ "#comment" : "percent-encoded characters",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+ "#sha1_url" : "2627e8140727fdf743f86fe18f69f99a052c9718",
+ "#sha1_metadata": "831790fddda081bdddd14f96985ab02dc5b5341f",
+},
+
+{
+ "#url" : "https://post-phinf.pstatic.net/MjAxOTA1MjlfMTQ4/MDAxNTU5MTI2NjcyNTkw.JUzkGb4V6dj9DXjLclrOoqR64uDxHFUO5KDriRdKpGwg.88mCtd4iT1NHlpVKSCaUpPmZPiDgT8hmQdQ5K_gYyu0g.JPEG/2.JPG",
+ "#comment" : "upper case file extension (#296)",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+},
+
+{
+ "#url" : "https://räksmörgås.josefsson.org/raksmorgas.jpg",
+ "#comment" : "internationalized domain name",
+ "#category": ("", "directlink", ""),
+ "#class" : directlink.DirectlinkExtractor,
+ "#sha1_url" : "a65667f670b194afbd1e3ea5e7a78938d36747da",
+ "#sha1_metadata": "fd5037fe86eebd4764e176cbaf318caec0f700be",
+},
+
+)
diff --git a/test/results/drawfriends.py b/test/results/drawfriends.py
new file mode 100644
index 00000000..d481fe70
--- /dev/null
+++ b/test/results/drawfriends.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v01
+
+
+__tests__ = (
+{
+ "#url" : "https://drawfriends.booru.org/index.php?page=post&s=list&tags=all",
+ "#category": ("gelbooru_v01", "drawfriends", "tag"),
+ "#class" : gelbooru_v01.GelbooruV01TagExtractor,
+},
+
+{
+ "#url" : "https://drawfriends.booru.org/index.php?page=favorites&s=view&id=1",
+ "#category": ("gelbooru_v01", "drawfriends", "favorite"),
+ "#class" : gelbooru_v01.GelbooruV01FavoriteExtractor,
+},
+
+{
+ "#url" : "https://drawfriends.booru.org/index.php?page=post&s=view&id=107474",
+ "#category": ("gelbooru_v01", "drawfriends", "post"),
+ "#class" : gelbooru_v01.GelbooruV01PostExtractor,
+},
+
+)
diff --git a/test/results/dynastyscans.py b/test/results/dynastyscans.py
new file mode 100644
index 00000000..bcd85917
--- /dev/null
+++ b/test/results/dynastyscans.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import dynastyscans
+
+
+__tests__ = (
+{
+ "#url" : "http://dynasty-scans.com/chapters/hitoribocchi_no_oo_seikatsu_ch33",
+ "#category": ("", "dynastyscans", "chapter"),
+ "#class" : dynastyscans.DynastyscansChapterExtractor,
+ "#sha1_url" : "dce64e8c504118f1ab4135c00245ea12413896cb",
+ "#sha1_metadata": "b67599703c27316a2fe4f11c3232130a1904e032",
+},
+
+{
+ "#url" : "http://dynasty-scans.com/chapters/new_game_the_spinoff_special_13",
+ "#category": ("", "dynastyscans", "chapter"),
+ "#class" : dynastyscans.DynastyscansChapterExtractor,
+ "#sha1_url" : "dbe5bbb74da2edcfb1832895a484e2a40bc8b538",
+ "#sha1_metadata": "6b674eb3a274999153f6be044973b195008ced2f",
+},
+
+{
+ "#url" : "https://dynasty-scans.com/series/hitoribocchi_no_oo_seikatsu",
+ "#category": ("", "dynastyscans", "manga"),
+ "#class" : dynastyscans.DynastyscansMangaExtractor,
+ "#pattern" : dynastyscans.DynastyscansChapterExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://dynasty-scans.com/images?with[]=4930&with[]=5211",
+ "#category": ("", "dynastyscans", "search"),
+ "#class" : dynastyscans.DynastyscansSearchExtractor,
+ "#sha1_url" : "22cf0fb64e12b29e79b0a3d26666086a48f9916a",
+ "#sha1_metadata": "11cbc555a15528d25567977b8808e10369c4c3ee",
+},
+
+{
+ "#url" : "https://dynasty-scans.com/images",
+ "#category": ("", "dynastyscans", "search"),
+ "#class" : dynastyscans.DynastyscansSearchExtractor,
+ "#range" : "1",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://dynasty-scans.com/images/1245",
+ "#category": ("", "dynastyscans", "image"),
+ "#class" : dynastyscans.DynastyscansImageExtractor,
+ "#sha1_url" : "15e54bd94148a07ed037f387d046c27befa043b2",
+ "#sha1_metadata": "0d8976c2d6fbc9ed6aa712642631b96e456dc37f",
+},
+
+)
diff --git a/test/results/e621.py b/test/results/e621.py
new file mode 100644
index 00000000..dd9787cd
--- /dev/null
+++ b/test/results/e621.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import e621
+
+
+__tests__ = (
+{
+ "#url" : "https://e621.net/posts?tags=anry",
+ "#category": ("E621", "e621", "tag"),
+ "#class" : e621.E621TagExtractor,
+ "#sha1_url" : "8021e5ea28d47c474c1ffc9bd44863c4d45700ba",
+ "#sha1_content": "501d1e5d922da20ee8ff9806f5ed3ce3a684fd58",
+},
+
+{
+ "#url" : "https://e621.net/post/index/1/anry",
+ "#category": ("E621", "e621", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e621.net/post?tags=anry",
+ "#category": ("E621", "e621", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e621.net/pools/73",
+ "#category": ("E621", "e621", "pool"),
+ "#class" : e621.E621PoolExtractor,
+ "#sha1_url" : "1bd09a72715286a79eea3b7f09f51b3493eb579a",
+ "#sha1_content": "91abe5d5334425d9787811d7f06d34c77974cd22",
+},
+
+{
+ "#url" : "https://e621.net/pool/show/73",
+ "#category": ("E621", "e621", "pool"),
+ "#class" : e621.E621PoolExtractor,
+},
+
+{
+ "#url" : "https://e621.net/posts/535",
+ "#category": ("E621", "e621", "post"),
+ "#class" : e621.E621PostExtractor,
+ "#sha1_url" : "f7f78b44c9b88f8f09caac080adc8d6d9fdaa529",
+ "#sha1_content": "66f46e96a893fba8e694c4e049b23c2acc9af462",
+
+ "date": "dt:2007-02-17 19:02:32",
+},
+
+{
+ "#url" : "https://e621.net/posts/3181052",
+ "#category": ("E621", "e621", "post"),
+ "#class" : e621.E621PostExtractor,
+ "#options" : {"metadata": "notes,pools"},
+ "#pattern" : r"https://static\d\.e621\.net/data/c6/8c/c68cca0643890b615f75fb2719589bff\.png",
+
+ "notes": [{
+ "body" : "Little Legends 2",
+ "created_at" : "2022-05-16T13:58:38.877-04:00",
+ "creator_id" : 517450,
+ "creator_name": "EeveeCuddler69",
+ "height" : 475,
+ "id" : 321296,
+ "is_active" : True,
+ "post_id" : 3181052,
+ "updated_at" : "2022-05-16T13:59:02.050-04:00",
+ "version" : 3,
+ "width" : 809,
+ "x" : 83,
+ "y" : 117,
+}],
+ "pools": [{
+ "category" : "series",
+ "created_at" : "2022-02-17T00:29:22.669-05:00",
+ "creator_id" : 1077440,
+ "creator_name": "Yeetus90",
+ "description" : """* "Little Legends":/pools/27971
+* Little Legends 2
+* "Little Legends 3":/pools/27481""",
+ "id" : 27492,
+ "is_active" : False,
+ "name" : "Little Legends 2",
+ "post_count" : 39,
+ "post_ids" : list,
+ "updated_at" : "2022-03-27T06:30:03.382-04:00",
+}],
+},
+
+{
+ "#url" : "https://e621.net/post/show/535",
+ "#category": ("E621", "e621", "post"),
+ "#class" : e621.E621PostExtractor,
+},
+
+{
+ "#url" : "https://e621.net/explore/posts/popular",
+ "#category": ("E621", "e621", "popular"),
+ "#class" : e621.E621PopularExtractor,
+},
+
+{
+ "#url" : "https://e621.net/explore/posts/popular?date=2019-06-01&scale=month",
+ "#category": ("E621", "e621", "popular"),
+ "#class" : e621.E621PopularExtractor,
+ "#pattern" : r"https://static\d.e621.net/data/../../[0-9a-f]+",
+ "#count" : ">= 70",
+},
+
+{
+ "#url" : "https://e621.net/favorites",
+ "#category": ("E621", "e621", "favorite"),
+ "#class" : e621.E621FavoriteExtractor,
+},
+
+{
+ "#url" : "https://e621.net/favorites?page=2&user_id=53275",
+ "#category": ("E621", "e621", "favorite"),
+ "#class" : e621.E621FavoriteExtractor,
+ "#pattern" : r"https://static\d.e621.net/data/../../[0-9a-f]+",
+ "#count" : "> 260",
+},
+
+)
diff --git a/test/results/e6ai.py b/test/results/e6ai.py
new file mode 100644
index 00000000..291f3b3a
--- /dev/null
+++ b/test/results/e6ai.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import e621
+
+
+__tests__ = (
+{
+ "#url" : "https://e6ai.net/posts?tags=anry",
+ "#category": ("E621", "e6ai", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/post/index/1/anry",
+ "#category": ("E621", "e6ai", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/post?tags=anry",
+ "#category": ("E621", "e6ai", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/pools/3",
+ "#category": ("E621", "e6ai", "pool"),
+ "#class" : e621.E621PoolExtractor,
+ "#sha1_url": "a6d1ad67a3fa9b9f73731d34d5f6f26f7e85855f",
+},
+
+{
+ "#url" : "https://e6ai.net/pool/show/3",
+ "#category": ("E621", "e6ai", "pool"),
+ "#class" : e621.E621PoolExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/posts/23",
+ "#category": ("E621", "e6ai", "post"),
+ "#class" : e621.E621PostExtractor,
+ "#sha1_url" : "3c85a806b3d9eec861948af421fe0e8ad6b8f881",
+ "#sha1_content": "a05a484e4eb64637d56d751c02e659b4bc8ea5d5",
+},
+
+{
+ "#url" : "https://e6ai.net/post/show/23",
+ "#category": ("E621", "e6ai", "post"),
+ "#class" : e621.E621PostExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/explore/posts/popular",
+ "#category": ("E621", "e6ai", "popular"),
+ "#class" : e621.E621PopularExtractor,
+},
+
+{
+ "#url" : "https://e6ai.net/favorites",
+ "#category": ("E621", "e6ai", "favorite"),
+ "#class" : e621.E621FavoriteExtractor,
+},
+
+)
diff --git a/test/results/e926.py b/test/results/e926.py
new file mode 100644
index 00000000..b046b459
--- /dev/null
+++ b/test/results/e926.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import e621
+
+
+__tests__ = (
+{
+ "#url" : "https://e926.net/posts?tags=anry",
+ "#category": ("E621", "e926", "tag"),
+ "#class" : e621.E621TagExtractor,
+ "#sha1_url" : "12198b275c62ffe2de67cca676c8e64de80c425d",
+ "#sha1_content": "501d1e5d922da20ee8ff9806f5ed3ce3a684fd58",
+},
+
+{
+ "#url" : "https://e926.net/post/index/1/anry",
+ "#category": ("E621", "e926", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e926.net/post?tags=anry",
+ "#category": ("E621", "e926", "tag"),
+ "#class" : e621.E621TagExtractor,
+},
+
+{
+ "#url" : "https://e926.net/pools/73",
+ "#category": ("E621", "e926", "pool"),
+ "#class" : e621.E621PoolExtractor,
+ "#sha1_url" : "6936f1b6a18c5c25bee7cad700088dbc2503481b",
+ "#sha1_content": "91abe5d5334425d9787811d7f06d34c77974cd22",
+},
+
+{
+ "#url" : "https://e926.net/pool/show/73",
+ "#category": ("E621", "e926", "pool"),
+ "#class" : e621.E621PoolExtractor,
+},
+
+{
+ "#url" : "https://e926.net/posts/535",
+ "#category": ("E621", "e926", "post"),
+ "#class" : e621.E621PostExtractor,
+ "#sha1_url" : "17aec8ebd8fab098d321adcb62a2db59dab1f4bf",
+ "#sha1_content": "66f46e96a893fba8e694c4e049b23c2acc9af462",
+},
+
+{
+ "#url" : "https://e926.net/post/show/535",
+ "#category": ("E621", "e926", "post"),
+ "#class" : e621.E621PostExtractor,
+},
+
+{
+ "#url" : "https://e926.net/explore/posts/popular",
+ "#category": ("E621", "e926", "popular"),
+ "#class" : e621.E621PopularExtractor,
+},
+
+{
+ "#url" : "https://e926.net/explore/posts/popular?date=2019-06-01&scale=month",
+ "#category": ("E621", "e926", "popular"),
+ "#class" : e621.E621PopularExtractor,
+ "#pattern" : r"https://static\d.e926.net/data/../../[0-9a-f]+",
+ "#count" : ">= 70",
+},
+
+{
+ "#url" : "https://e926.net/favorites",
+ "#category": ("E621", "e926", "favorite"),
+ "#class" : e621.E621FavoriteExtractor,
+},
+
+{
+ "#url" : "https://e926.net/favorites?page=2&user_id=53275",
+ "#category": ("E621", "e926", "favorite"),
+ "#class" : e621.E621FavoriteExtractor,
+ "#pattern" : r"https://static\d.e926.net/data/../../[0-9a-f]+",
+ "#count" : "> 260",
+},
+
+)
diff --git a/test/results/endchan.py b/test/results/endchan.py
new file mode 100644
index 00000000..293a8569
--- /dev/null
+++ b/test/results/endchan.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lynxchan
+
+
+__tests__ = (
+{
+ "#url" : "https://endchan.org/yuri/res/193483.html",
+ "#category": ("lynxchan", "endchan", "thread"),
+ "#class" : lynxchan.LynxchanThreadExtractor,
+ "#pattern" : r"https://endchan\.org/\.media/[^.]+(\.\w+)?$",
+ "#count" : ">= 19",
+},
+
+{
+ "#url" : "https://endchan.org/yuri/res/33621.html",
+ "#category": ("lynxchan", "endchan", "thread"),
+ "#class" : lynxchan.LynxchanThreadExtractor,
+},
+
+{
+ "#url" : "https://endchan.org/yuri/",
+ "#category": ("lynxchan", "endchan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+ "#pattern" : lynxchan.LynxchanThreadExtractor.pattern,
+ "#count" : ">= 9",
+},
+
+{
+ "#url" : "https://endchan.org/yuri/catalog.html",
+ "#category": ("lynxchan", "endchan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+},
+
+)
diff --git a/test/results/erome.py b/test/results/erome.py
new file mode 100644
index 00000000..f3269c04
--- /dev/null
+++ b/test/results/erome.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import erome
+
+
+__tests__ = (
+{
+ "#url" : "https://www.erome.com/a/NQgdlWvk",
+ "#category": ("", "erome", "album"),
+ "#class" : erome.EromeAlbumExtractor,
+ "#pattern" : r"https://v\d+\.erome\.com/\d+/NQgdlWvk/j7jlzmYB_480p\.mp4",
+ "#count" : 1,
+
+ "album_id": "NQgdlWvk",
+ "num" : 1,
+ "title" : "porn",
+ "user" : "yYgWBZw8o8qsMzM",
+},
+
+{
+ "#url" : "https://www.erome.com/a/TdbZ4ogi",
+ "#category": ("", "erome", "album"),
+ "#class" : erome.EromeAlbumExtractor,
+ "#pattern" : r"https://s\d+\.erome\.com/\d+/TdbZ4ogi/\w+",
+ "#count" : 6,
+
+ "album_id": "TdbZ4ogi",
+ "num" : int,
+ "title" : "82e78cfbb461ad87198f927fcb1fda9a1efac9ff.",
+ "user" : "yYgWBZw8o8qsMzM",
+},
+
+{
+ "#url" : "https://www.erome.com/yYgWBZw8o8qsMzM",
+ "#category": ("", "erome", "user"),
+ "#class" : erome.EromeUserExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://www.erome.com/search?q=cute",
+ "#category": ("", "erome", "search"),
+ "#class" : erome.EromeSearchExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+)
diff --git a/test/results/exhentai.py b/test/results/exhentai.py
new file mode 100644
index 00000000..293449c8
--- /dev/null
+++ b/test/results/exhentai.py
@@ -0,0 +1,132 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import exhentai
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://exhentai.org/g/1200119/d55c44d3d0/",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+ "#options" : {"original": False},
+ "#sha1_content": [
+ "2c68cff8a7ca540a78c36fdbf5fbae0260484f87",
+ "e9891a4c017ed0bb734cd1efba5cd03f594d31ff",
+ ],
+
+ "cost" : int,
+ "date" : "dt:2018-03-18 20:14:00",
+ "eh_category" : "Non-H",
+ "expunged" : False,
+ "favorites" : r"re:^[12]\d$",
+ "filecount" : "4",
+ "filesize" : 1488978,
+ "gid" : 1200119,
+ "height" : int,
+ "image_token" : r"re:[0-9a-f]{10}",
+ "lang" : "ja",
+ "language" : "Japanese",
+ "parent" : "",
+ "rating" : r"re:\d\.\d+",
+ "size" : int,
+ "tags" : [
+ "parody:komi-san wa komyushou desu.",
+ "character:shouko komi",
+ "group:seventh lowlife",
+ "other:sample",
+ ],
+ "thumb" : "https://exhentai.org/t/ce/0a/ce0a5bcb583229a9b07c0f83bcb1630ab1350640-624622-736-1036-jpg_250.jpg",
+ "title" : "C93 [Seventh_Lowlife] Komi-san ha Tokidoki Daitan desu (Komi-san wa Komyushou desu) [Sample]",
+ "title_jpn" : "(C93) [Comiketjack (わ!)] 古見さんは、時々大胆です。 (古見さんは、コミュ症です。) [見本]",
+ "token" : "d55c44d3d0",
+ "torrentcount": "0",
+ "uploader" : "klorpa",
+ "width" : int,
+},
+
+{
+ "#url" : "https://exhentai.org/g/960461/4f0e369d82/",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "http://exhentai.org/g/962698/7f02358e00/",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+ "#exception": exception.AuthorizationError,
+},
+
+{
+ "#url" : "https://exhentai.org/s/f68367b4c8/1200119-3",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+ "#options" : {"original": False},
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://e-hentai.org/s/f68367b4c8/1200119-3",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+ "#options" : {"original": False},
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://g.e-hentai.org/g/1200119/d55c44d3d0/",
+ "#category": ("", "exhentai", "gallery"),
+ "#class" : exhentai.ExhentaiGalleryExtractor,
+},
+
+{
+ "#url" : "https://e-hentai.org/?f_search=touhou",
+ "#category": ("", "exhentai", "search"),
+ "#class" : exhentai.ExhentaiSearchExtractor,
+},
+
+{
+ "#url" : "https://exhentai.org/?f_cats=767&f_search=touhou",
+ "#category": ("", "exhentai", "search"),
+ "#class" : exhentai.ExhentaiSearchExtractor,
+},
+
+{
+ "#url" : "https://exhentai.org/tag/parody:touhou+project",
+ "#category": ("", "exhentai", "search"),
+ "#class" : exhentai.ExhentaiSearchExtractor,
+},
+
+{
+ "#url" : "https://exhentai.org/?f_doujinshi=0&f_manga=0&f_artistcg=0&f_gamecg=0&f_western=0&f_non-h=1&f_imageset=0&f_cosplay=0&f_asianporn=0&f_misc=0&f_search=touhou&f_apply=Apply+Filter",
+ "#category": ("", "exhentai", "search"),
+ "#class" : exhentai.ExhentaiSearchExtractor,
+ "#pattern" : exhentai.ExhentaiGalleryExtractor.pattern,
+ "#range" : "1-30",
+ "#count" : 30,
+
+ "gallery_id" : int,
+ "gallery_token": r"re:^[0-9a-f]{10}$",
+},
+
+{
+ "#url" : "https://e-hentai.org/favorites.php",
+ "#category": ("", "exhentai", "favorite"),
+ "#class" : exhentai.ExhentaiFavoriteExtractor,
+ "#pattern" : r"https?://e-hentai\.org/g/1200119/d55c44d3d0",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://exhentai.org/favorites.php?favcat=1&f_search=touhou&f_apply=Search+Favorites",
+ "#category": ("", "exhentai", "favorite"),
+ "#class" : exhentai.ExhentaiFavoriteExtractor,
+},
+
+)
diff --git a/test/results/fallenangels.py b/test/results/fallenangels.py
new file mode 100644
index 00000000..e2167bb4
--- /dev/null
+++ b/test/results/fallenangels.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fallenangels
+
+
+__tests__ = (
+{
+ "#url" : "https://manga.fascans.com/manga/chronos-ruler/20/1",
+ "#category": ("", "fallenangels", "chapter"),
+ "#class" : fallenangels.FallenangelsChapterExtractor,
+ "#sha1_url" : "4604a7914566cc2da0ff789aa178e2d1c8c241e3",
+ "#sha1_metadata": "2dfcc50020e32cd207be88e2a8fac0933e36bdfb",
+},
+
+{
+ "#url" : "http://truyen.fascans.com/manga/hungry-marie/8",
+ "#category": ("", "fallenangels", "chapter"),
+ "#class" : fallenangels.FallenangelsChapterExtractor,
+ "#sha1_url" : "1f923d9cb337d5e7bbf4323719881794a951c6ae",
+ "#sha1_metadata": "2bdb7334c0e3eceb9946ffd3132df679b4a94f6a",
+},
+
+{
+ "#url" : "http://manga.fascans.com/manga/rakudai-kishi-no-eiyuutan/19.5",
+ "#category": ("", "fallenangels", "chapter"),
+ "#class" : fallenangels.FallenangelsChapterExtractor,
+ "#sha1_url" : "273f6863966c83ea79ad5846a2866e08067d3f0e",
+ "#sha1_metadata": "d1065685bfe0054c4ff2a0f20acb089de4cec253",
+},
+
+{
+ "#url" : "https://manga.fascans.com/manga/chronos-ruler",
+ "#category": ("", "fallenangels", "manga"),
+ "#class" : fallenangels.FallenangelsMangaExtractor,
+ "#sha1_url" : "eea07dd50f5bc4903aa09e2cc3e45c7241c9a9c2",
+ "#sha1_metadata": "c414249525d4c74ad83498b3c59a813557e59d7e",
+},
+
+{
+ "#url" : "https://truyen.fascans.com/manga/rakudai-kishi-no-eiyuutan",
+ "#category": ("", "fallenangels", "manga"),
+ "#class" : fallenangels.FallenangelsMangaExtractor,
+ "#sha1_url" : "51a731a6b82d5eb7a335fbae6b02d06aeb2ab07b",
+ "#sha1_metadata": "2d2a2a5d9ea5925eb9a47bb13d848967f3af086c",
+},
+
+)
diff --git a/test/results/fanbox.py b/test/results/fanbox.py
new file mode 100644
index 00000000..78f7fe54
--- /dev/null
+++ b/test/results/fanbox.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fanbox
+
+
+__tests__ = (
+{
+ "#url" : "https://xub.fanbox.cc",
+ "#category": ("", "fanbox", "creator"),
+ "#class" : fanbox.FanboxCreatorExtractor,
+ "#range" : "1-15",
+ "#count" : ">= 15",
+
+ "creatorId": "xub",
+ "tags" : list,
+ "title" : str,
+},
+
+{
+ "#url" : "https://xub.fanbox.cc/posts",
+ "#category": ("", "fanbox", "creator"),
+ "#class" : fanbox.FanboxCreatorExtractor,
+},
+
+{
+ "#url" : "https://www.fanbox.cc/@xub/",
+ "#category": ("", "fanbox", "creator"),
+ "#class" : fanbox.FanboxCreatorExtractor,
+},
+
+{
+ "#url" : "https://www.fanbox.cc/@xub/posts",
+ "#category": ("", "fanbox", "creator"),
+ "#class" : fanbox.FanboxCreatorExtractor,
+},
+
+{
+ "#url" : "https://www.fanbox.cc/@xub/posts/1910054",
+ "#category": ("", "fanbox", "post"),
+ "#class" : fanbox.FanboxPostExtractor,
+ "#count" : 3,
+
+ "title" : "えま★おうがすと",
+ "tags" : list,
+ "hasAdultContent": True,
+ "isCoverImage" : False,
+},
+
+{
+ "#url" : "https://nekoworks.fanbox.cc/posts/915",
+ "#comment" : "entry post type, image embedded in html of the post",
+ "#category": ("", "fanbox", "post"),
+ "#class" : fanbox.FanboxPostExtractor,
+ "#count" : 2,
+
+ "title" : "【SAYORI FAN CLUB】お届け内容",
+ "tags" : list,
+ "html" : str,
+ "hasAdultContent": True,
+},
+
+{
+ "#url" : "https://steelwire.fanbox.cc/posts/285502",
+ "#comment" : "article post type, imageMap, 2 twitter embeds, fanbox embed",
+ "#category": ("", "fanbox", "post"),
+ "#class" : fanbox.FanboxPostExtractor,
+ "#options" : {"embeds": True},
+ "#count" : 10,
+
+ "title" : "イラスト+SS|義足の炭鉱少年が義足を見せてくれるだけ 【全体公開版】",
+ "tags" : list,
+ "articleBody" : dict,
+ "hasAdultContent": True,
+},
+
+{
+ "#url" : "https://www.fanbox.cc/@official-en/posts/4326303",
+ "#comment" : "'content' metadata (#3020)",
+ "#category": ("", "fanbox", "post"),
+ "#class" : fanbox.FanboxPostExtractor,
+
+ "content": r"re:(?s)^Greetings from FANBOX.\n \nAs of Monday, September 5th, 2022, we are happy to announce the start of the FANBOX hashtag event #MySetupTour ! \nAbout the event\nTo join this event .+ \nPlease check this page for further details regarding the Privacy & Terms.\nhttps://fanbox.pixiv.help/.+/10184952456601\n\n\nThank you for your continued support of FANBOX.$",
+},
+
+{
+ "#url" : "https://mochirong.fanbox.cc/posts/3746116",
+ "#comment" : "imageMap file order (#2718)",
+ "#category": ("", "fanbox", "post"),
+ "#class" : fanbox.FanboxPostExtractor,
+ "#sha1_url": "c92ddd06f2efc4a5fe30ec67e21544f79a5c4062",
+},
+
+{
+ "#url" : "https://www.pixiv.net/fanbox/creator/52336352",
+ "#category": ("", "fanbox", "redirect"),
+ "#class" : fanbox.FanboxRedirectExtractor,
+ "#pattern" : fanbox.FanboxCreatorExtractor.pattern,
+},
+
+)
diff --git a/test/results/fanleaks.py b/test/results/fanleaks.py
new file mode 100644
index 00000000..c420e0ca
--- /dev/null
+++ b/test/results/fanleaks.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fanleaks
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://fanleaks.club/selti/880",
+ "#category": ("", "fanleaks", "post"),
+ "#class" : fanleaks.FanleaksPostExtractor,
+ "#pattern" : r"https://fanleaks\.club//models/selti/images/selti_0880\.jpg",
+
+ "model_id": "selti",
+ "model" : "Selti",
+ "id" : 880,
+ "type" : "photo",
+},
+
+{
+ "#url" : "https://fanleaks.club/daisy-keech/1038",
+ "#category": ("", "fanleaks", "post"),
+ "#class" : fanleaks.FanleaksPostExtractor,
+ "#pattern" : r"https://fanleaks\.club//models/daisy-keech/videos/daisy-keech_1038\.mp4",
+
+ "model_id": "daisy-keech",
+ "model" : "Daisy Keech",
+ "id" : 1038,
+ "type" : "video",
+},
+
+{
+ "#url" : "https://fanleaks.club/hannahowo/000",
+ "#category": ("", "fanleaks", "post"),
+ "#class" : fanleaks.FanleaksPostExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://fanleaks.club/hannahowo",
+ "#category": ("", "fanleaks", "model"),
+ "#class" : fanleaks.FanleaksModelExtractor,
+ "#pattern" : r"https://fanleaks\.club//models/hannahowo/(images|videos)/hannahowo_\d+\.\w+",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://fanleaks.club/belle-delphine",
+ "#category": ("", "fanleaks", "model"),
+ "#class" : fanleaks.FanleaksModelExtractor,
+ "#pattern" : r"https://fanleaks\.club//models/belle-delphine/(images|videos)/belle-delphine_\d+\.\w+",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://fanleaks.club/daisy-keech",
+ "#category": ("", "fanleaks", "model"),
+ "#class" : fanleaks.FanleaksModelExtractor,
+},
+
+)
diff --git a/test/results/fantia.py b/test/results/fantia.py
new file mode 100644
index 00000000..706b89d6
--- /dev/null
+++ b/test/results/fantia.py
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fantia
+
+
+__tests__ = (
+{
+ "#url" : "https://fantia.jp/fanclubs/6939",
+ "#category": ("", "fantia", "creator"),
+ "#class" : fantia.FantiaCreatorExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 25",
+
+ "fanclub_user_id": 52152,
+ "tags" : list,
+ "title" : str,
+},
+
+{
+ "#url" : "https://fantia.jp/posts/1166373",
+ "#category": ("", "fantia", "post"),
+ "#class" : fantia.FantiaPostExtractor,
+ "#pattern" : r"https://(c\.fantia\.jp/uploads/post/file/1166373/|cc\.fantia\.jp/uploads/post_content_photo/file/732549[01]|fantia\.jp/posts/1166373/album_image\?)",
+
+ "blogpost_text" : r"re:^$|This is a test.\n\nThis is a test.\n\n|Link to video:\nhttps://www.youtube.com/watch\?v=5SSdvNcAagI\n\nhtml img from another site:\n\n\n\n\n\n",
+ "comment" : """
+
+""",
+ "content_category": r"re:thumb|blog|photo_gallery",
+ "content_comment" : str,
+ "content_filename": r"re:|",
+ "content_title" : r"re:Test (Blog Content \d+|Image Gallery)|thumb",
+ "date" : "dt:2022-03-09 16:46:12",
+ "fanclub_id" : 356320,
+ "fanclub_name" : "Test Fantia",
+ "fanclub_url" : "https://fantia.jp/fanclubs/356320",
+ "fanclub_user_id" : 7487131,
+ "fanclub_user_name": "2022/03/08 15:13:52の名無し",
+ "file_url" : str,
+ "filename" : str,
+ "num" : int,
+ "plan" : dict,
+ "post_id" : 1166373,
+ "post_title" : "Test Fantia Post",
+ "post_url" : "https://fantia.jp/posts/1166373",
+ "posted_at" : "Thu, 10 Mar 2022 01:46:12 +0900",
+ "rating" : "general",
+ "tags" : [],
+},
+
+{
+ "#url" : "https://fantia.jp/posts/508363",
+ "#category": ("", "fantia", "post"),
+ "#class" : fantia.FantiaPostExtractor,
+ "#count" : 6,
+
+ "post_title": "zunda逆バニーでおしりコッショリ",
+ "tags" : list,
+ "rating" : "adult",
+ "post_id" : 508363,
+},
+
+)
diff --git a/test/results/fapachi.py b/test/results/fapachi.py
new file mode 100644
index 00000000..8907e7f8
--- /dev/null
+++ b/test/results/fapachi.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fapachi
+
+
+__tests__ = (
+{
+ "#url" : "https://fapachi.com/sonson/media/0082",
+ "#comment" : "NSFW",
+ "#category": ("", "fapachi", "post"),
+ "#class" : fapachi.FapachiPostExtractor,
+ "#pattern" : r"https://fapachi\.com/models/s/o/sonson/1/full/sonson_0082\.jpeg",
+
+ "user": "sonson",
+ "id" : "0082",
+},
+
+{
+ "#url" : "https://fapachi.com/ferxiita/media/0159",
+ "#comment" : "NSFW",
+ "#category": ("", "fapachi", "post"),
+ "#class" : fapachi.FapachiPostExtractor,
+},
+
+{
+ "#url" : "https://fapachi.com/sonson",
+ "#category": ("", "fapachi", "user"),
+ "#class" : fapachi.FapachiUserExtractor,
+ "#pattern" : fapachi.FapachiPostExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://fapachi.com/ferxiita/page/3",
+ "#category": ("", "fapachi", "user"),
+ "#class" : fapachi.FapachiUserExtractor,
+},
+
+)
diff --git a/test/results/fapello.py b/test/results/fapello.py
new file mode 100644
index 00000000..2b8381ca
--- /dev/null
+++ b/test/results/fapello.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fapello
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://fapello.com/carrykey/530/",
+ "#category": ("", "fapello", "post"),
+ "#class" : fapello.FapelloPostExtractor,
+ "#pattern" : r"https://fapello\.com/content/c/a/carrykey/1000/carrykey_0530\.jpg",
+
+ "model" : "carrykey",
+ "id" : 530,
+ "type" : "photo",
+ "thumbnail": "",
+},
+
+{
+ "#url" : "https://fapello.com/vladislava-661/693/",
+ "#category": ("", "fapello", "post"),
+ "#class" : fapello.FapelloPostExtractor,
+ "#pattern" : r"https://cdn\.fapello\.com/content/v/l/vladislava-661/1000/vladislava-661_0693\.mp4",
+
+ "model" : "vladislava-661",
+ "id" : 693,
+ "type" : "video",
+ "thumbnail": "https://fapello.com/content/v/l/vladislava-661/1000/vladislava-661_0693.jpg",
+},
+
+{
+ "#url" : "https://fapello.com/carrykey/000/",
+ "#category": ("", "fapello", "post"),
+ "#class" : fapello.FapelloPostExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://fapello.com/hyoon/",
+ "#category": ("", "fapello", "model"),
+ "#class" : fapello.FapelloModelExtractor,
+ "#pattern" : fapello.FapelloPostExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://fapello.com/kobaebeefboo/",
+ "#category": ("", "fapello", "model"),
+ "#class" : fapello.FapelloModelExtractor,
+},
+
+{
+ "#url" : "https://fapello.com/top-likes/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+ "#pattern" : fapello.FapelloModelExtractor.pattern,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://fapello.com/videos/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+ "#pattern" : fapello.FapelloPostExtractor.pattern,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://fapello.com/top-followers/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+},
+
+{
+ "#url" : "https://fapello.com/trending/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+},
+
+{
+ "#url" : "https://fapello.com/popular_videos/twelve_hours/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+},
+
+{
+ "#url" : "https://fapello.com/popular_videos/week/",
+ "#category": ("", "fapello", "path"),
+ "#class" : fapello.FapelloPathExtractor,
+},
+
+)
diff --git a/test/results/fappic.py b/test/results/fappic.py
new file mode 100644
index 00000000..b89c4e29
--- /dev/null
+++ b/test/results/fappic.py
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://fappic.com/98wxqcklyh8k/test.png",
+ "#category": ("imagehost", "fappic", "image"),
+ "#class" : imagehosts.FappicImageExtractor,
+},
+
+{
+ "#url" : "https://www.fappic.com/98wxqcklyh8k/test.png",
+ "#category": ("imagehost", "fappic", "image"),
+ "#class" : imagehosts.FappicImageExtractor,
+ "#pattern" : r"https://img\d+\.fappic\.com/img/\w+/test\.png",
+ "#sha1_metadata": "433b1d310b0ff12ad8a71ac7b9d8ba3f8cd1e898",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+)
diff --git a/test/results/fashionnova.py b/test/results/fashionnova.py
new file mode 100644
index 00000000..4225264f
--- /dev/null
+++ b/test/results/fashionnova.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://www.fashionnova.com/collections/mini-dresses",
+ "#category": ("shopify", "fashionnova", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.fashionnova.com/collections/mini-dresses/?page=1",
+ "#category": ("shopify", "fashionnova", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.fashionnova.com/collections/mini-dresses#1",
+ "#category": ("shopify", "fashionnova", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.fashionnova.com/products/essential-slide-red",
+ "#category": ("shopify", "fashionnova", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+ "#pattern" : r"https?://cdn\d*\.shopify.com/",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.fashionnova.com/collections/flats/products/name",
+ "#category": ("shopify", "fashionnova", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/fireden.py b/test/results/fireden.py
new file mode 100644
index 00000000..48549e18
--- /dev/null
+++ b/test/results/fireden.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://boards.fireden.net/sci/thread/11264294/",
+ "#category": ("foolfuuka", "fireden", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "61cab625c95584a12a30049d054931d64f8d20aa",
+},
+
+{
+ "#url" : "https://boards.fireden.net/sci/",
+ "#category": ("foolfuuka", "fireden", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://boards.fireden.net/_/search/text/test/",
+ "#category": ("foolfuuka", "fireden", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://boards.fireden.net/sci/gallery/6",
+ "#category": ("foolfuuka", "fireden", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/flickr.py b/test/results/flickr.py
new file mode 100644
index 00000000..5f1fee07
--- /dev/null
+++ b/test/results/flickr.py
@@ -0,0 +1,162 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import flickr
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.flickr.com/photos/departingyyz/16089302239",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#sha1_content": [
+ "3133006c6d657fe54cf7d4c46b82abbcb0efaf9f",
+ "0821a28ee46386e85b02b67cf2720063440a228c",
+ ],
+
+ "comments" : int,
+ "description": str,
+ "extension" : "jpg",
+ "filename" : "16089302239_de18cd8017_b",
+ "id" : 16089302239,
+ "height" : 683,
+ "label" : "Large",
+ "media" : "photo",
+ "url" : str,
+ "views" : int,
+ "width" : 1024,
+},
+
+{
+ "#url" : "https://secure.flickr.com/photos/departingyyz/16089302239",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+},
+
+{
+ "#url" : "https://m.flickr.com/photos/departingyyz/16089302239",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+},
+
+{
+ "#url" : "https://flickr.com/photos/departingyyz/16089302239",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/145617051@N08/46733161535",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#count" : 1,
+
+ "media": "video",
+},
+
+{
+ "#url" : "http://c2.staticflickr.com/2/1475/24531000464_9a7503ae68_b.jpg",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+},
+
+{
+ "#url" : "https://farm2.static.flickr.com/1035/1188352415_cb139831d0.jpg",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+},
+
+{
+ "#url" : "https://flic.kr/p/FPVo9U",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/zzz/16089302238",
+ "#category": ("", "flickr", "image"),
+ "#class" : flickr.FlickrImageExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/shona_s/albums/72157633471741607",
+ "#category": ("", "flickr", "album"),
+ "#class" : flickr.FlickrAlbumExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#count" : 6,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/shona_s/albums",
+ "#category": ("", "flickr", "album"),
+ "#class" : flickr.FlickrAlbumExtractor,
+ "#pattern" : flickr.FlickrAlbumExtractor.pattern,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://secure.flickr.com/photos/shona_s/albums",
+ "#category": ("", "flickr", "album"),
+ "#class" : flickr.FlickrAlbumExtractor,
+},
+
+{
+ "#url" : "https://m.flickr.com/photos/shona_s/albums",
+ "#category": ("", "flickr", "album"),
+ "#class" : flickr.FlickrAlbumExtractor,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/flickr/galleries/72157681572514792/",
+ "#category": ("", "flickr", "gallery"),
+ "#class" : flickr.FlickrGalleryExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#count" : ">= 10",
+},
+
+{
+ "#url" : "https://www.flickr.com/groups/bird_headshots/",
+ "#category": ("", "flickr", "group"),
+ "#class" : flickr.FlickrGroupExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#count" : "> 150",
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/shona_s/",
+ "#category": ("", "flickr", "user"),
+ "#class" : flickr.FlickrUserExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#count" : 28,
+},
+
+{
+ "#url" : "https://www.flickr.com/photos/shona_s/favorites",
+ "#category": ("", "flickr", "favorite"),
+ "#class" : flickr.FlickrFavoriteExtractor,
+ "#pattern" : flickr.FlickrImageExtractor.pattern,
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://flickr.com/search/?text=mountain",
+ "#category": ("", "flickr", "search"),
+ "#class" : flickr.FlickrSearchExtractor,
+},
+
+{
+ "#url" : "https://flickr.com/search/?text=tree%20cloud%20house&color_codes=4&styles=minimalism",
+ "#category": ("", "flickr", "search"),
+ "#class" : flickr.FlickrSearchExtractor,
+},
+
+)
diff --git a/test/results/foalcon.py b/test/results/foalcon.py
new file mode 100644
index 00000000..7639c0df
--- /dev/null
+++ b/test/results/foalcon.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import szurubooru
+
+
+__tests__ = (
+{
+ "#url" : "https://booru.foalcon.com/posts/query=simple_background",
+ "#category": ("szurubooru", "foalcon", "tag"),
+ "#class" : szurubooru.SzurubooruTagExtractor,
+ "#pattern" : r"https://booru\.foalcon\.com/data/posts/\d+_[0-9a-f]{16}\.\w+",
+ "#range" : "1-150",
+ "#count" : 150,
+},
+
+{
+ "#url" : "https://booru.foalcon.com/post/30092",
+ "#category": ("szurubooru", "foalcon", "post"),
+ "#class" : szurubooru.SzurubooruPostExtractor,
+ "#pattern" : r"https://booru\.foalcon\.com/data/posts/30092_b7d56e941888b624\.png",
+ "#sha1_url" : "dad4d4c67d87cd9a4ac429b3414747c27a95d5cb",
+ "#sha1_content": "86d1514c0ca8197950cc4b74e7a59b2dc76ebf9c",
+},
+
+)
diff --git a/test/results/furaffinity.py b/test/results/furaffinity.py
new file mode 100644
index 00000000..187029bb
--- /dev/null
+++ b/test/results/furaffinity.py
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import furaffinity
+
+
+__tests__ = (
+{
+ "#url" : "https://www.furaffinity.net/gallery/mirlinthloth/",
+ "#category": ("", "furaffinity", "gallery"),
+ "#class" : furaffinity.FuraffinityGalleryExtractor,
+ "#pattern" : r"https://d\d?\.f(uraffinity|acdn)\.net/art/mirlinthloth/\d+/\d+.\w+\.\w+",
+ "#range" : "45-50",
+ "#count" : 6,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/scraps/mirlinthloth/",
+ "#category": ("", "furaffinity", "scraps"),
+ "#class" : furaffinity.FuraffinityScrapsExtractor,
+ "#pattern" : r"https://d\d?\.f(uraffinity|acdn)\.net/art/[^/]+(/stories)?/\d+/\d+.\w+.",
+ "#count" : ">= 3",
+},
+
+{
+ "#url" : "https://www.furaffinity.net/favorites/mirlinthloth/",
+ "#category": ("", "furaffinity", "favorite"),
+ "#class" : furaffinity.FuraffinityFavoriteExtractor,
+ "#pattern" : r"https://d\d?\.f(uraffinity|acdn)\.net/art/[^/]+/\d+/\d+.\w+\.\w+",
+ "#range" : "45-50",
+ "#count" : 6,
+
+ "favorite_id": int,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/search/?q=cute",
+ "#category": ("", "furaffinity", "search"),
+ "#class" : furaffinity.FuraffinitySearchExtractor,
+ "#pattern" : r"https://d\d?\.f(uraffinity|acdn)\.net/art/[^/]+/\d+/\d+.\w+\.\w+",
+ "#range" : "45-50",
+ "#count" : 6,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/search/?q=leaf&range=1day",
+ "#comment" : "first page of search results (#2402)",
+ "#category": ("", "furaffinity", "search"),
+ "#class" : furaffinity.FuraffinitySearchExtractor,
+ "#range" : "1-3",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/view/21835115/",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+ "#pattern" : r"https://d\d*\.f(uraffinity|acdn)\.net/(download/)?art/mirlinthloth/music/1488278723/1480267446.mirlinthloth_dj_fennmink_-_bude_s_4_ever\.mp3",
+
+ "artist" : "mirlinthloth",
+ "artist_url" : "mirlinthloth",
+ "date" : "dt:2016-11-27 17:24:06",
+ "description": "A Song made playing the game Cosmic DJ.",
+ "extension" : "mp3",
+ "filename" : r"re:\d+\.\w+_dj_fennmink_-_bude_s_4_ever",
+ "id" : 21835115,
+ "tags" : list,
+ "title" : "Bude's 4 Ever",
+ "url" : r"re:https://d\d?\.f(uraffinity|acdn)\.net/art",
+ "user" : "mirlinthloth",
+ "views" : int,
+ "favorites" : int,
+ "comments" : int,
+ "rating" : "General",
+ "fa_category": "Music",
+ "theme" : "All",
+ "species" : "Unspecified / Any",
+ "gender" : "Any",
+ "width" : 120,
+ "height" : 120,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/view/42166511/",
+ "#comment" : "'external' option (#1492)",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+ "#options" : {"external": True},
+ "#pattern" : r"https://d\d*\.f(uraffinity|acdn)\.net/|http://www\.postybirb\.com",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/view/45331225/",
+ "#comment" : "no tags (#2277)",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+
+ "artist" : "Kota_Remminders",
+ "artist_url" : "kotaremminders",
+ "date" : "dt:2022-01-03 17:49:33",
+ "fa_category": "Adoptables",
+ "filename" : "1641232173.kotaremminders_chidopts1",
+ "gender" : "Any",
+ "height" : 905,
+ "id" : 45331225,
+ "rating" : "General",
+ "species" : "Unspecified / Any",
+ "tags" : [],
+ "theme" : "All",
+ "title" : "REMINDER",
+ "width" : 1280,
+},
+
+{
+ "#url" : "https://furaffinity.net/view/21835115/",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+},
+
+{
+ "#url" : "https://sfw.furaffinity.net/view/21835115/",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/full/21835115/",
+ "#category": ("", "furaffinity", "post"),
+ "#class" : furaffinity.FuraffinityPostExtractor,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/user/mirlinthloth/",
+ "#category": ("", "furaffinity", "user"),
+ "#class" : furaffinity.FuraffinityUserExtractor,
+ "#pattern" : "/gallery/mirlinthloth/$",
+},
+
+{
+ "#url" : "https://www.furaffinity.net/user/mirlinthloth/",
+ "#category": ("", "furaffinity", "user"),
+ "#class" : furaffinity.FuraffinityUserExtractor,
+ "#options" : {"include": "all"},
+ "#pattern" : "/(gallery|scraps|favorites)/mirlinthloth/$",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.furaffinity.net/watchlist/by/mirlinthloth/",
+ "#category": ("", "furaffinity", "following"),
+ "#class" : furaffinity.FuraffinityFollowingExtractor,
+ "#pattern" : furaffinity.FuraffinityUserExtractor.pattern,
+ "#range" : "176-225",
+ "#count" : 50,
+},
+
+)
diff --git a/test/results/furbooru.py b/test/results/furbooru.py
new file mode 100644
index 00000000..682aa005
--- /dev/null
+++ b/test/results/furbooru.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import philomena
+
+
+__tests__ = (
+{
+ "#url" : "https://furbooru.org/images/1",
+ "#category": ("philomena", "furbooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+ "#sha1_content": "9eaa1e1b32fa0f16520912257dbefaff238d5fd2",
+},
+
+{
+ "#url" : "https://furbooru.org/search?q=cute",
+ "#category": ("philomena", "furbooru", "search"),
+ "#class" : philomena.PhilomenaSearchExtractor,
+ "#range" : "40-60",
+ "#count" : 21,
+},
+
+{
+ "#url" : "https://furbooru.org/galleries/27",
+ "#category": ("philomena", "furbooru", "gallery"),
+ "#class" : philomena.PhilomenaGalleryExtractor,
+ "#count" : ">= 13",
+},
+
+)
diff --git a/test/results/fuskator.py b/test/results/fuskator.py
new file mode 100644
index 00000000..cd68c9c2
--- /dev/null
+++ b/test/results/fuskator.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import fuskator
+
+
+__tests__ = (
+{
+ "#url" : "https://fuskator.com/thumbs/d0GnIzXrSKU/",
+ "#category": ("", "fuskator", "gallery"),
+ "#class" : fuskator.FuskatorGalleryExtractor,
+ "#pattern" : r"https://i\d+.fuskator.com/large/d0GnIzXrSKU/.+\.jpg",
+ "#count" : 22,
+
+ "gallery_id" : 473023,
+ "gallery_hash": "d0GnIzXrSKU",
+ "title" : r"re:Shaved Brunette Babe Maria Ryabushkina with ",
+ "views" : int,
+ "score" : float,
+ "count" : 22,
+ "tags" : list,
+},
+
+{
+ "#url" : "https://fuskator.com/expanded/gXpKzjgIidA/index.html",
+ "#category": ("", "fuskator", "gallery"),
+ "#class" : fuskator.FuskatorGalleryExtractor,
+},
+
+{
+ "#url" : "https://fuskator.com/search/red_swimsuit/",
+ "#category": ("", "fuskator", "search"),
+ "#class" : fuskator.FuskatorSearchExtractor,
+ "#pattern" : fuskator.FuskatorGalleryExtractor.pattern,
+ "#count" : ">= 40",
+},
+
+{
+ "#url" : "https://fuskator.com/page/3/swimsuit/quality/",
+ "#category": ("", "fuskator", "search"),
+ "#class" : fuskator.FuskatorSearchExtractor,
+},
+
+)
diff --git a/test/results/gelbooru.py b/test/results/gelbooru.py
new file mode 100644
index 00000000..8d9ead27
--- /dev/null
+++ b/test/results/gelbooru.py
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru
+
+
+__tests__ = (
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=list&tags=bonocho",
+ "#category": ("booru", "gelbooru", "tag"),
+ "#class" : gelbooru.GelbooruTagExtractor,
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=list&tags=meiya_neon",
+ "#category": ("booru", "gelbooru", "tag"),
+ "#class" : gelbooru.GelbooruTagExtractor,
+ "#pattern" : r"https://img\d\.gelbooru\.com/images/../../[0-9a-f]{32}\.jpg",
+ "#range" : "196-204",
+ "#count" : 9,
+ "#sha1_url": "845a61aa1f90fb4ced841e8b7e62098be2e967bf",
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=pool&s=show&id=761",
+ "#category": ("booru", "gelbooru", "pool"),
+ "#class" : gelbooru.GelbooruPoolExtractor,
+ "#count" : 6,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=favorites&s=view&id=279415",
+ "#category": ("booru", "gelbooru", "favorite"),
+ "#class" : gelbooru.GelbooruFavoriteExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=view&id=313638",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+ "#count" : 1,
+ "#sha1_content": "5e255713cbf0a8e0801dc423563c34d896bb9229",
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=view&id=313638",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?s=view&page=post&id=313638",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&id=313638&s=view",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?s=view&id=313638&page=post",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?id=313638&page=post&s=view",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?id=313638&s=view&page=post",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=view&id=6018318",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_content": "977caf22f27c72a5d07ea4d4d9719acdab810991",
+
+ "tags_artist" : "kirisaki_shuusei",
+ "tags_character": str,
+ "tags_copyright": "vocaloid",
+ "tags_general" : str,
+ "tags_metadata" : str,
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=view&id=5938076",
+ "#comment" : "video",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+ "#pattern" : r"https://img\d\.gelbooru\.com/images/22/61/226111273615049235b001b381707bd0\.webm",
+ "#sha1_content": "6360452fa8c2f0c1137749e81471238564df832a",
+},
+
+{
+ "#url" : "https://gelbooru.com/index.php?page=post&s=view&id=5997331",
+ "#comment" : "notes",
+ "#category": ("booru", "gelbooru", "post"),
+ "#class" : gelbooru.GelbooruPostExtractor,
+ "#options" : {"notes": True},
+
+ "notes": [
+ {
+ "body" : "Look over this way when you talk~",
+ "height": 553,
+ "width" : 246,
+ "x" : 35,
+ "y" : 72,
+ },
+ {
+ "body" : """Hey~
+Are you listening~?""",
+ "height": 557,
+ "width" : 246,
+ "x" : 1233,
+ "y" : 109,
+ },
+ ],
+},
+
+{
+ "#url" : "https://gelbooru.com/redirect.php?s=Ly9nZWxib29ydS5jb20vaW5kZXgucGhwP3BhZ2U9cG9zdCZzPXZpZXcmaWQ9MTgzMDA0Ng==",
+ "#category": ("booru", "gelbooru", "redirect"),
+ "#class" : gelbooru.GelbooruRedirectExtractor,
+ "#pattern" : r"https://gelbooru.com/index.php\?page=post&s=view&id=1830046",
+},
+
+)
diff --git a/test/results/generic.py b/test/results/generic.py
new file mode 100644
index 00000000..dea9f7cd
--- /dev/null
+++ b/test/results/generic.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import generic
+
+
+__tests__ = (
+{
+ "#url" : "https://www.nongnu.org/lzip/",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+ "#count" : 1,
+ "#sha1_content": "40be5c77773d3e91db6e1c5df720ee30afb62368",
+
+ "description": "Lossless data compressor",
+ "imageurl" : "https://www.nongnu.org/lzip/lzip.png",
+ "keywords" : "lzip, clzip, plzip, lzlib, LZMA, bzip2, gzip, data compression, GNU, free software",
+ "pageurl" : "https://www.nongnu.org/lzip/",
+},
+
+{
+ "#url" : "https://räksmörgås.josefsson.org/",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+ "#pattern" : "^https://räksmörgås.josefsson.org/",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://en.wikipedia.org/Main_Page",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+{
+ "#url" : "https://example.org/path/to/file?que=1?&ry=2/#fragment",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+{
+ "#url" : "https://example.org/%27%3C%23/%23%3E%27.htm?key=%3C%26%3E",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+{
+ "#url" : "https://en.wikipedia.org/Main_Page",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+{
+ "#url" : "https://example.org/path/to/file?que=1?&ry=2/#fragment",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+{
+ "#url" : "https://example.org/%27%3C%23/%23%3E%27.htm?key=%3C%26%3E",
+ "#category": ("", "generic", ""),
+ "#class" : generic.GenericExtractor,
+},
+
+)
diff --git a/test/results/giantessbooru.py b/test/results/giantessbooru.py
new file mode 100644
index 00000000..5909c191
--- /dev/null
+++ b/test/results/giantessbooru.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shimmie2
+
+
+__tests__ = (
+{
+ "#url" : "https://giantessbooru.com/index.php?q=/post/list/drawing/1",
+ "#category": ("shimmie2", "giantessbooru", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+ "#pattern" : r"https://giantessbooru\.com/index\.php\?q=/image/\d+\.jpg",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://giantessbooru.com/post/list/drawing/1",
+ "#category": ("shimmie2", "giantessbooru", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+},
+
+{
+ "#url" : "https://giantessbooru.com/index.php?q=/post/view/41",
+ "#category": ("shimmie2", "giantessbooru", "post"),
+ "#class" : shimmie2.Shimmie2PostExtractor,
+ "#pattern" : r"https://giantessbooru\.com/index\.php\?q=/image/41\.jpg",
+ "#sha1_content": "79115ed309d1f4e82e7bead6948760e889139c91",
+
+ "extension": "jpg",
+ "file_url" : "https://giantessbooru.com/index.php?q=/image/41.jpg",
+ "filename" : "41",
+ "height" : 0,
+ "id" : 41,
+ "md5" : "",
+ "size" : 0,
+ "tags" : "anime bare_midriff color drawing gentle giantess karbo looking_at_tinies negeyari outdoors smiling snake_girl white_hair",
+ "width" : 1387,
+},
+
+{
+ "#url" : "https://giantessbooru.com/post/view/41",
+ "#category": ("shimmie2", "giantessbooru", "post"),
+ "#class" : shimmie2.Shimmie2PostExtractor,
+},
+
+)
diff --git a/test/results/gofile.py b/test/results/gofile.py
new file mode 100644
index 00000000..b7d26702
--- /dev/null
+++ b/test/results/gofile.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gofile
+
+
+__tests__ = (
+{
+ "#url" : "https://gofile.io/d/k6BomI",
+ "#category": ("", "gofile", "folder"),
+ "#class" : gofile.GofileFolderExtractor,
+ "#pattern" : r"https://store\d+\.gofile\.io/download/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/test-%E3%83%86%E3%82%B9%E3%83%88-%2522%26!\.png",
+
+ "createTime" : int,
+ "directLink" : r"re:https://store5.gofile.io/download/direct/.+",
+ "downloadCount": int,
+ "extension" : "png",
+ "filename" : "test-テスト-%22&!",
+ "folder" : {
+ "childs" : [
+ "b0367d79-b8ba-407f-8342-aaf8eb815443",
+ "7fd4a36a-c1dd-49ff-9223-d93f7d24093f",
+ ],
+ "code" : "k6BomI",
+ "createTime" : 1654076165,
+ "id" : "fafb59f9-a7c7-4fea-a098-b29b8d97b03c",
+ "name" : "root",
+ "public" : True,
+ "totalDownloadCount": int,
+ "totalSize" : 182,
+ "type" : "folder",
+ },
+ "id" : r"re:\w{8}-\w{4}-\w{4}-\w{4}-\w{12}",
+ "link" : r"re:https://store5.gofile.io/download/.+\.png",
+ "md5" : r"re:[0-9a-f]{32}",
+ "mimetype" : "image/png",
+ "name" : "test-テスト-%22&!.png",
+ "num" : int,
+ "parentFolder" : "fafb59f9-a7c7-4fea-a098-b29b8d97b03c",
+ "serverChoosen": "store5",
+ "size" : 182,
+ "thumbnail" : r"re:https://store5.gofile.io/download/.+\.png",
+ "type" : "file",
+},
+
+{
+ "#url" : "https://gofile.io/d/7fd4a36a-c1dd-49ff-9223-d93f7d24093f",
+ "#category": ("", "gofile", "folder"),
+ "#class" : gofile.GofileFolderExtractor,
+ "#options" : {"website-token": None},
+ "#sha1_content": "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+)
diff --git a/test/results/hbrowse.py b/test/results/hbrowse.py
new file mode 100644
index 00000000..c4b3dcd6
--- /dev/null
+++ b/test/results/hbrowse.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hbrowse
+
+
+__tests__ = (
+{
+ "#url" : "https://www.hbrowse.com/10363/c00000",
+ "#category": ("", "hbrowse", "chapter"),
+ "#class" : hbrowse.HbrowseChapterExtractor,
+ "#sha1_url" : "6feefbc9f4b98e20d8425ddffa9dd111791dc3e6",
+ "#sha1_metadata": "274996f6c809e5250b6ff3abbc5147e29f89d9a5",
+ "#sha1_content" : "44578ebbe176c2c27434966aef22945787e2781e",
+},
+
+{
+ "#url" : "https://www.hbrowse.com/10363",
+ "#category": ("", "hbrowse", "manga"),
+ "#class" : hbrowse.HbrowseMangaExtractor,
+ "#sha1_url" : "b89682bfb86c11d2af0dc47463804ec3ac4aadd6",
+ "#sha1_metadata": "4b15fda1858a69de1fbf5afddfe47dd893397312",
+},
+
+)
diff --git a/test/results/hentai2read.py b/test/results/hentai2read.py
new file mode 100644
index 00000000..01349c2e
--- /dev/null
+++ b/test/results/hentai2read.py
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentai2read
+
+
+__tests__ = (
+{
+ "#url" : "https://hentai2read.com/amazon_elixir/1/",
+ "#category": ("", "hentai2read", "chapter"),
+ "#class" : hentai2read.Hentai2readChapterExtractor,
+ "#sha1_url" : "964b942cf492b3a129d2fe2608abfc475bc99e71",
+ "#sha1_metadata": "85645b02d34aa11b3deb6dadd7536863476e1bad",
+},
+
+{
+ "#url" : "https://hentai2read.com/popuni_kei_joshi_panic/2.5/",
+ "#category": ("", "hentai2read", "chapter"),
+ "#class" : hentai2read.Hentai2readChapterExtractor,
+ "#pattern" : r"https://hentaicdn\.com/hentai/13088/2\.5y/ccdn00\d+\.jpg",
+ "#count" : 36,
+
+ "author" : "Kurisu",
+ "chapter" : 2,
+ "chapter_id" : 75152,
+ "chapter_minor": ".5",
+ "count" : 36,
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Popuni Kei Joshi Panic!",
+ "manga_id" : 13088,
+ "page" : int,
+ "title" : "Popuni Kei Joshi Panic! 2.5",
+ "type" : "Original",
+},
+
+{
+ "#url" : "https://hentai2read.com/amazon_elixir/",
+ "#category": ("", "hentai2read", "manga"),
+ "#class" : hentai2read.Hentai2readMangaExtractor,
+ "#sha1_url" : "273073752d418ec887d7f7211e42b832e8c403ba",
+ "#sha1_metadata": "5c1b712258e78e120907121d3987c71f834d13e1",
+},
+
+{
+ "#url" : "https://hentai2read.com/oshikage_riot/",
+ "#category": ("", "hentai2read", "manga"),
+ "#class" : hentai2read.Hentai2readMangaExtractor,
+ "#sha1_url" : "6595f920a3088a15c2819c502862d45f8eb6bea6",
+ "#sha1_metadata": "a2e9724acb221040d4b29bf9aa8cb75b2240d8af",
+},
+
+{
+ "#url" : "https://hentai2read.com/popuni_kei_joshi_panic/",
+ "#category": ("", "hentai2read", "manga"),
+ "#class" : hentai2read.Hentai2readMangaExtractor,
+ "#pattern" : hentai2read.Hentai2readChapterExtractor.pattern,
+ "#range" : "2-3",
+
+ "chapter" : int,
+ "chapter_id" : int,
+ "chapter_minor": ".5",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Popuni Kei Joshi Panic!",
+ "manga_id" : 13088,
+ "title" : str,
+ "type" : "Original",
+},
+
+)
diff --git a/test/results/hentaicosplays.py b/test/results/hentaicosplays.py
new file mode 100644
index 00000000..9760aee8
--- /dev/null
+++ b/test/results/hentaicosplays.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentaicosplays
+
+
+__tests__ = (
+{
+ "#url" : "https://hentai-cosplays.com/image/---devilism--tide-kurihara-/",
+ "#category": ("", "hentaicosplays", "gallery"),
+ "#class" : hentaicosplays.HentaicosplaysGalleryExtractor,
+ "#pattern" : r"https://static\d?.hentai-cosplays.com/upload/\d+/\d+/\d+/\d+.jpg$",
+
+ "count": 18,
+ "site" : "hentai-cosplays",
+ "slug" : "---devilism--tide-kurihara-",
+ "title": "艦 こ れ-devilism の tide Kurihara 憂",
+},
+
+{
+ "#url" : "https://fr.porn-images-xxx.com/image/enako-enako-24/",
+ "#category": ("", "hentaicosplays", "gallery"),
+ "#class" : hentaicosplays.HentaicosplaysGalleryExtractor,
+ "#pattern" : r"https://static\d?.porn-images-xxx.com/upload/\d+/\d+/\d+/\d+.jpg$",
+
+ "count": 11,
+ "site" : "porn-images-xxx",
+ "title": str,
+},
+
+{
+ "#url" : "https://ja.hentai-img.com/image/hollow-cora-502/",
+ "#category": ("", "hentaicosplays", "gallery"),
+ "#class" : hentaicosplays.HentaicosplaysGalleryExtractor,
+ "#pattern" : r"https://static\d?.hentai-img.com/upload/\d+/\d+/\d+/\d+.jpg$",
+
+ "count": 2,
+ "site" : "hentai-img",
+ "title": str,
+},
+
+)
diff --git a/test/results/hentaifoundry.py b/test/results/hentaifoundry.py
new file mode 100644
index 00000000..4dc4515d
--- /dev/null
+++ b/test/results/hentaifoundry.py
@@ -0,0 +1,152 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentaifoundry
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://www.hentai-foundry.com/user/Tenpura/profile",
+ "#category": ("", "hentaifoundry", "user"),
+ "#class" : hentaifoundry.HentaifoundryUserExtractor,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Tenpura",
+ "#category": ("", "hentaifoundry", "pictures"),
+ "#class" : hentaifoundry.HentaifoundryPicturesExtractor,
+ "#sha1_url": "ebbc981a85073745e3ca64a0f2ab31fab967fc28",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Tenpura/page/3",
+ "#category": ("", "hentaifoundry", "pictures"),
+ "#class" : hentaifoundry.HentaifoundryPicturesExtractor,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Evulchibi/scraps",
+ "#category": ("", "hentaifoundry", "scraps"),
+ "#class" : hentaifoundry.HentaifoundryScrapsExtractor,
+ "#sha1_url": "7cd9c6ec6258c4ab8c44991f7731be82337492a7",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Evulchibi/scraps/page/3",
+ "#category": ("", "hentaifoundry", "scraps"),
+ "#class" : hentaifoundry.HentaifoundryScrapsExtractor,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/user/Tenpura/faves/pictures",
+ "#category": ("", "hentaifoundry", "favorite"),
+ "#class" : hentaifoundry.HentaifoundryFavoriteExtractor,
+ "#sha1_url": "56f9ae2e89fe855e9fe1da9b81e5ec6212b0320b",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/user/Tenpura/faves/pictures/page/3",
+ "#category": ("", "hentaifoundry", "favorite"),
+ "#class" : hentaifoundry.HentaifoundryFavoriteExtractor,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/recent/2018-09-20",
+ "#category": ("", "hentaifoundry", "recent"),
+ "#class" : hentaifoundry.HentaifoundryRecentExtractor,
+ "#pattern" : r"https://pictures.hentai-foundry.com/[^/]/[^/?#]+/\d+/",
+ "#range" : "20-30",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/popular",
+ "#category": ("", "hentaifoundry", "popular"),
+ "#class" : hentaifoundry.HentaifoundryPopularExtractor,
+ "#pattern" : r"https://pictures.hentai-foundry.com/[^/]/[^/?#]+/\d+/",
+ "#range" : "20-30",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Tenpura/407501/shimakaze",
+ "#category": ("", "hentaifoundry", "image"),
+ "#class" : hentaifoundry.HentaifoundryImageExtractor,
+ "#sha1_url" : "fbf2fd74906738094e2575d2728e8dc3de18a8a3",
+ "#sha1_content": "91bf01497c39254b6dfb234a18e8f01629c77fd1",
+
+ "artist" : "Tenpura",
+ "date" : "dt:2016-02-22 14:41:19",
+ "description": "Thank you!",
+ "height" : 700,
+ "index" : 407501,
+ "media" : "Other digital art",
+ "ratings" : [
+ "Sexual content",
+ "Contains female nudity",
+ ],
+ "score" : int,
+ "tags" : [
+ "collection",
+ "kancolle",
+ "kantai",
+ "shimakaze",
+ ],
+ "title" : "shimakaze",
+ "user" : "Tenpura",
+ "views" : int,
+ "width" : 495,
+},
+
+{
+ "#url" : "http://www.hentai-foundry.com/pictures/user/Tenpura/407501/",
+ "#category": ("", "hentaifoundry", "image"),
+ "#class" : hentaifoundry.HentaifoundryImageExtractor,
+ "#pattern" : "http://pictures.hentai-foundry.com/t/Tenpura/407501/",
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/pictures/user/Tenpura/407501/",
+ "#category": ("", "hentaifoundry", "image"),
+ "#class" : hentaifoundry.HentaifoundryImageExtractor,
+},
+
+{
+ "#url" : "https://pictures.hentai-foundry.com/t/Tenpura/407501/Tenpura-407501-shimakaze.png",
+ "#category": ("", "hentaifoundry", "image"),
+ "#class" : hentaifoundry.HentaifoundryImageExtractor,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/stories/user/SnowWolf35",
+ "#category": ("", "hentaifoundry", "stories"),
+ "#class" : hentaifoundry.HentaifoundryStoriesExtractor,
+ "#count" : ">= 35",
+
+ "author" : "SnowWolf35",
+ "chapters" : int,
+ "comments" : int,
+ "date" : datetime.datetime,
+ "description": str,
+ "index" : int,
+ "rating" : int,
+ "ratings" : list,
+ "status" : r"re:(Inc|C)omplete",
+ "title" : str,
+ "user" : "SnowWolf35",
+ "views" : int,
+ "words" : int,
+},
+
+{
+ "#url" : "https://www.hentai-foundry.com/stories/user/SnowWolf35/26416/Overwatch-High-Chapter-Voting-Location",
+ "#category": ("", "hentaifoundry", "story"),
+ "#class" : hentaifoundry.HentaifoundryStoryExtractor,
+ "#sha1_url": "5a67cfa8c3bf7634c8af8485dd07c1ea74ee0ae8",
+
+ "title": "Overwatch High Chapter Voting Location",
+},
+
+)
diff --git a/test/results/hentaifox.py b/test/results/hentaifox.py
new file mode 100644
index 00000000..123bd277
--- /dev/null
+++ b/test/results/hentaifox.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentaifox
+
+
+__tests__ = (
+{
+ "#url" : "https://hentaifox.com/gallery/56622/",
+ "#category": ("", "hentaifox", "gallery"),
+ "#class" : hentaifox.HentaifoxGalleryExtractor,
+ "#pattern" : r"https://i\d*\.hentaifox\.com/\d+/\d+/\d+\.jpg",
+ "#count" : 24,
+ "#sha1_metadata": "bcd6b67284f378e5cc30b89b761140e3e60fcd92",
+},
+
+{
+ "#url" : "https://hentaifox.com/gallery/630/",
+ "#comment" : "'split_tag' element (#1378)",
+ "#category": ("", "hentaifox", "gallery"),
+ "#class" : hentaifox.HentaifoxGalleryExtractor,
+
+ "artist" : [
+ "beti",
+ "betty",
+ "magi",
+ "mimikaki",
+ ],
+ "characters": [
+ "aerith gainsborough",
+ "tifa lockhart",
+ "yuffie kisaragi",
+ ],
+ "count" : 32,
+ "gallery_id": 630,
+ "group" : ["cu-little2"],
+ "parody" : [
+ "darkstalkers | vampire",
+ "final fantasy vii",
+ ],
+ "tags" : [
+ "femdom",
+ "fingering",
+ "masturbation",
+ "yuri",
+ ],
+ "title" : "Cu-Little Bakanya~",
+ "type" : "doujinshi",
+},
+
+{
+ "#url" : "https://hentaifox.com/gallery/35261/",
+ "#comment" : "email-protected title (#4201)",
+ "#category": ("", "hentaifox", "gallery"),
+ "#class" : hentaifox.HentaifoxGalleryExtractor,
+
+ "gallery_id": 35261,
+ "title" : "ManageM@ster!",
+ "artist" : ["haritama hiroki"],
+ "group" : ["studio n.ball"],
+},
+
+{
+ "#url" : "https://hentaifox.com/parody/touhou-project/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+},
+
+{
+ "#url" : "https://hentaifox.com/character/reimu-hakurei/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+},
+
+{
+ "#url" : "https://hentaifox.com/artist/distance/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+},
+
+{
+ "#url" : "https://hentaifox.com/search/touhou/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+},
+
+{
+ "#url" : "https://hentaifox.com/group/v-slash/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+},
+
+{
+ "#url" : "https://hentaifox.com/tag/heterochromia/",
+ "#category": ("", "hentaifox", "search"),
+ "#class" : hentaifox.HentaifoxSearchExtractor,
+ "#pattern" : hentaifox.HentaifoxGalleryExtractor.pattern,
+ "#count" : ">= 60",
+
+ "url" : str,
+ "gallery_id": int,
+ "title" : str,
+},
+
+)
diff --git a/test/results/hentaihand.py b/test/results/hentaihand.py
new file mode 100644
index 00000000..3d9a34b6
--- /dev/null
+++ b/test/results/hentaihand.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentaihand
+
+
+__tests__ = (
+{
+ "#url" : "https://hentaihand.com/en/comic/c75-takumi-na-muchi-choudenji-hou-no-aishi-kata-how-to-love-a-super-electromagnetic-gun-toaru-kagaku-no-railgun-english",
+ "#category": ("", "hentaihand", "gallery"),
+ "#class" : hentaihand.HentaihandGalleryExtractor,
+ "#pattern" : r"https://cdn.hentaihand.com/.*/images/37387/\d+.jpg$",
+ "#count" : 50,
+
+ "artists" : ["Takumi Na Muchi"],
+ "date" : "dt:2014-06-28 00:00:00",
+ "gallery_id" : 37387,
+ "lang" : "en",
+ "language" : "English",
+ "parodies" : ["Toaru Kagaku No Railgun"],
+ "relationships": list,
+ "tags" : list,
+ "title" : r"re:\(C75\) \[Takumi na Muchi\] Choudenji Hou ",
+ "title_alt" : r"re:\(C75\) \[たくみなむち\] 超電磁砲のあいしかた",
+ "type" : "Doujinshi",
+},
+
+{
+ "#url" : "https://hentaihand.com/en/artist/takumi-na-muchi",
+ "#category": ("", "hentaihand", "tag"),
+ "#class" : hentaihand.HentaihandTagExtractor,
+ "#pattern" : hentaihand.HentaihandGalleryExtractor.pattern,
+ "#count" : ">= 6",
+},
+
+{
+ "#url" : "https://hentaihand.com/en/tag/full-color",
+ "#category": ("", "hentaihand", "tag"),
+ "#class" : hentaihand.HentaihandTagExtractor,
+},
+
+{
+ "#url" : "https://hentaihand.com/fr/language/japanese",
+ "#category": ("", "hentaihand", "tag"),
+ "#class" : hentaihand.HentaihandTagExtractor,
+},
+
+{
+ "#url" : "https://hentaihand.com/zh/category/manga",
+ "#category": ("", "hentaihand", "tag"),
+ "#class" : hentaihand.HentaihandTagExtractor,
+},
+
+)
diff --git a/test/results/hentaihere.py b/test/results/hentaihere.py
new file mode 100644
index 00000000..abe52fe9
--- /dev/null
+++ b/test/results/hentaihere.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hentaihere
+
+
+__tests__ = (
+{
+ "#url" : "https://hentaihere.com/m/S13812/1/1/",
+ "#category": ("", "hentaihere", "chapter"),
+ "#class" : hentaihere.HentaihereChapterExtractor,
+ "#sha1_url" : "964b942cf492b3a129d2fe2608abfc475bc99e71",
+ "#sha1_metadata": "0207d20eea3a15d2a8d1496755bdfa49de7cfa9d",
+},
+
+{
+ "#url" : "https://hentaihere.com/m/S23048/1.5/1/",
+ "#category": ("", "hentaihere", "chapter"),
+ "#class" : hentaihere.HentaihereChapterExtractor,
+ "#pattern" : r"https://hentaicdn\.com/hentai/23048/1\.5/ccdn00\d+\.jpg",
+ "#count" : 32,
+
+ "author" : "Shinozuka Yuuji",
+ "chapter" : 1,
+ "chapter_id" : 80186,
+ "chapter_minor": ".5",
+ "count" : 32,
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "High School Slut's Love Consultation",
+ "manga_id" : 23048,
+ "page" : int,
+ "title" : "High School Slut's Love Consultation + Girlfriend [Full Color]",
+ "type" : "Original",
+},
+
+{
+ "#url" : "https://hentaihere.com/m/S13812",
+ "#category": ("", "hentaihere", "manga"),
+ "#class" : hentaihere.HentaihereMangaExtractor,
+ "#sha1_url" : "d1ba6e28bb2162e844f8559c2b2725ba0a093559",
+ "#sha1_metadata": "5c1b712258e78e120907121d3987c71f834d13e1",
+},
+
+{
+ "#url" : "https://hentaihere.com/m/S7608",
+ "#category": ("", "hentaihere", "manga"),
+ "#class" : hentaihere.HentaihereMangaExtractor,
+ "#sha1_url": "6c5239758dc93f6b1b4175922836c10391b174f7",
+
+ "chapter" : int,
+ "chapter_id" : int,
+ "chapter_minor": "",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Oshikake Riot",
+ "manga_id" : 7608,
+ "title" : r"re:Oshikake Riot( \d+)?",
+ "type" : "Original",
+},
+
+)
diff --git a/test/results/hiperdex.py b/test/results/hiperdex.py
new file mode 100644
index 00000000..33948f22
--- /dev/null
+++ b/test/results/hiperdex.py
@@ -0,0 +1,136 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hiperdex
+
+
+__tests__ = (
+{
+ "#url" : "https://hiperdex.com/manga/domestic-na-kanojo/154-5/",
+ "#category": ("", "hiperdex", "chapter"),
+ "#class" : hiperdex.HiperdexChapterExtractor,
+ "#pattern" : r"https://(1st)?hiperdex\d?.(com|net|info)/wp-content/uploads/WP-manga/data/manga_\w+/[0-9a-f]{32}/\d+\.webp",
+ "#count" : 9,
+
+ "artist" : "Sasuga Kei",
+ "author" : "Sasuga Kei",
+ "chapter" : 154,
+ "chapter_minor": ".5",
+ "description" : r"re:Natsuo Fujii is in love with his teacher, ",
+ "genre" : list,
+ "manga" : "Domestic na Kanojo",
+ "release" : 2014,
+ "score" : float,
+ "type" : "Manga",
+},
+
+{
+ "#url" : "https://1sthiperdex.com/manga/domestic-na-kanojo/154-5/",
+ "#category": ("", "hiperdex", "chapter"),
+ "#class" : hiperdex.HiperdexChapterExtractor,
+},
+
+{
+ "#url" : "https://hiperdex2.com/manga/domestic-na-kanojo/154-5/",
+ "#category": ("", "hiperdex", "chapter"),
+ "#class" : hiperdex.HiperdexChapterExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.net/manga/domestic-na-kanojo/154-5/",
+ "#category": ("", "hiperdex", "chapter"),
+ "#class" : hiperdex.HiperdexChapterExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.info/manga/domestic-na-kanojo/154-5/",
+ "#category": ("", "hiperdex", "chapter"),
+ "#class" : hiperdex.HiperdexChapterExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.com/manga/1603231576-youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+ "#pattern" : hiperdex.HiperdexChapterExtractor.pattern,
+ "#count" : 51,
+
+ "artist" : "Bolp",
+ "author" : "Abyo4",
+ "chapter" : int,
+ "chapter_minor": "",
+ "description" : r"re:I didn’t think much of the creepy girl in ",
+ "genre" : list,
+ "manga" : "You’re Not That Special!",
+ "release" : 2019,
+ "score" : float,
+ "status" : "Completed",
+ "type" : "Manhwa",
+},
+
+{
+ "#url" : "https://hiperdex.com/manga/youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+},
+
+{
+ "#url" : "https://1sthiperdex.com/manga/youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+},
+
+{
+ "#url" : "https://hiperdex2.com/manga/youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.net/manga/youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.info/manga/youre-not-that-special/",
+ "#category": ("", "hiperdex", "manga"),
+ "#class" : hiperdex.HiperdexMangaExtractor,
+},
+
+{
+ "#url" : "https://1sthiperdex.com/manga-artist/beck-ho-an/",
+ "#category": ("", "hiperdex", "artist"),
+ "#class" : hiperdex.HiperdexArtistExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.net/manga-artist/beck-ho-an/",
+ "#category": ("", "hiperdex", "artist"),
+ "#class" : hiperdex.HiperdexArtistExtractor,
+},
+
+{
+ "#url" : "https://hiperdex2.com/manga-artist/beck-ho-an/",
+ "#category": ("", "hiperdex", "artist"),
+ "#class" : hiperdex.HiperdexArtistExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.info/manga-artist/beck-ho-an/",
+ "#category": ("", "hiperdex", "artist"),
+ "#class" : hiperdex.HiperdexArtistExtractor,
+},
+
+{
+ "#url" : "https://hiperdex.com/manga-author/viagra/",
+ "#category": ("", "hiperdex", "artist"),
+ "#class" : hiperdex.HiperdexArtistExtractor,
+ "#pattern" : hiperdex.HiperdexMangaExtractor.pattern,
+ "#count" : ">= 6",
+},
+
+)
diff --git a/test/results/hitomi.py b/test/results/hitomi.py
new file mode 100644
index 00000000..10e94135
--- /dev/null
+++ b/test/results/hitomi.py
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hitomi
+
+
+__tests__ = (
+{
+ "#url" : "https://hitomi.la/galleries/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#pattern" : r"https://[a-c]a\.hitomi\.la/webp/\d+/\d+/[0-9a-f]{64}\.webp",
+ "#count" : 16,
+ "#sha1_metadata": "86af5371f38117a07407f11af689bdd460b09710",
+},
+
+{
+ "#url" : "https://hitomi.la/galleries/1401410.html",
+ "#comment" : "download test",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#range" : "1",
+ "#sha1_content": "d75d5a3d1302a48469016b20e53c26b714d17745",
+},
+
+{
+ "#url" : "https://hitomi.la/galleries/733697.html",
+ "#comment" : "Game CG with scenes (#321)",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#count" : 210,
+},
+
+{
+ "#url" : "https://hitomi.la/galleries/1045954.html",
+ "#comment" : "fallback for galleries only available through /reader/ URLs",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#count" : 1413,
+},
+
+{
+ "#url" : "https://hitomi.la/cg/scathacha-sama-okuchi-ecchi-1291900.html",
+ "#comment" : "gallery with 'broken' redirect",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#options" : {"format": "original"},
+ "#pattern" : r"https://[a-c]b\.hitomi\.la/images/\d+/\d+/[0-9a-f]{64}\.jpg",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://hitomi.la/cg/1615823.html",
+ "#comment" : "no tags",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+ "#options" : {"format": "avif"},
+ "#pattern" : r"https://[a-c]a\.hitomi\.la/avif/\d+/\d+/[0-9a-f]{64}\.avif",
+ "#count" : 22,
+},
+
+{
+ "#url" : "https://hitomi.la/manga/amazon-no-hiyaku-867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/manga/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/doujinshi/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/cg/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/gamecg/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/reader/867789.html",
+ "#category": ("", "hitomi", "gallery"),
+ "#class" : hitomi.HitomiGalleryExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/tag/screenshots-japanese.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+ "#pattern" : hitomi.HitomiGalleryExtractor.pattern,
+ "#count" : ">= 35",
+},
+
+{
+ "#url" : "https://hitomi.la/artist/a1-all-1.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/group/initial%2Dg-all-1.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/series/amnesia-all-1.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/type/doujinshi-all-1.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+},
+
+{
+ "#url" : "https://hitomi.la/character/a2-all-1.html",
+ "#category": ("", "hitomi", "tag"),
+ "#class" : hitomi.HitomiTagExtractor,
+},
+
+)
diff --git a/test/results/horne.py b/test/results/horne.py
new file mode 100644
index 00000000..eb7b0a79
--- /dev/null
+++ b/test/results/horne.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nijie
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://horne.red/members.php?id=58000",
+ "#category": ("Nijie", "horne", "user"),
+ "#class" : nijie.NijieUserExtractor,
+},
+
+{
+ "#url" : "https://horne.red/members_illust.php?id=58000",
+ "#category": ("Nijie", "horne", "illustration"),
+ "#class" : nijie.NijieIllustrationExtractor,
+ "#pattern" : r"https://pic\.nijie\.net/\d+/horne/\d+/\d+/\d+/illust/\d+_\d+_[0-9a-f]+_[0-9a-f]+\.png",
+ "#range" : "1-20",
+ "#count" : 20,
+
+ "artist_id" : 58000,
+ "artist_name": "のえるわ",
+ "date" : datetime.datetime,
+ "description": str,
+ "image_id" : int,
+ "num" : int,
+ "tags" : list,
+ "title" : str,
+ "url" : str,
+ "user_id" : 58000,
+ "user_name" : "のえるわ",
+},
+
+{
+ "#url" : "https://horne.red/members_dojin.php?id=58000",
+ "#category": ("Nijie", "horne", "doujin"),
+ "#class" : nijie.NijieDoujinExtractor,
+},
+
+{
+ "#url" : "https://horne.red/user_like_illust_view.php?id=58000",
+ "#category": ("Nijie", "horne", "favorite"),
+ "#class" : nijie.NijieFavoriteExtractor,
+ "#range" : "1-5",
+ "#count" : 5,
+
+ "user_id" : 58000,
+ "user_name": "のえるわ",
+},
+
+{
+ "#url" : "https://horne.red/history_nuita.php?id=58000",
+ "#category": ("Nijie", "horne", "nuita"),
+ "#class" : nijie.NijieNuitaExtractor,
+},
+
+{
+ "#url" : "https://horne.red/like_user_view.php",
+ "#category": ("Nijie", "horne", "feed"),
+ "#class" : nijie.NijieFeedExtractor,
+},
+
+{
+ "#url" : "https://horne.red/like_my.php",
+ "#category": ("Nijie", "horne", "followed"),
+ "#class" : nijie.NijiefollowedExtractor,
+},
+
+{
+ "#url" : "https://horne.red/view.php?id=8716",
+ "#category": ("Nijie", "horne", "image"),
+ "#class" : nijie.NijieImageExtractor,
+ "#count" : 4,
+
+ "artist_id" : 58000,
+ "artist_name": "のえるわ",
+ "date" : "dt:2018-02-04 14:47:24",
+ "description": "ノエル「そんなことしなくても、言ってくれたら咥えるのに・・・♡」",
+ "image_id" : 8716,
+ "tags" : [
+ "男の娘",
+ "フェラ",
+ "オリキャラ",
+ "うちのこ",
+ ],
+ "title" : "ノエル「いまどきそんな、恵方巻ネタなんてやらなくても・・・」",
+ "user_id" : 58000,
+ "user_name" : "のえるわ",
+},
+
+)
diff --git a/test/results/hotleak.py b/test/results/hotleak.py
new file mode 100644
index 00000000..4e577d11
--- /dev/null
+++ b/test/results/hotleak.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import hotleak
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://hotleak.vip/kaiyakawaii/photo/1617145",
+ "#category": ("", "hotleak", "post"),
+ "#class" : hotleak.HotleakPostExtractor,
+ "#pattern" : r"https://hotleak\.vip/storage/images/3625/1617145/fefdd5988dfcf6b98cc9e11616018868\.jpg",
+
+ "id" : 1617145,
+ "creator" : "kaiyakawaii",
+ "type" : "photo",
+ "filename" : "fefdd5988dfcf6b98cc9e11616018868",
+ "extension": "jpg",
+},
+
+{
+ "#url" : "https://hotleak.vip/lilmochidoll/video/1625538",
+ "#category": ("", "hotleak", "post"),
+ "#class" : hotleak.HotleakPostExtractor,
+ "#pattern" : r"ytdl:https://cdn8-leak\.camhdxx\.com/1661/1625538/index\.m3u8",
+
+ "id" : 1625538,
+ "creator" : "lilmochidoll",
+ "type" : "video",
+ "filename" : "index",
+ "extension": "mp4",
+},
+
+{
+ "#url" : "https://hotleak.vip/kaiyakawaii",
+ "#category": ("", "hotleak", "creator"),
+ "#class" : hotleak.HotleakCreatorExtractor,
+ "#range" : "1-200",
+ "#count" : 200,
+},
+
+{
+ "#url" : "https://hotleak.vip/stellaviolet",
+ "#category": ("", "hotleak", "creator"),
+ "#class" : hotleak.HotleakCreatorExtractor,
+ "#count" : "> 600",
+},
+
+{
+ "#url" : "https://hotleak.vip/doesnotexist",
+ "#category": ("", "hotleak", "creator"),
+ "#class" : hotleak.HotleakCreatorExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://hotleak.vip/photos",
+ "#category": ("", "hotleak", "category"),
+ "#class" : hotleak.HotleakCategoryExtractor,
+ "#pattern" : hotleak.HotleakPostExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://hotleak.vip/videos",
+ "#category": ("", "hotleak", "category"),
+ "#class" : hotleak.HotleakCategoryExtractor,
+},
+
+{
+ "#url" : "https://hotleak.vip/creators",
+ "#category": ("", "hotleak", "category"),
+ "#class" : hotleak.HotleakCategoryExtractor,
+ "#pattern" : hotleak.HotleakCreatorExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://hotleak.vip/hot",
+ "#category": ("", "hotleak", "category"),
+ "#class" : hotleak.HotleakCategoryExtractor,
+},
+
+{
+ "#url" : "https://hotleak.vip/search?search=gallery-dl",
+ "#category": ("", "hotleak", "search"),
+ "#class" : hotleak.HotleakSearchExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://hotleak.vip/search?search=hannah",
+ "#category": ("", "hotleak", "search"),
+ "#class" : hotleak.HotleakSearchExtractor,
+ "#count" : "> 30",
+},
+
+)
diff --git a/test/results/hypnohub.py b/test/results/hypnohub.py
new file mode 100644
index 00000000..d979b620
--- /dev/null
+++ b/test/results/hypnohub.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v02
+
+
+__tests__ = (
+{
+ "#url" : "https://hypnohub.net/index.php?page=post&s=list&tags=gonoike_biwa",
+ "#category": ("gelbooru_v02", "hypnohub", "tag"),
+ "#class" : gelbooru_v02.GelbooruV02TagExtractor,
+ "#sha1_url": "fe662b86d38c331fcac9c62af100167d404937dc",
+},
+
+{
+ "#url" : "https://hypnohub.net/index.php?page=pool&s=show&id=61",
+ "#category": ("gelbooru_v02", "hypnohub", "pool"),
+ "#class" : gelbooru_v02.GelbooruV02PoolExtractor,
+ "#count" : 3,
+ "#sha1_url": "d314826280073441a2da609f70ee814d1f4b9407",
+},
+
+{
+ "#url" : "https://hypnohub.net/index.php?page=favorites&s=view&id=43546",
+ "#category": ("gelbooru_v02", "hypnohub", "favorite"),
+ "#class" : gelbooru_v02.GelbooruV02FavoriteExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://hypnohub.net/index.php?page=post&s=view&id=1439",
+ "#category": ("gelbooru_v02", "hypnohub", "post"),
+ "#class" : gelbooru_v02.GelbooruV02PostExtractor,
+ "#options" : {
+ "tags" : True,
+ "notes": True,
+ },
+ "#pattern" : r"https://hypnohub\.net/images/90/24/90245c3c5250c2a8173255d3923a010b\.jpg",
+ "#sha1_content": "5987c5d2354f22e5fa9b7ee7ce4a6f7beb8b2b71",
+
+ "tags_artist" : "brokenteapot",
+ "tags_character": "hsien-ko",
+ "tags_copyright": "capcom darkstalkers",
+ "tags_general" : str,
+ "tags_metadata" : "dialogue text translated",
+ "notes" : [
+ {
+ "body" : "Master Master Master Master Master Master",
+ "height": 83,
+ "id" : 10577,
+ "width" : 129,
+ "x" : 259,
+ "y" : 20,
+ },
+ {
+ "body" : "Response Response Response Response Response Response",
+ "height": 86,
+ "id" : 10578,
+ "width" : 125,
+ "x" : 126,
+ "y" : 20,
+ },
+ {
+ "body" : "Obedience Obedience Obedience Obedience Obedience Obedience",
+ "height": 80,
+ "id" : 10579,
+ "width" : 98,
+ "x" : 20,
+ "y" : 20,
+ },
+ ],
+},
+
+)
diff --git a/test/results/idolcomplex.py b/test/results/idolcomplex.py
new file mode 100644
index 00000000..6aced68c
--- /dev/null
+++ b/test/results/idolcomplex.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import idolcomplex
+
+
+__tests__ = (
+{
+ "#url" : "https://idol.sankakucomplex.com/?tags=lyumos",
+ "#category": ("booru", "idolcomplex", "tag"),
+ "#class" : idolcomplex.IdolcomplexTagExtractor,
+ "#pattern" : r"https://is\.sankakucomplex\.com/data/[^/]{2}/[^/]{2}/[^/]{32}\.\w+\?e=\d+&m=[^]+",
+ "#range" : "18-22",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://idol.sankakucomplex.com/?tags=order:favcount",
+ "#category": ("booru", "idolcomplex", "tag"),
+ "#class" : idolcomplex.IdolcomplexTagExtractor,
+ "#range" : "18-22",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://idol.sankakucomplex.com/?tags=lyumos+wreath&page=3&next=694215",
+ "#category": ("booru", "idolcomplex", "tag"),
+ "#class" : idolcomplex.IdolcomplexTagExtractor,
+},
+
+{
+ "#url" : "https://idol.sankakucomplex.com/pool/show/145",
+ "#category": ("booru", "idolcomplex", "pool"),
+ "#class" : idolcomplex.IdolcomplexPoolExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://idol.sankakucomplex.com/post/show/694215",
+ "#category": ("booru", "idolcomplex", "post"),
+ "#class" : idolcomplex.IdolcomplexPostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_content": "694ec2491240787d75bf5d0c75d0082b53a85afd",
+
+ "tags_character": "shani_(the_witcher)",
+ "tags_copyright": "the_witcher",
+ "tags_idol" : str,
+ "tags_medium" : str,
+ "tags_general" : str,
+},
+
+)
diff --git a/test/results/illusioncardsbooru.py b/test/results/illusioncardsbooru.py
new file mode 100644
index 00000000..ba079364
--- /dev/null
+++ b/test/results/illusioncardsbooru.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v01
+
+
+__tests__ = (
+{
+ "#url" : "https://illusioncards.booru.org/index.php?page=post&s=list&tags=koikatsu",
+ "#category": ("gelbooru_v01", "illusioncardsbooru", "tag"),
+ "#class" : gelbooru_v01.GelbooruV01TagExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://illusioncards.booru.org/index.php?page=favorites&s=view&id=84887",
+ "#category": ("gelbooru_v01", "illusioncardsbooru", "favorite"),
+ "#class" : gelbooru_v01.GelbooruV01FavoriteExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://illusioncards.booru.org/index.php?page=post&s=view&id=82746",
+ "#category": ("gelbooru_v01", "illusioncardsbooru", "post"),
+ "#class" : gelbooru_v01.GelbooruV01PostExtractor,
+ "#sha1_url" : "3f9cd2fadf78869b90bc5422f27b48f1af0e0909",
+ "#sha1_content": "159e60b92d05597bd1bb63510c2c3e4a4bada1dc",
+},
+
+)
diff --git a/test/results/imagebam.py b/test/results/imagebam.py
new file mode 100644
index 00000000..759e2dc4
--- /dev/null
+++ b/test/results/imagebam.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagebam
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.imagebam.com/gallery/adz2y0f9574bjpmonaismyrhtjgvey4o",
+ "#category": ("", "imagebam", "gallery"),
+ "#class" : imagebam.ImagebamGalleryExtractor,
+ "#sha1_url" : "76d976788ae2757ac81694736b07b72356f5c4c8",
+ "#sha1_metadata": "b048478b1bbba3072a7fa9fcc40630b3efad1f6c",
+ "#sha1_content" : "596e6bfa157f2c7169805d50075c2986549973a8",
+},
+
+{
+ "#url" : "http://www.imagebam.com/gallery/op9dwcklwdrrguibnkoe7jxgvig30o5p",
+ "#category": ("", "imagebam", "gallery"),
+ "#class" : imagebam.ImagebamGalleryExtractor,
+ "#count" : 107,
+ "#sha1_url": "32ae6fe5dc3e4ca73ff6252e522d16473595d1d1",
+},
+
+{
+ "#url" : "http://www.imagebam.com/gallery/gsl8teckymt4vbvx1stjkyk37j70va2c",
+ "#category": ("", "imagebam", "gallery"),
+ "#class" : imagebam.ImagebamGalleryExtractor,
+ "#exception": exception.HttpError,
+},
+
+{
+ "#url" : "https://www.imagebam.com/view/GA3MT1",
+ "#comment" : "/view/ path (#2378)",
+ "#category": ("", "imagebam", "gallery"),
+ "#class" : imagebam.ImagebamGalleryExtractor,
+ "#sha1_url" : "35018ce1e00a2d2825a33d3cd37857edaf804919",
+ "#sha1_metadata": "3a9f98178f73694c527890c0d7ca9a92b46987ba",
+},
+
+{
+ "#url" : "https://www.imagebam.com/image/94d56c502511890",
+ "#category": ("", "imagebam", "image"),
+ "#class" : imagebam.ImagebamImageExtractor,
+ "#sha1_url" : "5e9ba3b1451f8ded0ae3a1b84402888893915d4a",
+ "#sha1_metadata": "2a4380d4b57554ff793898c2d6ec60987c86d1a1",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+{
+ "#url" : "http://images3.imagebam.com/1d/8c/44/94d56c502511890.png",
+ "#category": ("", "imagebam", "image"),
+ "#class" : imagebam.ImagebamImageExtractor,
+},
+
+{
+ "#url" : "https://www.imagebam.com/image/0850951366904951",
+ "#comment" : "NSFW (#1534)",
+ "#category": ("", "imagebam", "image"),
+ "#class" : imagebam.ImagebamImageExtractor,
+ "#sha1_url": "d37297b17ed1615b4311c8ed511e50ce46e4c748",
+},
+
+{
+ "#url" : "https://www.imagebam.com/view/ME8JOQP",
+ "#comment" : "/view/ path (#2378)",
+ "#category": ("", "imagebam", "image"),
+ "#class" : imagebam.ImagebamImageExtractor,
+ "#sha1_url" : "4dca72bbe61a0360185cf4ab2bed8265b49565b8",
+ "#sha1_metadata": "15a494c02fd30846b41b42a26117aedde30e4ceb",
+ "#sha1_content" : "f81008666b17a42d8834c4749b910e1dc10a6e83",
+},
+
+)
diff --git a/test/results/imagechest.py b/test/results/imagechest.py
new file mode 100644
index 00000000..4b6a2ba3
--- /dev/null
+++ b/test/results/imagechest.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagechest
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://imgchest.com/p/3na7kr3by8d",
+ "#category": ("", "imagechest", "gallery"),
+ "#class" : imagechest.ImagechestGalleryExtractor,
+ "#pattern" : r"https://cdn\.imgchest\.com/files/\w+\.(jpg|png)",
+ "#count" : 3,
+ "#sha1_url" : "7328ca4ec2459378d725e3be19f661d2b045feda",
+ "#sha1_content": "076959e65be30249a2c651fbe6090dc30ba85193",
+
+ "count" : 3,
+ "gallery_id": "3na7kr3by8d",
+ "num" : int,
+ "title" : "Wizardry - Video Game From The Mid 80's",
+},
+
+{
+ "#url" : "https://imgchest.com/p/9p4n3q2z7nq",
+ "#comment" : "'Load More Files' button (#4028)",
+ "#category": ("", "imagechest", "gallery"),
+ "#class" : imagechest.ImagechestGalleryExtractor,
+ "#pattern" : r"https://cdn\.imgchest\.com/files/\w+\.(jpg|png)",
+ "#count" : 52,
+ "#sha1_url": "f5674e8ba79d336193c9f698708d9dcc10e78cc7",
+},
+
+{
+ "#url" : "https://imgchest.com/p/xxxxxxxxxxx",
+ "#category": ("", "imagechest", "gallery"),
+ "#class" : imagechest.ImagechestGalleryExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+)
diff --git a/test/results/imagefap.py b/test/results/imagefap.py
new file mode 100644
index 00000000..99a22166
--- /dev/null
+++ b/test/results/imagefap.py
@@ -0,0 +1,191 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagefap
+
+
+__tests__ = (
+{
+ "#url" : "https://www.imagefap.com/gallery/7102714",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+ "#pattern" : r"https://cdnh?\.imagefap\.com/images/full/\d+/\d+/\d+\.jpg",
+ "#sha1_metadata": "bdcb75b1e4b9dddc718f3d66e1a58afa9d81a38b",
+ "#sha1_content" : "694a0a57385980a6f90fbc296cadcd6c11ba2dab",
+},
+
+{
+ "#url" : "https://www.imagefap.com/gallery/7876223",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+ "#pattern" : r"https://cdnh?\.imagefap\.com/images/full/\d+/\d+/\d+\.jpg",
+ "#count" : 44,
+
+ "categories" : [
+ "Asses",
+ "Softcore",
+ "Pornstars",
+ ],
+ "count" : 44,
+ "description": "",
+ "gallery_id" : 7876223,
+ "image_id" : int,
+ "num" : int,
+ "tags" : [
+ "big ass",
+ "panties",
+ "horny",
+ "pussy",
+ "exposed",
+ "outdoor",
+ ],
+ "title" : "Kelsi Monroe in lingerie",
+ "uploader" : "BdRachel",
+},
+
+{
+ "#url" : "https://www.imagefap.com/gallery/6180555",
+ "#comment" : "description (#3905)",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+ "#range" : "1",
+
+ "categories" : [
+ "Amateur",
+ "Softcore",
+ "Homemade",
+ ],
+ "count" : 36,
+ "description": "Nude and dressed sluts showing off the goods",
+ "gallery_id" : 6180555,
+ "image_id" : int,
+ "num" : int,
+ "tags" : [],
+ "title" : "Dressed or Undressed MG*",
+ "uploader" : "splitopen",
+},
+
+{
+ "#url" : "https://www.imagefap.com/pictures/7102714",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.imagefap.com/gallery.php?gid=7102714",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+},
+
+{
+ "#url" : "https://beta.imagefap.com/gallery.php?gid=7102714",
+ "#category": ("", "imagefap", "gallery"),
+ "#class" : imagefap.ImagefapGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.imagefap.com/photo/1962981893",
+ "#category": ("", "imagefap", "image"),
+ "#class" : imagefap.ImagefapImageExtractor,
+ "#pattern" : r"https://cdnh?\.imagefap\.com/images/full/65/196/1962981893\.jpg",
+
+ "date" : "21/08/2014",
+ "gallery_id": 7876223,
+ "height" : 1600,
+ "image_id" : 1962981893,
+ "title" : "Kelsi Monroe in lingerie",
+ "uploader" : "BdRachel",
+ "width" : 1066,
+},
+
+{
+ "#url" : "https://beta.imagefap.com/photo/1962981893",
+ "#category": ("", "imagefap", "image"),
+ "#class" : imagefap.ImagefapImageExtractor,
+},
+
+{
+ "#url" : "https://www.imagefap.com/organizer/409758",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#pattern" : r"https://www\.imagefap\.com/gallery/7876223",
+ "#count" : 1,
+ "#sha1_url": "37822523e6e4a56feb9dea35653760c86b44ff89",
+},
+
+{
+ "#url" : "https://www.imagefap.com/usergallery.php?userid=1981976&folderid=409758",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#sha1_url": "37822523e6e4a56feb9dea35653760c86b44ff89",
+},
+
+{
+ "#url" : "https://www.imagefap.com/usergallery.php?user=BdRachel&folderid=409758",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#sha1_url": "37822523e6e4a56feb9dea35653760c86b44ff89",
+},
+
+{
+ "#url" : "https://www.imagefap.com/profile/BdRachel/galleries?folderid=-1",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#pattern" : imagefap.ImagefapGalleryExtractor.pattern,
+ "#range" : "1-40",
+},
+
+{
+ "#url" : "https://www.imagefap.com/usergallery.php?userid=1981976&folderid=-1",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#pattern" : imagefap.ImagefapGalleryExtractor.pattern,
+ "#range" : "1-40",
+},
+
+{
+ "#url" : "https://www.imagefap.com/usergallery.php?user=BdRachel&folderid=-1",
+ "#category": ("", "imagefap", "folder"),
+ "#class" : imagefap.ImagefapFolderExtractor,
+ "#pattern" : imagefap.ImagefapGalleryExtractor.pattern,
+ "#range" : "1-40",
+},
+
+{
+ "#url" : "https://www.imagefap.com/profile/BdRachel",
+ "#category": ("", "imagefap", "user"),
+ "#class" : imagefap.ImagefapUserExtractor,
+ "#pattern" : imagefap.ImagefapFolderExtractor.pattern,
+ "#count" : ">= 18",
+},
+
+{
+ "#url" : "https://www.imagefap.com/usergallery.php?userid=1862791",
+ "#category": ("", "imagefap", "user"),
+ "#class" : imagefap.ImagefapUserExtractor,
+ "#pattern" : r"https://www\.imagefap\.com/profile/LucyRae/galleries\?folderid=-1",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.imagefap.com/profile/BdRachel/galleries",
+ "#category": ("", "imagefap", "user"),
+ "#class" : imagefap.ImagefapUserExtractor,
+},
+
+{
+ "#url" : "https://www.imagefap.com/profile.php?user=BdRachel",
+ "#category": ("", "imagefap", "user"),
+ "#class" : imagefap.ImagefapUserExtractor,
+},
+
+{
+ "#url" : "https://beta.imagefap.com/profile.php?user=BdRachel",
+ "#category": ("", "imagefap", "user"),
+ "#class" : imagefap.ImagefapUserExtractor,
+},
+
+)
diff --git a/test/results/imagetwist.py b/test/results/imagetwist.py
new file mode 100644
index 00000000..4606a773
--- /dev/null
+++ b/test/results/imagetwist.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://imagetwist.com/f1i2s4vhvbrq/test.png",
+ "#category": ("imagehost", "imagetwist", "image"),
+ "#class" : imagehosts.ImagetwistImageExtractor,
+ "#sha1_url" : "8d5e168c0bee30211f821c6f3b2116e419d42671",
+ "#sha1_metadata": "d1060a4c2e3b73b83044e20681712c0ffdd6cfef",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+{
+ "#url" : "https://www.imagetwist.com/f1i2s4vhvbrq/test.png",
+ "#category": ("imagehost", "imagetwist", "image"),
+ "#class" : imagehosts.ImagetwistImageExtractor,
+},
+
+{
+ "#url" : "https://phun.imagetwist.com/f1i2s4vhvbrq/test.png",
+ "#category": ("imagehost", "imagetwist", "image"),
+ "#class" : imagehosts.ImagetwistImageExtractor,
+},
+
+{
+ "#url" : "https://imagehaha.com/f1i2s4vhvbrq/test.png",
+ "#category": ("imagehost", "imagetwist", "image"),
+ "#class" : imagehosts.ImagetwistImageExtractor,
+},
+
+{
+ "#url" : "https://www.imagehaha.com/f1i2s4vhvbrq/test.png",
+ "#category": ("imagehost", "imagetwist", "image"),
+ "#class" : imagehosts.ImagetwistImageExtractor,
+},
+
+)
diff --git a/test/results/imagevenue.py b/test/results/imagevenue.py
new file mode 100644
index 00000000..f57b1c94
--- /dev/null
+++ b/test/results/imagevenue.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://www.imagevenue.com/ME13LS07",
+ "#category": ("imagehost", "imagevenue", "image"),
+ "#class" : imagehosts.ImagevenueImageExtractor,
+ "#pattern" : r"https://cdn-images\.imagevenue\.com/10/ac/05/ME13LS07_o\.png",
+ "#sha1_metadata": "ae15d6e3b2095f019eee84cd896700cd34b09c36",
+ "#sha1_content" : "cfaa8def53ed1a575e0c665c9d6d8cf2aac7a0ee",
+},
+
+{
+ "#url" : "https://www.imagevenue.com/view/o?i=92518_13732377annakarina424200712535AM_122_486lo.jpg&h=img150&l=loc486",
+ "#category": ("imagehost", "imagevenue", "image"),
+ "#class" : imagehosts.ImagevenueImageExtractor,
+ "#sha1_url": "8bf0254e29250d8f5026c0105bbdda3ee3d84980",
+},
+
+{
+ "#url" : "http://img28116.imagevenue.com/img.php?image=th_52709_test_122_64lo.jpg",
+ "#category": ("imagehost", "imagevenue", "image"),
+ "#class" : imagehosts.ImagevenueImageExtractor,
+ "#sha1_url": "f98e3091df7f48a05fb60fbd86f789fc5ec56331",
+},
+
+)
diff --git a/test/results/imgbb.py b/test/results/imgbb.py
new file mode 100644
index 00000000..adc1dcf9
--- /dev/null
+++ b/test/results/imgbb.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imgbb
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://ibb.co/album/i5PggF",
+ "#category": ("", "imgbb", "album"),
+ "#class" : imgbb.ImgbbAlbumExtractor,
+ "#range" : "1-80",
+ "#sha1_url" : "70afec9fcc3a6de62a6b644b487d892d8d47cf1a",
+ "#sha1_metadata": "569e1d88ebdd27655387559cdf1cd526a3e1ab69",
+},
+
+{
+ "#url" : "https://ibb.co/album/i5PggF?sort=title_asc",
+ "#category": ("", "imgbb", "album"),
+ "#class" : imgbb.ImgbbAlbumExtractor,
+ "#range" : "1-80",
+ "#sha1_url" : "afdf5fc95d8e09d77e8f44312f3e9b843987bb5a",
+ "#sha1_metadata": "f090e14d0e5f7868595082b2c95da1309c84872d",
+},
+
+{
+ "#url" : "https://ibb.co/album/kYKpwF",
+ "#comment" : "no user data (#471)",
+ "#category": ("", "imgbb", "album"),
+ "#class" : imgbb.ImgbbAlbumExtractor,
+ "#sha1_url": "ac0abcfcb89f4df6adc2f7e4ff872f3b03ef1bc7",
+
+ "user": "",
+},
+
+{
+ "#url" : "https://ibb.co/album/hqgWrF",
+ "#comment" : "private",
+ "#category": ("", "imgbb", "album"),
+ "#class" : imgbb.ImgbbAlbumExtractor,
+ "#exception": exception.HttpError,
+},
+
+{
+ "#url" : "https://folkie.imgbb.com",
+ "#category": ("", "imgbb", "user"),
+ "#class" : imgbb.ImgbbUserExtractor,
+ "#pattern" : r"https?://i\.ibb\.co/\w+/[^/?#]+",
+ "#range" : "1-80",
+},
+
+{
+ "#url" : "https://ibb.co/fUqh5b",
+ "#category": ("", "imgbb", "image"),
+ "#class" : imgbb.ImgbbImageExtractor,
+ "#pattern" : r"https://i\.ibb\.co/g3kvx80/Arundel-Ireeman-5\.jpg",
+ "#sha1_content": "c5a0965178a8b357acd8aa39660092918c63795e",
+
+ "id" : "fUqh5b",
+ "title" : "Arundel Ireeman 5",
+ "url" : "https://i.ibb.co/g3kvx80/Arundel-Ireeman-5.jpg",
+ "width" : 960,
+ "height" : 719,
+ "user" : "folkie",
+ "extension": "jpg",
+},
+
+)
diff --git a/test/results/imgbox.py b/test/results/imgbox.py
new file mode 100644
index 00000000..ed0be593
--- /dev/null
+++ b/test/results/imgbox.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imgbox
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://imgbox.com/g/JaX5V5HX7g",
+ "#category": ("", "imgbox", "gallery"),
+ "#class" : imgbox.ImgboxGalleryExtractor,
+ "#sha1_url" : "da4f15b161461119ee78841d4b8e8d054d95f906",
+ "#sha1_metadata": "4b1e62820ac2c6205b7ad0b6322cc8e00dbe1b0c",
+ "#sha1_content" : "d20307dc8511ac24d688859c55abf2e2cc2dd3cc",
+},
+
+{
+ "#url" : "https://imgbox.com/g/cUGEkRbdZZ",
+ "#category": ("", "imgbox", "gallery"),
+ "#class" : imgbox.ImgboxGalleryExtractor,
+ "#sha1_url" : "76506a3aab175c456910851f66227e90484ca9f7",
+ "#sha1_metadata": "fb0427b87983197849fb2887905e758f3e50cb6e",
+},
+
+{
+ "#url" : "https://imgbox.com/g/JaX5V5HX7h",
+ "#category": ("", "imgbox", "gallery"),
+ "#class" : imgbox.ImgboxGalleryExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://imgbox.com/qHhw7lpG",
+ "#category": ("", "imgbox", "image"),
+ "#class" : imgbox.ImgboxImageExtractor,
+ "#sha1_url" : "ee9cdea6c48ad0161c1b5f81f6b0c9110997038c",
+ "#sha1_metadata": "dfc72310026b45f3feb4f9cada20c79b2575e1af",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+{
+ "#url" : "https://imgbox.com/qHhw7lpH",
+ "#category": ("", "imgbox", "image"),
+ "#class" : imgbox.ImgboxImageExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+)
diff --git a/test/results/imgclick.py b/test/results/imgclick.py
new file mode 100644
index 00000000..983f21f4
--- /dev/null
+++ b/test/results/imgclick.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "http://imgclick.net/4tbrre1oxew9/test-_-_.png.html",
+ "#category": ("imagehost", "imgclick", "image"),
+ "#class" : imagehosts.ImgclickImageExtractor,
+ "#sha1_url" : "140dcb250a325f2d26b2d918c18b8ac6a2a0f6ab",
+ "#sha1_metadata": "6895256143eab955622fc149aa367777a8815ba3",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+)
diff --git a/test/results/imgspice.py b/test/results/imgspice.py
new file mode 100644
index 00000000..b2691b6a
--- /dev/null
+++ b/test/results/imgspice.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://imgspice.com/nwfwtpyog50y/test.png.html",
+ "#category": ("imagehost", "imgspice", "image"),
+ "#class" : imagehosts.ImgspiceImageExtractor,
+ "#sha1_url" : "b8c30a8f51ee1012959a4cfd46197fabf14de984",
+ "#sha1_metadata": "100e310a19a2fa22d87e1bbc427ecb9f6501e0c0",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+)
diff --git a/test/results/imgth.py b/test/results/imgth.py
new file mode 100644
index 00000000..333e1352
--- /dev/null
+++ b/test/results/imgth.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imgth
+
+
+__tests__ = (
+{
+ "#url" : "https://imgth.com/gallery/37/wallpaper-anime",
+ "#category": ("", "imgth", "gallery"),
+ "#class" : imgth.ImgthGalleryExtractor,
+ "#pattern" : r"https://imgth\.com/images/2009/11/25/wallpaper-anime_\w+\.jpg",
+ "#sha1_url": "4ae1d281ca2b48952cf5cca57e9914402ad72748",
+
+ "count" : 12,
+ "date" : "dt:2009-11-25 18:21:00",
+ "extension" : "jpg",
+ "filename" : r"re:wallpaper-anime_\w+",
+ "gallery_id": 37,
+ "num" : int,
+ "title" : "Wallpaper anime",
+ "user" : "celebrities",
+},
+
+{
+ "#url" : "https://www.imgth.com/gallery/37/wallpaper-anime",
+ "#category": ("", "imgth", "gallery"),
+ "#class" : imgth.ImgthGalleryExtractor,
+},
+
+)
diff --git a/test/results/imgur.py b/test/results/imgur.py
new file mode 100644
index 00000000..4fedc600
--- /dev/null
+++ b/test/results/imgur.py
@@ -0,0 +1,367 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imgur
+from gallery_dl import exception
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://imgur.com/21yMxCS",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+ "#sha1_url" : "6f2dcfb86815bdd72808c313e5f715610bc7b9b2",
+ "#sha1_content": "0c8768055e4e20e7c7259608b67799171b691140",
+
+ "account_id" : 0,
+ "comment_count" : int,
+ "cover_id" : "21yMxCS",
+ "date" : "dt:2016-11-10 14:24:35",
+ "description" : "",
+ "downvote_count": int,
+ "duration" : 0,
+ "ext" : "png",
+ "favorite" : False,
+ "favorite_count": 0,
+ "has_sound" : False,
+ "height" : 32,
+ "id" : "21yMxCS",
+ "image_count" : 1,
+ "in_most_viral" : False,
+ "is_ad" : False,
+ "is_album" : False,
+ "is_animated" : False,
+ "is_looping" : False,
+ "is_mature" : False,
+ "is_pending" : False,
+ "mime_type" : "image/png",
+ "name" : "test-テスト",
+ "point_count" : int,
+ "privacy" : "",
+ "score" : int,
+ "size" : 182,
+ "title" : "Test",
+ "upvote_count" : int,
+ "url" : "https://i.imgur.com/21yMxCS.png",
+ "view_count" : int,
+ "width" : 64,
+},
+
+{
+ "#url" : "http://imgur.com/0gybAXR",
+ "#comment" : "gifv/mp4 video",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+ "#sha1_url" : "a2220eb265a55b0c95e0d3d721ec7665460e3fd7",
+ "#sha1_content": "a3c080e43f58f55243ab830569ba02309d59abfc",
+},
+
+{
+ "#url" : "https://imgur.com/XFfsmuC",
+ "#comment" : "missing title in API response (#467)",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+
+ "title": "Tears are a natural response to irritants",
+},
+
+{
+ "#url" : "https://imgur.com/1Nily2P",
+ "#comment" : "animated png",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+ "#pattern" : "https://i.imgur.com/1Nily2P.png",
+},
+
+{
+ "#url" : "https://imgur.com/zzzzzzz",
+ "#comment" : "not found",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+ "#exception": exception.HttpError,
+},
+
+{
+ "#url" : "https://m.imgur.com/r/Celebs/iHJ7tsM",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://www.imgur.com/21yMxCS",
+ "#comment" : "www",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://m.imgur.com/21yMxCS",
+ "#comment" : "mobile",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/zxaY6",
+ "#comment" : "5 character key",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://imgur.io/zxaY6",
+ "#comment" : ".io",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://i.imgur.com/21yMxCS.png",
+ "#comment" : "direct link",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://i.imgur.io/21yMxCS.png",
+ "#comment" : "direct link .io",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://i.imgur.com/21yMxCSh.png",
+ "#comment" : "direct link thumbnail",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://i.imgur.com/zxaY6.gif",
+ "#comment" : "direct link (short)",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://i.imgur.com/zxaY6s.gif",
+ "#comment" : "direct link (short; thumb)",
+ "#category": ("", "imgur", "image"),
+ "#class" : imgur.ImgurImageExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/a/TcBmP",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+ "#sha1_url": "ce3552f550a5b5316bd9c7ae02e21e39f30c0563",
+
+ "album" : {
+ "account_id" : 0,
+ "comment_count" : int,
+ "cover_id" : "693j2Kr",
+ "date" : "dt:2015-10-09 10:37:50",
+ "description" : "",
+ "downvote_count": 0,
+ "favorite" : False,
+ "favorite_count": 0,
+ "id" : "TcBmP",
+ "image_count" : 19,
+ "in_most_viral" : False,
+ "is_ad" : False,
+ "is_album" : True,
+ "is_mature" : False,
+ "is_pending" : False,
+ "privacy" : "private",
+ "score" : int,
+ "title" : "138",
+ "upvote_count" : int,
+ "url" : "https://imgur.com/a/TcBmP",
+ "view_count" : int,
+ "virality" : int,
+ },
+ "account_id" : 0,
+ "count" : 19,
+ "date" : datetime.datetime,
+ "description": "",
+ "ext" : "jpg",
+ "has_sound" : False,
+ "height" : int,
+ "id" : str,
+ "is_animated": False,
+ "is_looping" : False,
+ "mime_type" : "image/jpeg",
+ "name" : str,
+ "num" : int,
+ "size" : int,
+ "title" : str,
+ "type" : "image",
+ "updated_at" : None,
+ "url" : str,
+ "width" : int,
+},
+
+{
+ "#url" : "https://imgur.com/a/eD9CT",
+ "#comment" : "large album",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+ "#sha1_url": "de748c181a04d18bef1de9d4f4866ef0a06d632b",
+},
+
+{
+ "#url" : "https://imgur.com/a/RhJXhVT/all",
+ "#comment" : "7 character album hash",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+ "#sha1_url": "695ef0c950023362a0163ee5041796300db76674",
+},
+
+{
+ "#url" : "https://imgur.com/a/TcBmQ",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+ "#exception": exception.HttpError,
+},
+
+{
+ "#url" : "https://imgur.com/a/pjOnJA0",
+ "#comment" : "empty, no 'media' (#2557)",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.imgur.com/a/TcBmP",
+ "#comment" : "www",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+},
+
+{
+ "#url" : "https://imgur.io/a/TcBmP",
+ "#comment" : ".io",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+},
+
+{
+ "#url" : "https://m.imgur.com/a/TcBmP",
+ "#comment" : "mobile",
+ "#category": ("", "imgur", "album"),
+ "#class" : imgur.ImgurAlbumExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/gallery/zf2fIms",
+ "#comment" : "non-album gallery (#380)",
+ "#category": ("", "imgur", "gallery"),
+ "#class" : imgur.ImgurGalleryExtractor,
+ "#pattern" : "https://imgur.com/zf2fIms",
+},
+
+{
+ "#url" : "https://imgur.com/gallery/eD9CT",
+ "#category": ("", "imgur", "gallery"),
+ "#class" : imgur.ImgurGalleryExtractor,
+ "#pattern" : "https://imgur.com/a/eD9CT",
+},
+
+{
+ "#url" : "https://imgur.com/t/unmuted/26sEhNr",
+ "#category": ("", "imgur", "gallery"),
+ "#class" : imgur.ImgurGalleryExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/t/cat/qSB8NbN",
+ "#category": ("", "imgur", "gallery"),
+ "#class" : imgur.ImgurGalleryExtractor,
+},
+
+{
+ "#url" : "https://imgur.io/t/cat/qSB8NbN",
+ "#comment" : ".io",
+ "#category": ("", "imgur", "gallery"),
+ "#class" : imgur.ImgurGalleryExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/user/Miguenzo",
+ "#category": ("", "imgur", "user"),
+ "#class" : imgur.ImgurUserExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://imgur.com/user/Miguenzo/posts",
+ "#category": ("", "imgur", "user"),
+ "#class" : imgur.ImgurUserExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/user/Miguenzo/submitted",
+ "#category": ("", "imgur", "user"),
+ "#class" : imgur.ImgurUserExtractor,
+},
+
+{
+ "#url" : "https://imgur.com/user/Miguenzo/favorites",
+ "#category": ("", "imgur", "favorite"),
+ "#class" : imgur.ImgurFavoriteExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://imgur.com/user/mikf1/favorites/folder/11896757/public",
+ "#category": ("", "imgur", "favorite-folder"),
+ "#class" : imgur.ImgurFavoriteFolderExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://imgur.com/user/mikf1/favorites/folder/11896741/private",
+ "#category": ("", "imgur", "favorite-folder"),
+ "#class" : imgur.ImgurFavoriteFolderExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://imgur.com/r/pics",
+ "#category": ("", "imgur", "subreddit"),
+ "#class" : imgur.ImgurSubredditExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://imgur.com/t/animals",
+ "#category": ("", "imgur", "tag"),
+ "#class" : imgur.ImgurTagExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://imgur.com/search?q=cute+cat",
+ "#category": ("", "imgur", "search"),
+ "#class" : imgur.ImgurSearchExtractor,
+ "#pattern" : r"https://imgur\.com(/a)?/\w+$",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+)
diff --git a/test/results/imxto.py b/test/results/imxto.py
new file mode 100644
index 00000000..430b388b
--- /dev/null
+++ b/test/results/imxto.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://imx.to/i/1qdeva",
+ "#comment" : "new-style URL",
+ "#category": ("imagehost", "imxto", "image"),
+ "#class" : imagehosts.ImxtoImageExtractor,
+ "#sha1_url" : "ab2173088a6cdef631d7a47dec4a5da1c6a00130",
+ "#sha1_content": "0c8768055e4e20e7c7259608b67799171b691140",
+
+ "size" : 18,
+ "width" : 64,
+ "height": 32,
+ "hash" : "94d56c599223c59f3feb71ea603484d1",
+},
+
+{
+ "#url" : "https://imx.to/img-57a2050547b97.html",
+ "#comment" : "old-style URL",
+ "#category": ("imagehost", "imxto", "image"),
+ "#class" : imagehosts.ImxtoImageExtractor,
+ "#sha1_url" : "a83fe6ef1909a318c4d49fcf2caf62f36c3f9204",
+ "#sha1_content": "54592f2635674c25677c6872db3709d343cdf92f",
+
+ "size" : 5284,
+ "width" : 320,
+ "height": 160,
+ "hash" : "40da6aaa7b8c42b18ef74309bbc713fc",
+},
+
+{
+ "#url" : "https://img.yt/img-57a2050547b97.html",
+ "#comment" : "img.yt domain",
+ "#category": ("imagehost", "imxto", "image"),
+ "#class" : imagehosts.ImxtoImageExtractor,
+ "#sha1_url": "a83fe6ef1909a318c4d49fcf2caf62f36c3f9204",
+},
+
+{
+ "#url" : "https://imx.to/img-57a2050547b98.html",
+ "#category": ("imagehost", "imxto", "image"),
+ "#class" : imagehosts.ImxtoImageExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://imx.to/g/ozdy",
+ "#category": ("imagehost", "imxto", "gallery"),
+ "#class" : imagehosts.ImxtoGalleryExtractor,
+ "#pattern" : imagehosts.ImxtoImageExtractor.pattern,
+ "#count" : 40,
+
+ "title": "untitled gallery",
+},
+
+)
diff --git a/test/results/inkbunny.py b/test/results/inkbunny.py
new file mode 100644
index 00000000..7129877e
--- /dev/null
+++ b/test/results/inkbunny.py
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import inkbunny
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://inkbunny.net/soina",
+ "#category": ("", "inkbunny", "user"),
+ "#class" : inkbunny.InkbunnyUserExtractor,
+ "#pattern" : r"https://[\w.]+\.metapix\.net/files/full/\d+/\d+_soina_.+",
+ "#range" : "20-50",
+
+ "date" : datetime.datetime,
+ "deleted" : bool,
+ "file_id" : r"re:[0-9]+",
+ "filename" : r"re:[0-9]+_soina_\w+",
+ "full_file_md5" : r"re:[0-9a-f]{32}",
+ "mimetype" : str,
+ "submission_id" : r"re:[0-9]+",
+ "user_id" : "20969",
+ "comments_count" : r"re:[0-9]+",
+ "favorite" : bool,
+ "favorites_count": r"re:[0-9]+",
+ "friends_only" : bool,
+ "guest_block" : bool,
+ "hidden" : bool,
+ "pagecount" : r"re:[0-9]+",
+ "pools" : list,
+ "pools_count" : int,
+ "public" : bool,
+ "rating_id" : r"re:[0-9]+",
+ "rating_name" : str,
+ "ratings" : list,
+ "scraps" : bool,
+ "tags" : list,
+ "title" : str,
+ "type_name" : str,
+ "username" : "soina",
+ "views" : str,
+},
+
+{
+ "#url" : "https://inkbunny.net/gallery/soina",
+ "#category": ("", "inkbunny", "gallery"),
+ "#class" : inkbunny.InkbunnyUserExtractor,
+ "#range" : "1-25",
+
+ "scraps": False,
+},
+
+{
+ "#url" : "https://inkbunny.net/scraps/soina",
+ "#category": ("", "inkbunny", "scraps"),
+ "#class" : inkbunny.InkbunnyUserExtractor,
+ "#range" : "1-25",
+
+ "scraps": True,
+},
+
+{
+ "#url" : "https://inkbunny.net/poolview_process.php?pool_id=28985",
+ "#category": ("", "inkbunny", "pool"),
+ "#class" : inkbunny.InkbunnyPoolExtractor,
+ "#count" : 9,
+
+ "pool_id": "28985",
+},
+
+{
+ "#url" : "https://inkbunny.net/submissionsviewall.php?rid=ffffffffff&mode=pool&pool_id=28985&page=1&orderby=pool_order&random=no",
+ "#category": ("", "inkbunny", "pool"),
+ "#class" : inkbunny.InkbunnyPoolExtractor,
+},
+
+{
+ "#url" : "https://inkbunny.net/userfavorites_process.php?favs_user_id=20969",
+ "#category": ("", "inkbunny", "favorite"),
+ "#class" : inkbunny.InkbunnyFavoriteExtractor,
+ "#pattern" : r"https://[\w.]+\.metapix\.net/files/full/\d+/\d+_\w+_.+",
+ "#range" : "20-50",
+
+ "favs_user_id": "20969",
+},
+
+{
+ "#url" : "https://inkbunny.net/submissionsviewall.php?rid=ffffffffff&mode=userfavs&random=no&orderby=fav_datetime&page=1&user_id=20969",
+ "#category": ("", "inkbunny", "favorite"),
+ "#class" : inkbunny.InkbunnyFavoriteExtractor,
+},
+
+{
+ "#url" : "https://inkbunny.net/submissionsviewall.php?rid=ffffffffff&mode=search&page=1&orderby=create_datetime&text=cute&stringtype=and&keywords=yes&title=yes&description=no&artist=&favsby=&type=&days=&keyword_id=&user_id=&random=&md5=",
+ "#category": ("", "inkbunny", "search"),
+ "#class" : inkbunny.InkbunnySearchExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+
+ "search": {
+ "rid" : "ffffffffff",
+ "mode" : "search",
+ "page" : "1",
+ "orderby" : "create_datetime",
+ "text" : "cute",
+ "stringtype" : "and",
+ "keywords" : "yes",
+ "title" : "yes",
+ "description": "no",
+ },
+},
+
+{
+ "#url" : "https://inkbunny.net/watchlist_process.php?mode=watching&user_id=20969",
+ "#category": ("", "inkbunny", "following"),
+ "#class" : inkbunny.InkbunnyFollowingExtractor,
+ "#pattern" : inkbunny.InkbunnyUserExtractor.pattern,
+ "#count" : ">= 90",
+},
+
+{
+ "#url" : "https://inkbunny.net/usersviewall.php?rid=ffffffffff&mode=watching&page=1&user_id=20969&orderby=added&namesonly=",
+ "#category": ("", "inkbunny", "following"),
+ "#class" : inkbunny.InkbunnyFollowingExtractor,
+},
+
+{
+ "#url" : "https://inkbunny.net/s/1829715",
+ "#category": ("", "inkbunny", "post"),
+ "#class" : inkbunny.InkbunnyPostExtractor,
+ "#pattern" : r"https://[\w.]+\.metapix\.net/files/full/2626/2626843_soina_dscn2296\.jpg",
+ "#sha1_content": "cf69d8dddf0822a12b4eef1f4b2258bd600b36c8",
+},
+
+{
+ "#url" : "https://inkbunny.net/s/2044094",
+ "#category": ("", "inkbunny", "post"),
+ "#class" : inkbunny.InkbunnyPostExtractor,
+ "#count" : 4,
+},
+
+)
diff --git a/test/results/instagram.py b/test/results/instagram.py
new file mode 100644
index 00000000..7f601426
--- /dev/null
+++ b/test/results/instagram.py
@@ -0,0 +1,262 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import instagram
+
+
+__tests__ = (
+{
+ "#url" : "https://www.instagram.com/instagram/",
+ "#category": ("", "instagram", "user"),
+ "#class" : instagram.InstagramUserExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/?hl=en",
+ "#category": ("", "instagram", "user"),
+ "#class" : instagram.InstagramUserExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/id:25025320/",
+ "#category": ("", "instagram", "user"),
+ "#class" : instagram.InstagramUserExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/posts/",
+ "#category": ("", "instagram", "posts"),
+ "#class" : instagram.InstagramPostsExtractor,
+ "#range" : "1-16",
+ "#count" : ">= 16",
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/reels/",
+ "#category": ("", "instagram", "reels"),
+ "#class" : instagram.InstagramReelsExtractor,
+ "#range" : "40-60",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/tagged/",
+ "#category": ("", "instagram", "tagged"),
+ "#class" : instagram.InstagramTaggedExtractor,
+ "#range" : "1-16",
+ "#count" : ">= 16",
+
+ "tagged_owner_id" : "25025320",
+ "tagged_username" : "instagram",
+ "tagged_full_name": "Instagram",
+},
+
+{
+ "#url" : "https://www.instagram.com/kadakaofficial/guide/knit-i-need-collection/18131821684305217/",
+ "#category": ("", "instagram", "guide"),
+ "#class" : instagram.InstagramGuideExtractor,
+ "#range" : "1-16",
+ "#count" : ">= 16",
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/saved/",
+ "#category": ("", "instagram", "saved"),
+ "#class" : instagram.InstagramSavedExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/saved/all-posts/",
+ "#category": ("", "instagram", "saved"),
+ "#class" : instagram.InstagramSavedExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/saved/collection_name/123456789/",
+ "#category": ("", "instagram", "collection"),
+ "#class" : instagram.InstagramCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/stories/instagram/",
+ "#category": ("", "instagram", "stories"),
+ "#class" : instagram.InstagramStoriesExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/stories/highlights/18042509488170095/",
+ "#category": ("", "instagram", "highlights"),
+ "#class" : instagram.InstagramStoriesExtractor,
+},
+
+{
+ "#url" : "https://instagram.com/stories/geekmig/2724343156064789461",
+ "#category": ("", "instagram", "stories"),
+ "#class" : instagram.InstagramStoriesExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/s/aGlnaGxpZ2h0OjE4MDQyNTA5NDg4MTcwMDk1",
+ "#category": ("", "instagram", "highlights"),
+ "#class" : instagram.InstagramStoriesExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/s/aGlnaGxpZ2h0OjE4MDQyNTA5NDg4MTcwMDk1?story_media_id=2724343156064789461",
+ "#category": ("", "instagram", "highlights"),
+ "#class" : instagram.InstagramStoriesExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/highlights",
+ "#category": ("", "instagram", "highlights"),
+ "#class" : instagram.InstagramHighlightsExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/following",
+ "#category": ("", "instagram", "following"),
+ "#class" : instagram.InstagramFollowingExtractor,
+ "#range" : "1-16",
+ "#count" : ">= 16",
+},
+
+{
+ "#url" : "https://www.instagram.com/explore/tags/instagram/",
+ "#category": ("", "instagram", "tag"),
+ "#class" : instagram.InstagramTagExtractor,
+ "#range" : "1-16",
+ "#count" : ">= 16",
+},
+
+{
+ "#url" : "https://www.instagram.com/instagram/avatar",
+ "#category": ("", "instagram", "avatar"),
+ "#class" : instagram.InstagramAvatarExtractor,
+ "#pattern" : r"https://instagram\.[\w.-]+\.fbcdn\.net/v/t51\.2885-19/281440578_1088265838702675_6233856337905829714_n\.jpg",
+},
+
+{
+ "#url" : "https://www.instagram.com/p/BqvsDleB3lV/",
+ "#comment" : "GraphImage",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+ "#pattern" : r"https://[^/]+\.(cdninstagram\.com|fbcdn\.net)/v(p/[0-9a-f]+/[0-9A-F]+)?/t51.2885-15/e35/44877605_725955034447492_3123079845831750529_n.jpg",
+
+ "date" : "dt:2018-11-29 01:04:04",
+ "description" : str,
+ "height" : int,
+ "likes" : int,
+ "location_id" : "214424288",
+ "location_slug" : "hong-kong",
+ "location_url" : r"re:/explore/locations/214424288/hong-kong/",
+ "media_id" : "1922949326347663701",
+ "shortcode" : "BqvsDleB3lV",
+ "post_id" : "1922949326347663701",
+ "post_shortcode": "BqvsDleB3lV",
+ "post_url" : "https://www.instagram.com/p/BqvsDleB3lV/",
+ "tags" : ["#WHPsquares"],
+ "typename" : "GraphImage",
+ "username" : "instagram",
+ "width" : int,
+},
+
+{
+ "#url" : "https://www.instagram.com/p/BoHk1haB5tM/",
+ "#comment" : "GraphSidecar",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+ "#count" : 5,
+
+ "sidecar_media_id": "1875629777499953996",
+ "sidecar_shortcode": "BoHk1haB5tM",
+ "post_id" : "1875629777499953996",
+ "post_shortcode" : "BoHk1haB5tM",
+ "post_url" : "https://www.instagram.com/p/BoHk1haB5tM/",
+ "num" : int,
+ "likes" : int,
+ "username" : "instagram",
+},
+
+{
+ "#url" : "https://www.instagram.com/p/Bqxp0VSBgJg/",
+ "#comment" : "GraphVideo",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+ "#pattern" : r"/46840863_726311431074534_7805566102611403091_n\.mp4",
+
+ "date" : "dt:2018-11-29 19:23:58",
+ "description": str,
+ "height" : int,
+ "likes" : int,
+ "media_id" : "1923502432034620000",
+ "post_url" : "https://www.instagram.com/p/Bqxp0VSBgJg/",
+ "shortcode" : "Bqxp0VSBgJg",
+ "tags" : ["#ASMR"],
+ "typename" : "GraphVideo",
+ "username" : "instagram",
+ "width" : int,
+},
+
+{
+ "#url" : "https://www.instagram.com/tv/BkQjCfsBIzi/",
+ "#comment" : "GraphVideo (IGTV)",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+ "#pattern" : r"/10000000_597132547321814_702169244961988209_n\.mp4",
+
+ "date" : "dt:2018-06-20 19:51:32",
+ "description": str,
+ "height" : int,
+ "likes" : int,
+ "media_id" : "1806097553666903266",
+ "post_url" : "https://www.instagram.com/p/BkQjCfsBIzi/",
+ "shortcode" : "BkQjCfsBIzi",
+ "typename" : "GraphVideo",
+ "username" : "instagram",
+ "width" : int,
+},
+
+{
+ "#url" : "https://www.instagram.com/p/BtOvDOfhvRr/",
+ "#comment" : "GraphSidecar with 2 embedded GraphVideo objects",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+ "#count" : 2,
+
+ "post_url" : "https://www.instagram.com/p/BtOvDOfhvRr/",
+ "sidecar_media_id": "1967717017113261163",
+ "sidecar_shortcode": "BtOvDOfhvRr",
+ "video_url" : str,
+},
+
+{
+ "#url" : "https://www.instagram.com/p/B_2lf3qAd3y/",
+ "#comment" : "GraphImage with tagged user",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+
+ "tagged_users": [{
+ "id" : "1246468638",
+ "username" : "kaaymbl",
+ "full_name": "Call Me Kay",
+}],
+},
+
+{
+ "#url" : "https://www.instagram.com/dm/p/CW042g7B9CY/",
+ "#comment" : "URL with username (#2085)",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+},
+
+{
+ "#url" : "https://www.instagram.com/reel/CDg_6Y1pxWu/",
+ "#category": ("", "instagram", "post"),
+ "#class" : instagram.InstagramPostExtractor,
+},
+
+)
diff --git a/test/results/issuu.py b/test/results/issuu.py
new file mode 100644
index 00000000..5e086d1e
--- /dev/null
+++ b/test/results/issuu.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import issuu
+
+
+__tests__ = (
+{
+ "#url" : "https://issuu.com/issuu/docs/motions-1-2019/",
+ "#category": ("", "issuu", "publication"),
+ "#class" : issuu.IssuuPublicationExtractor,
+ "#pattern" : r"https://image.isu.pub/190916155301-\w+/jpg/page_\d+.jpg",
+ "#count" : 36,
+
+ "document" : {
+ "access" : "PUBLIC",
+ "contentRating": {
+ "isAdsafe" : True,
+ "isExplicit": False,
+ "isReviewed": True,
+ },
+ "date" : "dt:2019-09-16 00:00:00",
+ "description" : r"re:Motions, the brand new publication by I",
+ "documentName" : "motions-1-2019",
+ "downloadable" : False,
+ "pageCount" : 36,
+ "publicationId": "d99ec95935f15091b040cb8060f05510",
+ "title" : "Motions by Issuu - Issue 1",
+ "username" : "issuu",
+ },
+ "extension": "jpg",
+ "filename" : r"re:page_\d+",
+ "num" : int,
+},
+
+{
+ "#url" : "https://issuu.com/issuu",
+ "#category": ("", "issuu", "user"),
+ "#class" : issuu.IssuuUserExtractor,
+ "#pattern" : issuu.IssuuPublicationExtractor.pattern,
+ "#count" : "> 25",
+},
+
+)
diff --git a/test/results/itaku.py b/test/results/itaku.py
new file mode 100644
index 00000000..ef3d3679
--- /dev/null
+++ b/test/results/itaku.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import itaku
+
+
+__tests__ = (
+{
+ "#url" : "https://itaku.ee/profile/piku/gallery",
+ "#category": ("", "itaku", "gallery"),
+ "#class" : itaku.ItakuGalleryExtractor,
+ "#pattern" : r"https://d1wmr8tlk3viaj\.cloudfront\.net/gallery_imgs/[^/?#]+\.(jpg|png|gif)",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://itaku.ee/images/100471",
+ "#category": ("", "itaku", "image"),
+ "#class" : itaku.ItakuImageExtractor,
+ "#pattern" : r"https://d1wmr8tlk3viaj\.cloudfront\.net/gallery_imgs/220504_oUNIAFT\.png",
+ "#count" : 1,
+
+ "already_pinned" : None,
+ "blacklisted" : {
+ "blacklisted_tags": [],
+ "is_blacklisted" : False,
+ },
+ "can_reshare" : True,
+ "date" : "dt:2022-05-05 19:21:17",
+ "date_added" : "2022-05-05T19:21:17.674148Z",
+ "date_edited" : "2022-05-25T14:37:46.220612Z",
+ "description" : "sketch from drawpile",
+ "extension" : "png",
+ "filename" : "220504_oUNIAFT",
+ "hotness_score" : float,
+ "id" : 100471,
+ "image" : "https://d1wmr8tlk3viaj.cloudfront.net/gallery_imgs/220504_oUNIAFT.png",
+ "image_xl" : "https://d1wmr8tlk3viaj.cloudfront.net/gallery_imgs/220504_oUNIAFT/lg.jpg",
+ "liked_by_you" : False,
+ "maturity_rating" : "SFW",
+ "num_comments" : int,
+ "num_likes" : int,
+ "num_reshares" : int,
+ "obj_tags" : 136446,
+ "owner" : 16775,
+ "owner_avatar" : "https://d1wmr8tlk3viaj.cloudfront.net/profile_pics/av2022r_vKYVywc/md.jpg",
+ "owner_displayname": "Piku",
+ "owner_username" : "piku",
+ "reshared_by_you" : False,
+ "sections" : ["Fanart/Miku"],
+ "tags" : list,
+ "tags_character" : ["hatsune_miku"],
+ "tags_copyright" : ["vocaloid"],
+ "tags_general" : [
+ "twintails",
+ "green_hair",
+ "flag",
+ "gloves",
+ "green_eyes",
+ "female",
+ "racing_miku",
+ ],
+ "title" : "Racing Miku 2022 Ver.",
+ "too_mature" : False,
+ "uncompressed_filesize": "0.62",
+ "video" : None,
+ "visibility" : "PUBLIC",
+},
+
+{
+ "#url" : "https://itaku.ee/images/19465",
+ "#comment" : "video",
+ "#category": ("", "itaku", "image"),
+ "#class" : itaku.ItakuImageExtractor,
+ "#pattern" : r"https://d1wmr8tlk3viaj\.cloudfront\.net/gallery_vids/sleepy_af_OY5GHWw\.mp4",
+},
+
+)
diff --git a/test/results/itchio.py b/test/results/itchio.py
new file mode 100644
index 00000000..d2acfa61
--- /dev/null
+++ b/test/results/itchio.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import itchio
+
+
+__tests__ = (
+{
+ "#url" : "https://sirtartarus.itch.io/a-craft-of-mine",
+ "#category": ("", "itchio", "game"),
+ "#class" : itchio.ItchioGameExtractor,
+ "#pattern" : r"https://\w+\.ssl\.hwcdn\.net/upload2/game/1983311/7723751\?",
+ "#count" : 1,
+
+ "extension": "",
+ "filename" : "7723751",
+ "game" : {
+ "id" : 1983311,
+ "noun" : "game",
+ "title": "A Craft Of Mine",
+ "url" : "https://sirtartarus.itch.io/a-craft-of-mine",
+ },
+ "user" : {
+ "id" : 4060052,
+ "name": "SirTartarus",
+ "url" : "https://sirtartarus.itch.io",
+ },
+},
+
+)
diff --git a/test/results/joyreactor.py b/test/results/joyreactor.py
new file mode 100644
index 00000000..4c29c213
--- /dev/null
+++ b/test/results/joyreactor.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import reactor
+
+
+__tests__ = (
+{
+ "#url" : "http://joyreactor.cc/tag/Advent+Cirno",
+ "#category": ("reactor", "joyreactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "http://joyreactor.com/tag/Cirno",
+ "#category": ("reactor", "joyreactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+ "#sha1_url": "aa59090590b26f4654881301fe8fe748a51625a8",
+},
+
+{
+ "#url" : "http://joyreactor.com/tag/Dark+Souls+2/best",
+ "#comment" : "'best' rating (#3073)",
+ "#category": ("reactor", "joyreactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+ "#count" : 4,
+},
+
+{
+ "#url" : "http://joyreactor.cc/search/Nature",
+ "#category": ("reactor", "joyreactor", "search"),
+ "#class" : reactor.ReactorSearchExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "http://joyreactor.com/search?q=Nature",
+ "#category": ("reactor", "joyreactor", "search"),
+ "#class" : reactor.ReactorSearchExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "http://joyreactor.cc/user/hemantic",
+ "#category": ("reactor", "joyreactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+},
+
+{
+ "#url" : "http://joyreactor.com/user/Tacoman123",
+ "#category": ("reactor", "joyreactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+ "#sha1_url": "60ce9a3e3db791a0899f7fb7643b5b87d09ae3b5",
+},
+
+{
+ "#url" : "http://joyreactor.com/post/3721876",
+ "#comment" : "single image",
+ "#category": ("reactor", "joyreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#pattern" : r"http://img\d\.joyreactor\.com/pics/post/full/cartoon-painting-monster-lake-4841316.jpeg",
+ "#count" : 1,
+ "#sha1_metadata": "2207a7dfed55def2042b6c2554894c8d7fda386e",
+},
+
+{
+ "#url" : "http://joyreactor.com/post/3713804",
+ "#comment" : "4 images",
+ "#category": ("reactor", "joyreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#pattern" : r"http://img\d\.joyreactor\.com/pics/post/full/movie-tv-godzilla-monsters-\d+\.jpeg",
+ "#count" : 4,
+ "#sha1_metadata": "d7da9ba7809004c809eedcf6f1c06ad0fbb3df21",
+},
+
+{
+ "#url" : "http://joyreactor.com/post/3726210",
+ "#comment" : "gif / video",
+ "#category": ("reactor", "joyreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url" : "60f3b9a0a3918b269bea9b4f8f1a5ab3c2c550f8",
+ "#sha1_metadata": "8949d9d5fc469dab264752432efbaa499561664a",
+},
+
+{
+ "#url" : "http://joyreactor.com/post/3668724",
+ "#comment" : "youtube embed",
+ "#category": ("reactor", "joyreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url" : "bf1666eddcff10c9b58f6be63fa94e4e13074214",
+ "#sha1_metadata": "e18b1ffbd79d76f9a0e90b6d474cc2499e343f0b",
+},
+
+{
+ "#url" : "http://joyreactor.cc/post/1299",
+ "#comment" : "'malformed' JSON",
+ "#category": ("reactor", "joyreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url": "ab02c6eb7b4035ad961b29ee0770ee41be2fcc39",
+},
+
+)
diff --git a/test/results/jpgfish.py b/test/results/jpgfish.py
new file mode 100644
index 00000000..5aa4a126
--- /dev/null
+++ b/test/results/jpgfish.py
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import jpgfish
+
+
+__tests__ = (
+{
+ "#url" : "https://jpg1.su/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+ "#pattern" : r"https://simp3\.jpg\.church/images/funnymeme\.jpg",
+ "#sha1_content": "098e5e9b17ad634358426e0ffd1c93871474d13c",
+
+ "album" : "",
+ "extension": "jpg",
+ "filename" : "funnymeme",
+ "id" : "LecXGS",
+ "url" : "https://simp3.jpg.church/images/funnymeme.jpg",
+ "user" : "exearco",
+},
+
+{
+ "#url" : "https://jpg.church/img/auCruA",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+ "#pattern" : r"https://simp2\.jpg\.church/hannahowo_00457\.jpg",
+
+ "album": "401-500",
+},
+
+{
+ "#url" : "https://jpeg.pet/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+},
+
+{
+ "#url" : "https://jpg.pet/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+},
+
+{
+ "#url" : "https://jpg.fishing/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+},
+
+{
+ "#url" : "https://jpg.fish/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+},
+
+{
+ "#url" : "https://jpg.church/img/funnymeme.LecXGS",
+ "#category": ("", "jpgfish", "image"),
+ "#class" : jpgfish.JpgfishImageExtractor,
+},
+
+{
+ "#url" : "https://jpg1.su/album/CDilP/?sort=date_desc&page=1",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://jpg.fishing/a/gunggingnsk.N9OOI",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+ "#count" : 114,
+},
+
+{
+ "#url" : "https://jpg.fish/a/101-200.aNJ6A/",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://jpg.church/a/hannahowo.aNTdH/sub",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+ "#count" : 606,
+},
+
+{
+ "#url" : "https://jpeg.pet/album/CDilP/?sort=date_desc&page=1",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+},
+
+{
+ "#url" : "https://jpg.pet/album/CDilP/?sort=date_desc&page=1",
+ "#category": ("", "jpgfish", "album"),
+ "#class" : jpgfish.JpgfishAlbumExtractor,
+},
+
+{
+ "#url" : "https://jpg1.su/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://jpg.church/exearco/albums",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://jpeg.pet/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+},
+
+{
+ "#url" : "https://jpg.pet/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+},
+
+{
+ "#url" : "https://jpg.fishing/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+},
+
+{
+ "#url" : "https://jpg.fish/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+},
+
+{
+ "#url" : "https://jpg.church/exearco",
+ "#category": ("", "jpgfish", "user"),
+ "#class" : jpgfish.JpgfishUserExtractor,
+},
+
+)
diff --git a/test/results/kabeuchi.py b/test/results/kabeuchi.py
new file mode 100644
index 00000000..37b6a3d8
--- /dev/null
+++ b/test/results/kabeuchi.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import kabeuchi
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://kabe-uchiroom.com/mypage/?id=919865303848255493",
+ "#category": ("", "kabeuchi", "user"),
+ "#class" : kabeuchi.KabeuchiUserExtractor,
+ "#pattern" : r"https://kabe-uchiroom\.com/accounts/upfile/3/919865303848255493/\w+\.jpe?g",
+ "#count" : ">= 24",
+},
+
+{
+ "#url" : "https://kabe-uchiroom.com/mypage/?id=123456789",
+ "#category": ("", "kabeuchi", "user"),
+ "#class" : kabeuchi.KabeuchiUserExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+)
diff --git a/test/results/keenspot.py b/test/results/keenspot.py
new file mode 100644
index 00000000..9f756ad8
--- /dev/null
+++ b/test/results/keenspot.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import keenspot
+
+
+__tests__ = (
+{
+ "#url" : "http://marksmen.keenspot.com/",
+ "#comment" : "link",
+ "#category": ("", "keenspot", "comic"),
+ "#class" : keenspot.KeenspotComicExtractor,
+ "#range" : "1-3",
+ "#sha1_url": "83bcf029103bf8bc865a1988afa4aaeb23709ba6",
+},
+
+{
+ "#url" : "http://barkercomic.keenspot.com/",
+ "#comment" : "id",
+ "#category": ("", "keenspot", "comic"),
+ "#class" : keenspot.KeenspotComicExtractor,
+ "#range" : "1-3",
+ "#sha1_url": "c4080926db18d00bac641fdd708393b7d61379e6",
+},
+
+{
+ "#url" : "http://crowscare.keenspot.com/",
+ "#comment" : "id v2",
+ "#category": ("", "keenspot", "comic"),
+ "#class" : keenspot.KeenspotComicExtractor,
+ "#range" : "1-3",
+ "#sha1_url": "a00e66a133dd39005777317da90cef921466fcaa",
+},
+
+{
+ "#url" : "http://supernovas.keenspot.com/",
+ "#comment" : "ks",
+ "#category": ("", "keenspot", "comic"),
+ "#class" : keenspot.KeenspotComicExtractor,
+ "#range" : "1-3",
+ "#sha1_url": "de21b12887ef31ff82edccbc09d112e3885c3aab",
+},
+
+{
+ "#url" : "http://twokinds.keenspot.com/comic/1066/",
+ "#category": ("", "keenspot", "comic"),
+ "#class" : keenspot.KeenspotComicExtractor,
+ "#range" : "1-3",
+ "#sha1_url": "6a784e11370abfb343dcad9adbb7718f9b7be350",
+},
+
+)
diff --git a/test/results/kemonoparty.py b/test/results/kemonoparty.py
new file mode 100644
index 00000000..f5419f02
--- /dev/null
+++ b/test/results/kemonoparty.py
@@ -0,0 +1,232 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import kemonoparty
+
+
+__tests__ = (
+{
+ "#url" : "https://kemono.party/fanbox/user/6993449",
+ "#category": ("", "kemonoparty", "fanbox"),
+ "#class" : kemonoparty.KemonopartyUserExtractor,
+ "#range" : "1-25",
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://kemono.party/patreon/user/881792?o=150",
+ "#comment" : "'max-posts' option, 'o' query parameter (#1674)",
+ "#category": ("", "kemonoparty", "patreon"),
+ "#class" : kemonoparty.KemonopartyUserExtractor,
+ "#options" : {"max-posts": 25},
+ "#count" : "< 100",
+},
+
+{
+ "#url" : "https://kemono.su/subscribestar/user/alcorart",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyUserExtractor,
+},
+
+{
+ "#url" : "https://kemono.party/subscribestar/user/alcorart",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyUserExtractor,
+},
+
+{
+ "#url" : "https://kemono.party/fanbox/user/6993449/post/506575",
+ "#category": ("", "kemonoparty", "fanbox"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#pattern" : r"https://kemono.party/data/21/0f/210f35388e28bbcf756db18dd516e2d82ce75[0-9a-f]+\.jpg",
+ "#sha1_content": "900949cefc97ab8dc1979cc3664785aac5ba70dd",
+
+ "added" : "Wed, 06 May 2020 20:28:02 GMT",
+ "content" : str,
+ "count" : 1,
+ "date" : "dt:2019-08-11 02:09:04",
+ "edited" : None,
+ "embed" : dict,
+ "extension" : "jpeg",
+ "filename" : "P058kDFYus7DbqAkGlfWTlOr",
+ "hash" : "210f35388e28bbcf756db18dd516e2d82ce758e0d32881eeee76d43e1716d382",
+ "id" : "506575",
+ "num" : 1,
+ "published" : "Sun, 11 Aug 2019 02:09:04 GMT",
+ "service" : "fanbox",
+ "shared_file": False,
+ "subcategory": "fanbox",
+ "title" : "c96取り置き",
+ "type" : "file",
+ "user" : "6993449",
+},
+
+{
+ "#url" : "https://kemono.party/fanbox/user/7356311/post/802343",
+ "#comment" : "inline image (#1286)",
+ "#category": ("", "kemonoparty", "fanbox"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#pattern" : r"https://kemono\.party/data/47/b5/47b5c014ecdcfabdf2c85eec53f1133a76336997ae8596f332e97d956a460ad2\.jpg",
+
+ "hash": "47b5c014ecdcfabdf2c85eec53f1133a76336997ae8596f332e97d956a460ad2",
+},
+
+{
+ "#url" : "https://kemono.party/gumroad/user/trylsc/post/IURjT",
+ "#comment" : "kemono.party -> data.kemono.party",
+ "#category": ("", "kemonoparty", "gumroad"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#pattern" : r"https://kemono\.party/data/(a4/7b/a47bfe938d8c1682eef06e885927484cd8df1b.+\.jpg|c6/04/c6048f5067fd9dbfa7a8be565ac194efdfb6e4.+\.zip)",
+},
+
+{
+ "#url" : "https://kemono.party/gumroad/user/3252870377455/post/aJnAH",
+ "#comment" : "username (#1548, #1652)",
+ "#category": ("", "kemonoparty", "gumroad"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#options" : {"metadata": True},
+
+ "username": "Kudalyn's Creations",
+},
+
+{
+ "#url" : "https://kemono.party/patreon/user/4158582/post/32099982",
+ "#comment" : "allow duplicates (#2440)",
+ "#category": ("", "kemonoparty", "patreon"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://kemono.party/patreon/user/4158582/post/32099982",
+ "#comment" : "allow duplicates (#2440)",
+ "#category": ("", "kemonoparty", "patreon"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#options" : {"duplicates": True},
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://kemono.party/patreon/user/34134344/post/38129255",
+ "#comment" : "DMs (#2008)",
+ "#category": ("", "kemonoparty", "patreon"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#options" : {"dms": True},
+
+ "dms": [{
+ "body" : r"re:Hi! Thank you very much for supporting the work I did in May. Here's your reward pack! I hope you find something you enjoy in it. :\)\n\nhttps://www.mediafire.com/file/\w+/Set13_tier_2.zip/file",
+ "date" : "2021-07-31 02:47:51.327865",
+}],
+},
+
+{
+ "#url" : "https://kemono.party/patreon/user/19623797/post/29035449",
+ "#comment" : "invalid file (#3510)",
+ "#category": ("", "kemonoparty", "patreon"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+ "#pattern" : r"907ba78b4545338d3539683e63ecb51cf51c10adc9dabd86e92bd52339f298b9\.txt",
+ "#sha1_content": "da39a3ee5e6b4b0d3255bfef95601890afd80709",
+},
+
+{
+ "#url" : "https://kemono.su/subscribestar/user/alcorart/post/184330",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+},
+
+{
+ "#url" : "https://kemono.party/subscribestar/user/alcorart/post/184330",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+},
+
+{
+ "#url" : "https://www.kemono.party/subscribestar/user/alcorart/post/184330",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+},
+
+{
+ "#url" : "https://beta.kemono.party/subscribestar/user/alcorart/post/184330",
+ "#category": ("", "kemonoparty", "subscribestar"),
+ "#class" : kemonoparty.KemonopartyPostExtractor,
+},
+
+{
+ "#url" : "https://kemono.party/discord/server/488668827274444803#finish-work",
+ "#category": ("", "kemonoparty", "discord"),
+ "#class" : kemonoparty.KemonopartyDiscordExtractor,
+ "#count" : 4,
+
+ "channel_name": "finish-work",
+},
+
+{
+ "#url" : "https://kemono.su/discord/server/256559665620451329/channel/462437519519383555#",
+ "#category": ("", "kemonoparty", "discord"),
+ "#class" : kemonoparty.KemonopartyDiscordExtractor,
+ "#pattern" : r"https://kemono\.su/data/(e3/77/e377e3525164559484ace2e64425b0cec1db08.*\.png|51/45/51453640a5e0a4d23fbf57fb85390f9c5ec154.*\.gif)",
+ "#count" : ">= 2",
+
+ "hash": r"re:e377e3525164559484ace2e64425b0cec1db08|51453640a5e0a4d23fbf57fb85390f9c5ec154",
+},
+
+{
+ "#url" : "https://kemono.party/discord/server/315262215055736843/channel/315262215055736843#general",
+ "#comment" : "'inline' files",
+ "#category": ("", "kemonoparty", "discord"),
+ "#class" : kemonoparty.KemonopartyDiscordExtractor,
+ "#options" : {"image-filter": "type == 'inline'"},
+ "#pattern" : r"https://cdn\.discordapp\.com/attachments/\d+/\d+/.+$",
+ "#range" : "1-5",
+
+ "hash": "",
+},
+
+{
+ "#url" : "https://kemono.party/discord/server/488668827274444803",
+ "#category": ("", "kemonoparty", "discord-server"),
+ "#class" : kemonoparty.KemonopartyDiscordServerExtractor,
+ "#pattern" : kemonoparty.KemonopartyDiscordExtractor.pattern,
+ "#count" : 13,
+},
+
+{
+ "#url" : "https://kemono.su/discord/server/488668827274444803",
+ "#category": ("", "kemonoparty", "discord-server"),
+ "#class" : kemonoparty.KemonopartyDiscordServerExtractor,
+ "#pattern" : kemonoparty.KemonopartyDiscordExtractor.pattern,
+ "#count" : 13,
+},
+
+{
+ "#url" : "https://kemono.party/favorites",
+ "#category": ("", "kemonoparty", "favorite"),
+ "#class" : kemonoparty.KemonopartyFavoriteExtractor,
+ "#pattern" : kemonoparty.KemonopartyUserExtractor.pattern,
+ "#count" : 3,
+ "#sha1_url": "f4b5b796979bcba824af84206578c79101c7f0e1",
+},
+
+{
+ "#url" : "https://kemono.party/favorites?type=post",
+ "#category": ("", "kemonoparty", "favorite"),
+ "#class" : kemonoparty.KemonopartyFavoriteExtractor,
+ "#pattern" : kemonoparty.KemonopartyPostExtractor.pattern,
+ "#count" : 3,
+ "#sha1_url": "ecfccf5f0d50b8d14caa7bbdcf071de5c1e5b90f",
+},
+
+{
+ "#url" : "https://kemono.su/favorites?type=post",
+ "#category": ("", "kemonoparty", "favorite"),
+ "#class" : kemonoparty.KemonopartyFavoriteExtractor,
+ "#pattern" : kemonoparty.KemonopartyPostExtractor.pattern,
+ "#count" : 3,
+ "#sha1_url": "4be8e84cb384a907a8e7997baaf6287b451783b5",
+},
+
+)
diff --git a/test/results/khinsider.py b/test/results/khinsider.py
new file mode 100644
index 00000000..b680cab2
--- /dev/null
+++ b/test/results/khinsider.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import khinsider
+
+
+__tests__ = (
+{
+ "#url" : "https://downloads.khinsider.com/game-soundtracks/album/horizon-riders-wii",
+ "#category": ("", "khinsider", "soundtrack"),
+ "#class" : khinsider.KhinsiderSoundtrackExtractor,
+ "#pattern" : r"https?://vgm(site|downloads)\.com/soundtracks/horizon-riders-wii/[^/]+/Horizon%20Riders%20Wii%20-%20Full%20Soundtrack\.mp3",
+ "#count" : 1,
+
+ "album" : {
+ "count" : 1,
+ "date" : "Sep 18th, 2016",
+ "name" : "Horizon Riders",
+ "platform": "Wii",
+ "size" : 26214400,
+ "type" : "Gamerip",
+ },
+ "extension": "mp3",
+ "filename" : "Horizon Riders Wii - Full Soundtrack",
+},
+
+)
diff --git a/test/results/kohlchan.py b/test/results/kohlchan.py
new file mode 100644
index 00000000..479ed715
--- /dev/null
+++ b/test/results/kohlchan.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lynxchan
+
+
+__tests__ = (
+{
+ "#url" : "https://kohlchan.net/a/res/4594.html",
+ "#category": ("lynxchan", "kohlchan", "thread"),
+ "#class" : lynxchan.LynxchanThreadExtractor,
+ "#pattern" : r"https://kohlchan\.net/\.media/[0-9a-f]{64}(\.\w+)?$",
+ "#count" : ">= 80",
+},
+
+{
+ "#url" : "https://kohlchan.net/a/",
+ "#category": ("lynxchan", "kohlchan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+ "#pattern" : lynxchan.LynxchanThreadExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://kohlchan.net/a/2.html",
+ "#category": ("lynxchan", "kohlchan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+},
+
+{
+ "#url" : "https://kohlchan.net/a/catalog.html",
+ "#category": ("lynxchan", "kohlchan", "board"),
+ "#class" : lynxchan.LynxchanBoardExtractor,
+},
+
+)
diff --git a/test/results/komikcast.py b/test/results/komikcast.py
new file mode 100644
index 00000000..9a246009
--- /dev/null
+++ b/test/results/komikcast.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import komikcast
+
+
+__tests__ = (
+{
+ "#url" : "https://komikcast.site/chapter/apotheosis-chapter-02-2-bahasa-indonesia/",
+ "#category": ("", "komikcast", "chapter"),
+ "#class" : komikcast.KomikcastChapterExtractor,
+ "#sha1_url" : "f6b43fbc027697749b3ea1c14931c83f878d7936",
+ "#sha1_metadata": "f3938e1aff9ad1f302f52447e9781b21f6da26d4",
+},
+
+{
+ "#url" : "https://komikcast.me/chapter/soul-land-ii-chapter-300-1-bahasa-indonesia/",
+ "#category": ("", "komikcast", "chapter"),
+ "#class" : komikcast.KomikcastChapterExtractor,
+ "#sha1_url" : "efd00a9bd95461272d51990d7bc54b79ff3ff2e6",
+ "#sha1_metadata": "cb646cfed3d45105bd645ab38b2e9f7d8c436436",
+},
+
+{
+ "#url" : "https://komikcast.site/komik/090-eko-to-issho/",
+ "#category": ("", "komikcast", "manga"),
+ "#class" : komikcast.KomikcastMangaExtractor,
+ "#sha1_url" : "19d3d50d532e84be6280a3d61ff0fd0ca04dd6b4",
+ "#sha1_metadata": "837a7e96867344ff59d840771c04c20dc46c0ab1",
+},
+
+{
+ "#url" : "https://komikcast.me/tonari-no-kashiwagi-san/",
+ "#category": ("", "komikcast", "manga"),
+ "#class" : komikcast.KomikcastMangaExtractor,
+},
+
+)
diff --git a/test/results/konachan.py b/test/results/konachan.py
new file mode 100644
index 00000000..576acdaa
--- /dev/null
+++ b/test/results/konachan.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import moebooru
+
+
+__tests__ = (
+{
+ "#url" : "https://konachan.com/post/show/205189",
+ "#category": ("moebooru", "konachan", "post"),
+ "#class" : moebooru.MoebooruPostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_content": "674e75a753df82f5ad80803f575818b8e46e4b65",
+
+ "tags_artist" : "patata",
+ "tags_character": "clownpiece",
+ "tags_copyright": "touhou",
+ "tags_general" : str,
+},
+
+{
+ "#url" : "https://konachan.net/post/show/205189",
+ "#category": ("moebooru", "konachan", "post"),
+ "#class" : moebooru.MoebooruPostExtractor,
+},
+
+{
+ "#url" : "https://konachan.com/post?tags=patata",
+ "#category": ("moebooru", "konachan", "tag"),
+ "#class" : moebooru.MoebooruTagExtractor,
+ "#sha1_content": "838cfb815e31f48160855435655ddf7bfc4ecb8d",
+},
+
+{
+ "#url" : "https://konachan.com/post?tags=",
+ "#comment" : "empty 'tags' (#4354)",
+ "#category": ("moebooru", "konachan", "tag"),
+ "#class" : moebooru.MoebooruTagExtractor,
+},
+
+{
+ "#url" : "https://konachan.net/post?tags=patata",
+ "#category": ("moebooru", "konachan", "tag"),
+ "#class" : moebooru.MoebooruTagExtractor,
+},
+
+{
+ "#url" : "https://konachan.com/pool/show/95",
+ "#category": ("moebooru", "konachan", "pool"),
+ "#class" : moebooru.MoebooruPoolExtractor,
+ "#sha1_content": "cf0546e38a93c2c510a478f8744e60687b7a8426",
+},
+
+{
+ "#url" : "https://konachan.net/pool/show/95",
+ "#category": ("moebooru", "konachan", "pool"),
+ "#class" : moebooru.MoebooruPoolExtractor,
+},
+
+{
+ "#url" : "https://konachan.com/post/popular_by_month?month=11&year=2010",
+ "#category": ("moebooru", "konachan", "popular"),
+ "#class" : moebooru.MoebooruPopularExtractor,
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://konachan.com/post/popular_recent",
+ "#category": ("moebooru", "konachan", "popular"),
+ "#class" : moebooru.MoebooruPopularExtractor,
+},
+
+{
+ "#url" : "https://konachan.net/post/popular_recent",
+ "#category": ("moebooru", "konachan", "popular"),
+ "#class" : moebooru.MoebooruPopularExtractor,
+},
+
+)
diff --git a/test/results/lensdump.py b/test/results/lensdump.py
new file mode 100644
index 00000000..73f1fbdf
--- /dev/null
+++ b/test/results/lensdump.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lensdump
+
+
+__tests__ = (
+{
+ "#url" : "https://lensdump.com/a/1IhJr",
+ "#category": ("", "lensdump", "album"),
+ "#class" : lensdump.LensdumpAlbumExtractor,
+ "#pattern" : r"https://[abcd]\.l3n\.co/i/tq\w{4}\.png",
+
+ "extension": "png",
+ "name" : str,
+ "num" : int,
+ "title" : str,
+ "url" : str,
+ "width" : int,
+},
+
+{
+ "#url" : "https://lensdump.com/vstar925/albums",
+ "#category": ("", "lensdump", "albums"),
+ "#class" : lensdump.LensdumpAlbumsExtractor,
+},
+
+{
+ "#url" : "https://lensdump.com/i/tyoAyM",
+ "#category": ("", "lensdump", "image"),
+ "#class" : lensdump.LensdumpImageExtractor,
+ "#pattern" : r"https://c\.l3n\.co/i/tyoAyM\.webp",
+ "#sha1_content": "1aa749ed2c0cf679ec8e1df60068edaf3875de46",
+
+ "date" : "dt:2022-08-01 08:24:28",
+ "extension": "webp",
+ "filename" : "tyoAyM",
+ "height" : 400,
+ "id" : "tyoAyM",
+ "title" : "MYOBI clovis bookcaseset",
+ "url" : "https://c.l3n.co/i/tyoAyM.webp",
+ "width" : 620,
+},
+
+)
diff --git a/test/results/lesbianenergy.py b/test/results/lesbianenergy.py
new file mode 100644
index 00000000..fffe8a0c
--- /dev/null
+++ b/test/results/lesbianenergy.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import misskey
+
+
+__tests__ = (
+{
+ "#url" : "https://lesbian.energy/@rerorero",
+ "#category": ("misskey", "lesbian.energy", "user"),
+ "#class" : misskey.MisskeyUserExtractor,
+ "#pattern" : r"https://lesbian.energy/files/\w+",
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://lesbian.energy/@nano@mk.yopo.work",
+ "#category": ("misskey", "lesbian.energy", "user"),
+ "#class" : misskey.MisskeyUserExtractor,
+},
+
+{
+ "#url" : "https://lesbian.energy/notes/995ig09wqy",
+ "#category": ("misskey", "lesbian.energy", "note"),
+ "#class" : misskey.MisskeyNoteExtractor,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://lesbian.energy/notes/96ynd9w5kc",
+ "#category": ("misskey", "lesbian.energy", "note"),
+ "#class" : misskey.MisskeyNoteExtractor,
+},
+
+{
+ "#url" : "https://lesbian.energy/my/favorites",
+ "#category": ("misskey", "lesbian.energy", "favorite"),
+ "#class" : misskey.MisskeyFavoriteExtractor,
+},
+
+)
diff --git a/test/results/lexica.py b/test/results/lexica.py
new file mode 100644
index 00000000..07183f67
--- /dev/null
+++ b/test/results/lexica.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lexica
+
+
+__tests__ = (
+{
+ "#url" : "https://lexica.art/?q=tree",
+ "#category": ("", "lexica", "search"),
+ "#class" : lexica.LexicaSearchExtractor,
+ "#pattern" : r"https://lexica-serve-encoded-images2\.sharif\.workers.dev/full_jpg/[0-9a-f-]{36}$",
+ "#range" : "1-80",
+ "#count" : 80,
+
+ "height" : int,
+ "id" : str,
+ "upscaled_height": int,
+ "upscaled_width" : int,
+ "userid" : str,
+ "width" : int,
+ "prompt" : {
+ "c" : int,
+ "grid" : bool,
+ "height" : int,
+ "id" : str,
+ "images" : list,
+ "initImage" : None,
+ "initImageStrength": None,
+ "model" : "lexica-aperture-v2",
+ "negativePrompt" : str,
+ "prompt" : str,
+ "seed" : str,
+ "timestamp" : r"re:\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\dZ",
+ "width" : int,
+ },
+},
+
+)
diff --git a/test/results/lightroom.py b/test/results/lightroom.py
new file mode 100644
index 00000000..4c1a0532
--- /dev/null
+++ b/test/results/lightroom.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import lightroom
+
+
+__tests__ = (
+{
+ "#url" : "https://lightroom.adobe.com/shares/0c9cce2033f24d24975423fe616368bf",
+ "#category": ("", "lightroom", "gallery"),
+ "#class" : lightroom.LightroomGalleryExtractor,
+ "#count" : ">= 55",
+
+ "title": "Sterne und Nachtphotos",
+ "user" : "Christian Schrang",
+},
+
+{
+ "#url" : "https://lightroom.adobe.com/shares/7ba68ad5a97e48608d2e6c57e6082813",
+ "#category": ("", "lightroom", "gallery"),
+ "#class" : lightroom.LightroomGalleryExtractor,
+ "#count" : ">= 180",
+
+ "title": "HEBFC Snr/Res v Brighton",
+ "user" : "",
+},
+
+)
diff --git a/test/results/livedoor.py b/test/results/livedoor.py
new file mode 100644
index 00000000..7ab366f9
--- /dev/null
+++ b/test/results/livedoor.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import livedoor
+
+
+__tests__ = (
+{
+ "#url" : "http://blog.livedoor.jp/zatsu_ke/",
+ "#category": ("", "livedoor", "blog"),
+ "#class" : livedoor.LivedoorBlogExtractor,
+ "#pattern" : r"https?://livedoor.blogimg.jp/\w+/imgs/\w/\w/\w+\.\w+",
+ "#range" : "1-50",
+ "#count" : 50,
+ "#archive" : False,
+
+ "post" : {
+ "categories" : tuple,
+ "date" : "type:datetime",
+ "description": str,
+ "id" : int,
+ "tags" : list,
+ "title" : str,
+ "user" : "zatsu_ke",
+ },
+ "filename": str,
+ "hash" : r"re:\w{4,}",
+ "num" : int,
+},
+
+{
+ "#url" : "http://blog.livedoor.jp/uotapo/",
+ "#category": ("", "livedoor", "blog"),
+ "#class" : livedoor.LivedoorBlogExtractor,
+ "#range" : "1-5",
+ "#count" : 5,
+},
+
+{
+ "#url" : "http://blog.livedoor.jp/zatsu_ke/archives/51493859.html",
+ "#category": ("", "livedoor", "post"),
+ "#class" : livedoor.LivedoorPostExtractor,
+ "#sha1_url" : "9ca3bbba62722c8155be79ad7fc47be409e4a7a2",
+ "#sha1_metadata": "1f5b558492e0734f638b760f70bfc0b65c5a97b9",
+},
+
+{
+ "#url" : "http://blog.livedoor.jp/amaumauma/archives/7835811.html",
+ "#category": ("", "livedoor", "post"),
+ "#class" : livedoor.LivedoorPostExtractor,
+ "#sha1_url" : "204bbd6a9db4969c50e0923855aeede04f2e4a62",
+ "#sha1_metadata": "05821c7141360e6057ef2d382b046f28326a799d",
+},
+
+{
+ "#url" : "http://blog.livedoor.jp/uotapo/archives/1050616939.html",
+ "#category": ("", "livedoor", "post"),
+ "#class" : livedoor.LivedoorPostExtractor,
+ "#sha1_url" : "4b5ab144b7309eb870d9c08f8853d1abee9946d2",
+ "#sha1_metadata": "84fbf6e4eef16675013d6333039a7cfcb22c2d50",
+},
+
+)
diff --git a/test/results/lolibooru.py b/test/results/lolibooru.py
new file mode 100644
index 00000000..f8750269
--- /dev/null
+++ b/test/results/lolibooru.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import moebooru
+
+
+__tests__ = (
+{
+ "#url" : "https://lolibooru.moe/post/show/281305/",
+ "#category": ("moebooru", "lolibooru", "post"),
+ "#class" : moebooru.MoebooruPostExtractor,
+ "#options" : {"notes": True},
+ "#sha1_content": "a331430223ffc5b23c31649102e7d49f52489b57",
+
+ "notes": list,
+},
+
+{
+ "#url" : "https://lolibooru.moe/post/show/287835",
+ "#category": ("moebooru", "lolibooru", "post"),
+ "#class" : moebooru.MoebooruPostExtractor,
+},
+
+{
+ "#url" : "https://lolibooru.moe/post?tags=ruu_%28tksymkw%29",
+ "#category": ("moebooru", "lolibooru", "tag"),
+ "#class" : moebooru.MoebooruTagExtractor,
+},
+
+{
+ "#url" : "https://lolibooru.moe/pool/show/239",
+ "#category": ("moebooru", "lolibooru", "pool"),
+ "#class" : moebooru.MoebooruPoolExtractor,
+},
+
+{
+ "#url" : "https://lolibooru.moe/post/popular_recent",
+ "#category": ("moebooru", "lolibooru", "popular"),
+ "#class" : moebooru.MoebooruPopularExtractor,
+},
+
+)
diff --git a/test/results/loudbooru.py b/test/results/loudbooru.py
new file mode 100644
index 00000000..58236b7d
--- /dev/null
+++ b/test/results/loudbooru.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shimmie2
+
+
+__tests__ = (
+{
+ "#url" : "https://loudbooru.com/post/list/original_character/1",
+ "#category": ("shimmie2", "loudbooru", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+ "#pattern" : r"https://loudbooru\.com/_images/[0-9a-f]{32}/\d+",
+ "#range" : "1-100",
+ "#count" : 100,
+},
+
+{
+ "#url" : "https://loudbooru.com/post/view/33828",
+ "#category": ("shimmie2", "loudbooru", "post"),
+ "#class" : shimmie2.Shimmie2PostExtractor,
+ "#pattern" : r"https://loudbooru\.com/_images/.+\.png",
+ "#sha1_content": "a4755f787ba23ae2aa297a46810f802ca9032739",
+
+ "extension": "png",
+ "file_url" : "https://loudbooru.com/_images/ca2638d903c86e8337fe9aeb4974be88/33828%20-%202020%20artist%3Astikyfinkaz%20character%3Alisa_loud%20cover%20fanfiction%3Aplatz_eins%20frowning%20half-closed_eyes%20solo%20text%20title_card.png",
+ "filename" : "33828 - 2020 artist:stikyfinkaz character:lisa_loud cover fanfiction:platz_eins frowning half-closed_eyes solo text title_card",
+ "height" : 1920,
+ "id" : 33828,
+ "md5" : "ca2638d903c86e8337fe9aeb4974be88",
+ "tags" : "2020 artist:stikyfinkaz character:lisa_loud cover fanfiction:platz_eins frowning half-closed_eyes solo text title_card",
+ "width" : 1078,
+},
+
+)
diff --git a/test/results/loungeunderwear.py b/test/results/loungeunderwear.py
new file mode 100644
index 00000000..521de25c
--- /dev/null
+++ b/test/results/loungeunderwear.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://loungeunderwear.com/collections/apparel",
+ "#category": ("shopify", "loungeunderwear", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://de.loungeunderwear.com/products/ribbed-crop-top-black",
+ "#category": ("shopify", "loungeunderwear", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/luscious.py b/test/results/luscious.py
new file mode 100644
index 00000000..d5429612
--- /dev/null
+++ b/test/results/luscious.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import luscious
+import datetime
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://luscious.net/albums/okinami-no-koigokoro_277031/",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+ "#pattern" : r"https://storage\.bhs\.cloud\.ovh\.net/v1/AUTH_\w+/images/NTRshouldbeillegal/277031/luscious_net_\d+_\d+\.jpg$",
+
+ "album" : {
+ "__typename" : "Album",
+ "audiences" : list,
+ "content" : "Hentai",
+ "cover" : r"re:https://\w+.luscious.net/.+/277031/",
+ "created" : 1479625853,
+ "created_by" : "NTRshouldbeillegal",
+ "date" : "dt:2016-11-20 07:10:53",
+ "description" : "Enjoy.",
+ "download_url" : r"re:/download/(r/)?824778/277031/",
+ "genres" : list,
+ "id" : 277031,
+ "is_manga" : True,
+ "labels" : list,
+ "language" : "English",
+ "like_status" : "none",
+ "modified" : int,
+ "permissions" : list,
+ "rating" : float,
+ "slug" : "okinami-no-koigokoro",
+ "status" : None,
+ "tags" : list,
+ "title" : "Okinami no Koigokoro",
+ "url" : "/albums/okinami-no-koigokoro_277031/",
+ "marked_for_deletion" : False,
+ "marked_for_processing" : False,
+ "number_of_animated_pictures": 0,
+ "number_of_favorites" : int,
+ "number_of_pictures" : 18,
+ },
+ "aspect_ratio" : r"re:\d+:\d+",
+ "category" : "luscious",
+ "created" : int,
+ "date" : datetime.datetime,
+ "height" : int,
+ "id" : int,
+ "is_animated" : False,
+ "like_status" : "none",
+ "position" : int,
+ "resolution" : r"re:\d+x\d+",
+ "status" : None,
+ "tags" : list,
+ "thumbnail" : str,
+ "title" : str,
+ "width" : int,
+ "number_of_comments": int,
+ "number_of_favorites": int,
+},
+
+{
+ "#url" : "https://luscious.net/albums/not-found_277035/",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://members.luscious.net/albums/login-required_323871/",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+ "#count" : 64,
+},
+
+{
+ "#url" : "https://www.luscious.net/albums/okinami_277031/",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+},
+
+{
+ "#url" : "https://members.luscious.net/albums/okinami_277031/",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+},
+
+{
+ "#url" : "https://luscious.net/pictures/c/video_game_manga/album/okinami-no-koigokoro_277031/sorted/position/id/16528978/@_1",
+ "#category": ("", "luscious", "album"),
+ "#class" : luscious.LusciousAlbumExtractor,
+},
+
+{
+ "#url" : "https://members.luscious.net/albums/list/",
+ "#category": ("", "luscious", "search"),
+ "#class" : luscious.LusciousSearchExtractor,
+},
+
+{
+ "#url" : "https://members.luscious.net/albums/list/?display=date_newest&language_ids=%2B1&tagged=+full_color&page=1",
+ "#category": ("", "luscious", "search"),
+ "#class" : luscious.LusciousSearchExtractor,
+ "#pattern" : luscious.LusciousAlbumExtractor.pattern,
+ "#range" : "41-60",
+ "#count" : 20,
+},
+
+)
diff --git a/test/results/mangadex.py b/test/results/mangadex.py
new file mode 100644
index 00000000..c6a9e53a
--- /dev/null
+++ b/test/results/mangadex.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangadex
+from gallery_dl import exception
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://mangadex.org/chapter/f946ac53-0b71-4b5d-aeb2-7931b13c4aaa",
+ "#category": ("", "mangadex", "chapter"),
+ "#class" : mangadex.MangadexChapterExtractor,
+ "#sha1_metadata": "e86128a79ebe7201b648f1caa828496a2878dc8f",
+},
+
+{
+ "#url" : "https://mangadex.org/chapter/61a88817-9c29-4281-bdf1-77b3c1be9831",
+ "#comment" : "oneshot",
+ "#category": ("", "mangadex", "chapter"),
+ "#class" : mangadex.MangadexChapterExtractor,
+ "#count" : 64,
+ "#sha1_metadata": "d11ed057a919854696853362be35fc0ba7dded4c",
+},
+
+{
+ "#url" : "https://mangadex.org/chapter/74149a55-e7c4-44ea-8a37-98e879c1096f",
+ "#comment" : "MANGA Plus (#1154)",
+ "#category": ("", "mangadex", "chapter"),
+ "#class" : mangadex.MangadexChapterExtractor,
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://mangadex.org/chapter/364728a4-6909-4164-9eea-6b56354f7c78",
+ "#comment" : "'externalUrl', but still downloadable / 404 (#2503)",
+ "#category": ("", "mangadex", "chapter"),
+ "#class" : mangadex.MangadexChapterExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://mangadex.org/title/f90c4398-8aad-4f51-8a1f-024ca09fdcbc",
+ "#comment" : "mutliple values for 'lang' (#4093)",
+ "#category": ("", "mangadex", "manga"),
+ "#class" : mangadex.MangadexMangaExtractor,
+ "#count" : ">= 5",
+
+ "manga" : "Souten no Koumori",
+ "manga_id" : "f90c4398-8aad-4f51-8a1f-024ca09fdcbc",
+ "title" : r"re:One[Ss]hot",
+ "volume" : 0,
+ "chapter" : 0,
+ "chapter_minor": "",
+ "chapter_id" : str,
+ "date" : datetime.datetime,
+ "lang" : str,
+ "language" : str,
+ "artist" : ["Arakawa Hiromu"],
+ "author" : ["Arakawa Hiromu"],
+ "status" : "completed",
+ "tags" : [
+ "Oneshot",
+ "Historical",
+ "Action",
+ "Martial Arts",
+ "Drama",
+ "Tragedy",
+ ],
+},
+
+{
+ "#url" : "https://mangadex.org/title/f90c4398-8aad-4f51-8a1f-024ca09fdcbc",
+ "#comment" : "mutliple values for 'lang' (#4093)",
+ "#category": ("", "mangadex", "manga"),
+ "#class" : mangadex.MangadexMangaExtractor,
+ "#options" : {"lang": "fr,it"},
+ "#count" : 2,
+
+ "manga" : "Souten no Koumori",
+ "lang" : r"re:fr|it",
+ "language": r"re:French|Italian",
+},
+
+{
+ "#url" : "https://mangadex.cc/manga/d0c88e3b-ea64-4e07-9841-c1d2ac982f4a/",
+ "#category": ("", "mangadex", "manga"),
+ "#class" : mangadex.MangadexMangaExtractor,
+ "#options" : {"lang": "en"},
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://mangadex.org/title/7c1e2742-a086-4fd3-a3be-701fd6cf0be9",
+ "#category": ("", "mangadex", "manga"),
+ "#class" : mangadex.MangadexMangaExtractor,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://mangadex.org/title/584ef094-b2ab-40ce-962c-bce341fb9d10",
+ "#category": ("", "mangadex", "manga"),
+ "#class" : mangadex.MangadexMangaExtractor,
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "https://mangadex.org/title/feed",
+ "#category": ("", "mangadex", "feed"),
+ "#class" : mangadex.MangadexFeedExtractor,
+},
+
+)
diff --git a/test/results/mangafox.py b/test/results/mangafox.py
new file mode 100644
index 00000000..dc0cc9a0
--- /dev/null
+++ b/test/results/mangafox.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangafox
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "http://fanfox.net/manga/kidou_keisatsu_patlabor/v05/c006.2/1.html",
+ "#category": ("", "mangafox", "chapter"),
+ "#class" : mangafox.MangafoxChapterExtractor,
+ "#sha1_metadata": "5661dab258d42d09d98f194f7172fb9851a49766",
+ "#sha1_content" : "5c50c252dcf12ffecf68801f4db8a2167265f66c",
+},
+
+{
+ "#url" : "http://mangafox.me/manga/kidou_keisatsu_patlabor/v05/c006.2/",
+ "#category": ("", "mangafox", "chapter"),
+ "#class" : mangafox.MangafoxChapterExtractor,
+},
+
+{
+ "#url" : "http://fanfox.net/manga/black_clover/vTBD/c295/1.html",
+ "#category": ("", "mangafox", "chapter"),
+ "#class" : mangafox.MangafoxChapterExtractor,
+},
+
+{
+ "#url" : "https://fanfox.net/manga/kanojo_mo_kanojo",
+ "#category": ("", "mangafox", "manga"),
+ "#class" : mangafox.MangafoxMangaExtractor,
+ "#pattern" : mangafox.MangafoxChapterExtractor.pattern,
+ "#count" : ">=60",
+
+ "author" : "HIROYUKI",
+ "chapter" : int,
+ "chapter_minor" : r"re:^(\.\d+)?$",
+ "chapter_string": r"re:(v\d+/)?c\d+",
+ "date" : datetime.datetime,
+ "description" : "High school boy Naoya gets a confession from Momi, a cute and friendly girl. However, Naoya already has a girlfriend, Seki... but Momi is too good a catch to let go. Momi and Nagoya's goal becomes clear: convince Seki to accept being an item with the two of them. Will she budge?",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Kanojo mo Kanojo",
+ "tags" : [
+ "Comedy",
+ "Romance",
+ "School Life",
+ "Shounen",
+ ],
+ "volume" : int,
+},
+
+{
+ "#url" : "https://mangafox.me/manga/shangri_la_frontier",
+ "#category": ("", "mangafox", "manga"),
+ "#class" : mangafox.MangafoxMangaExtractor,
+ "#pattern" : mangafox.MangafoxChapterExtractor.pattern,
+ "#count" : ">=45",
+},
+
+{
+ "#url" : "https://m.fanfox.net/manga/sentai_daishikkaku",
+ "#category": ("", "mangafox", "manga"),
+ "#class" : mangafox.MangafoxMangaExtractor,
+},
+
+)
diff --git a/test/results/mangahere.py b/test/results/mangahere.py
new file mode 100644
index 00000000..db17a6b0
--- /dev/null
+++ b/test/results/mangahere.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangahere
+
+
+__tests__ = (
+{
+ "#url" : "https://www.mangahere.cc/manga/dongguo_xiaojie/c004.2/",
+ "#category": ("", "mangahere", "chapter"),
+ "#class" : mangahere.MangahereChapterExtractor,
+ "#sha1_metadata": "7c98d7b50a47e6757b089aa875a53aa970cac66f",
+ "#sha1_content" : "708d475f06893b88549cbd30df1e3f9428f2c884",
+},
+
+{
+ "#url" : "https://www.mangahere.cc/manga/beastars/c196/1.html",
+ "#comment" : "URLs without HTTP scheme (#1070)",
+ "#category": ("", "mangahere", "chapter"),
+ "#class" : mangahere.MangahereChapterExtractor,
+ "#pattern" : "https://zjcdn.mangahere.org/.*",
+},
+
+{
+ "#url" : "http://www.mangahere.co/manga/dongguo_xiaojie/c003.2/",
+ "#category": ("", "mangahere", "chapter"),
+ "#class" : mangahere.MangahereChapterExtractor,
+},
+
+{
+ "#url" : "http://m.mangahere.co/manga/dongguo_xiaojie/c003.2/",
+ "#category": ("", "mangahere", "chapter"),
+ "#class" : mangahere.MangahereChapterExtractor,
+},
+
+{
+ "#url" : "https://www.mangahere.cc/manga/aria/",
+ "#category": ("", "mangahere", "manga"),
+ "#class" : mangahere.MangahereMangaExtractor,
+ "#count" : 71,
+ "#sha1_url" : "9c2e54ec42e9a87ad53096c328b33c90750af3e4",
+ "#sha1_metadata": "71503c682c5d0c277a50409a8c5fd78e871e3d69",
+},
+
+{
+ "#url" : "https://www.mangahere.cc/manga/hiyokoi/#50",
+ "#category": ("", "mangahere", "manga"),
+ "#class" : mangahere.MangahereMangaExtractor,
+ "#sha1_url" : "654850570aa03825cd57e2ae2904af489602c523",
+ "#sha1_metadata": "c8084d89a9ea6cf40353093669f9601a39bf5ca2",
+},
+
+{
+ "#url" : "http://www.mangahere.cc/manga/gunnm_mars_chronicle/",
+ "#comment" : "adult filter (#556)",
+ "#category": ("", "mangahere", "manga"),
+ "#class" : mangahere.MangahereMangaExtractor,
+ "#pattern" : mangahere.MangahereChapterExtractor.pattern,
+ "#count" : ">= 50",
+},
+
+{
+ "#url" : "https://www.mangahere.co/manga/aria/",
+ "#category": ("", "mangahere", "manga"),
+ "#class" : mangahere.MangahereMangaExtractor,
+},
+
+{
+ "#url" : "https://m.mangahere.co/manga/aria/",
+ "#category": ("", "mangahere", "manga"),
+ "#class" : mangahere.MangahereMangaExtractor,
+},
+
+)
diff --git a/test/results/mangakakalot.py b/test/results/mangakakalot.py
new file mode 100644
index 00000000..b0b8bada
--- /dev/null
+++ b/test/results/mangakakalot.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangakakalot
+
+
+__tests__ = (
+{
+ "#url" : "https://ww3.mangakakalot.tv/chapter/manga-jk986845/chapter-34.2",
+ "#category": ("", "mangakakalot", "chapter"),
+ "#class" : mangakakalot.MangakakalotChapterExtractor,
+ "#pattern" : r"https://cm\.blazefast\.co/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{32}\.jpg",
+ "#count" : 9,
+ "#sha1_metadata": "0f1586ff52f0f9cbbb25306ae64ab718f8a6a633",
+},
+
+{
+ "#url" : "https://mangakakalot.tv/chapter/hatarakanai_futari_the_jobless_siblings/chapter_20.1",
+ "#category": ("", "mangakakalot", "chapter"),
+ "#class" : mangakakalot.MangakakalotChapterExtractor,
+},
+
+{
+ "#url" : "https://ww3.mangakakalot.tv/manga/manga-jk986845",
+ "#category": ("", "mangakakalot", "manga"),
+ "#class" : mangakakalot.MangakakalotMangaExtractor,
+ "#pattern" : mangakakalot.MangakakalotChapterExtractor.pattern,
+ "#count" : ">= 30",
+},
+
+{
+ "#url" : "https://mangakakalot.tv/manga/lk921810",
+ "#category": ("", "mangakakalot", "manga"),
+ "#class" : mangakakalot.MangakakalotMangaExtractor,
+},
+
+)
diff --git a/test/results/mangalife.py b/test/results/mangalife.py
new file mode 100644
index 00000000..80226afe
--- /dev/null
+++ b/test/results/mangalife.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangasee
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://manga4life.com/read-online/One-Piece-chapter-1063-page-1.html",
+ "#category": ("", "mangalife", "chapter"),
+ "#class" : mangasee.MangaseeChapterExtractor,
+ "#pattern" : r"https://[^/]+/manga/One-Piece/1063-0\d\d\.png",
+ "#count" : 13,
+
+ "author" : ["ODA Eiichiro"],
+ "chapter" : 1063,
+ "chapter_minor" : "",
+ "chapter_string": "110630",
+ "count" : 13,
+ "date" : "dt:2022-10-16 17:32:54",
+ "extension" : "png",
+ "filename" : r"re:1063-0\d\d",
+ "genre" : [
+ "Action",
+ "Adventure",
+ "Comedy",
+ "Drama",
+ "Fantasy",
+ "Shounen",
+ ],
+ "index" : "1",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "One Piece",
+ "page" : int,
+ "title" : "",
+},
+
+{
+ "#url" : "https://manga4life.com/manga/Ano-Musume-Ni-Kiss-To-Shirayuri-O",
+ "#category": ("", "mangalife", "manga"),
+ "#class" : mangasee.MangaseeMangaExtractor,
+ "#pattern" : mangasee.MangaseeChapterExtractor.pattern,
+ "#count" : ">= 50",
+
+ "author" : ["Canno"],
+ "chapter" : int,
+ "chapter_minor" : r"re:^|\.5$",
+ "chapter_string": r"re:100\d\d\d",
+ "date" : datetime.datetime,
+ "genre" : [
+ "Comedy",
+ "Romance",
+ "School Life",
+ "Seinen",
+ "Shoujo Ai",
+ ],
+ "index" : "1",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Ano-Musume-Ni-Kiss-To-Shirayuri-O",
+ "title" : "",
+},
+
+)
diff --git a/test/results/manganelo.py b/test/results/manganelo.py
new file mode 100644
index 00000000..b5772656
--- /dev/null
+++ b/test/results/manganelo.py
@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import manganelo
+
+
+__tests__ = (
+{
+ "#url" : "https://chapmanganato.com/manga-gn983696/chapter-23",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+ "#pattern" : r"https://v\d+\.mkklcdnv6tempv5\.com/img/tab_17/03/23/39/gn983696/vol_3_chapter_23_24_yen/\d+-[no]\.jpg",
+ "#count" : 25,
+ "#sha1_metadata": "17faaea7f0fb8c2675a327bf3aa0bcd7a6311d68",
+},
+
+{
+ "#url" : "https://chapmanganelo.com/manga-ti107776/chapter-4",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+ "#pattern" : r"https://v\d+\.mkklcdnv6tempv5\.com/img/tab_17/01/92/08/ti970565/chapter_4_caster/\d+-o\.jpg",
+ "#count" : 45,
+ "#sha1_metadata": "06e01fa9b3fc9b5b954c0d4a98f0153b40922ded",
+},
+
+{
+ "#url" : "https://chapmanganato.com/manga-no991297/chapter-8",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+ "#count" : 20,
+
+ "chapter" : 8,
+ "chapter_minor": "-1",
+},
+
+{
+ "#url" : "https://readmanganato.com/manga-gn983696/chapter-23",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+},
+
+{
+ "#url" : "https://manganelo.com/chapter/gamers/chapter_15",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+},
+
+{
+ "#url" : "https://manganelo.com/chapter/gq921227/chapter_23",
+ "#category": ("", "manganelo", "chapter"),
+ "#class" : manganelo.ManganeloChapterExtractor,
+},
+
+{
+ "#url" : "https://chapmanganato.com/manga-gn983696",
+ "#category": ("", "manganelo", "manga"),
+ "#class" : manganelo.ManganeloMangaExtractor,
+ "#pattern" : manganelo.ManganeloChapterExtractor.pattern,
+ "#count" : ">= 25",
+},
+
+{
+ "#url" : "https://m.manganelo.com/manga-ti107776",
+ "#category": ("", "manganelo", "manga"),
+ "#class" : manganelo.ManganeloMangaExtractor,
+ "#pattern" : manganelo.ManganeloChapterExtractor.pattern,
+ "#count" : ">= 12",
+},
+
+{
+ "#url" : "https://readmanganato.com/manga-gn983696",
+ "#category": ("", "manganelo", "manga"),
+ "#class" : manganelo.ManganeloMangaExtractor,
+},
+
+{
+ "#url" : "https://manganelo.com/manga/read_otome_no_teikoku",
+ "#category": ("", "manganelo", "manga"),
+ "#class" : manganelo.ManganeloMangaExtractor,
+},
+
+{
+ "#url" : "https://manganelo.com/manga/ol921234/",
+ "#category": ("", "manganelo", "manga"),
+ "#class" : manganelo.ManganeloMangaExtractor,
+},
+
+)
diff --git a/test/results/mangapark.py b/test/results/mangapark.py
new file mode 100644
index 00000000..432f535f
--- /dev/null
+++ b/test/results/mangapark.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangapark
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://mangapark.net/title/114972-aria/6710214-en-ch.60.2",
+ "#category": ("", "mangapark", "chapter"),
+ "#class" : mangapark.MangaparkChapterExtractor,
+ "#pattern" : r"https://[\w-]+\.mpcdn\.org/comic/2002/e67/61e29278a583b9227964076e/\d+_\d+_\d+_\d+\.jpeg\?acc=[^]+&exp=\d+",
+ "#count" : 70,
+
+ "artist" : [],
+ "author" : ["Amano Kozue"],
+ "chapter" : 60,
+ "chapter_id" : 6710214,
+ "chapter_minor": ".2",
+ "count" : 70,
+ "date" : "dt:2022-01-15 09:25:03",
+ "extension" : "jpeg",
+ "filename" : str,
+ "genre" : [
+ "adventure",
+ "comedy",
+ "drama",
+ "sci_fi",
+ "shounen",
+ "slice_of_life",
+ ],
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Aria",
+ "manga_id" : 114972,
+ "page" : int,
+ "source" : "Koala",
+ "title" : "Special Navigation - Aquaria Ii",
+ "volume" : 12,
+},
+
+{
+ "#url" : "https://mangapark.com/title/114972-aria/6710214-en-ch.60.2",
+ "#category": ("", "mangapark", "chapter"),
+ "#class" : mangapark.MangaparkChapterExtractor,
+},
+
+{
+ "#url" : "https://mangapark.org/title/114972-aria/6710214-en-ch.60.2",
+ "#category": ("", "mangapark", "chapter"),
+ "#class" : mangapark.MangaparkChapterExtractor,
+},
+
+{
+ "#url" : "https://mangapark.io/title/114972-aria/6710214-en-ch.60.2",
+ "#category": ("", "mangapark", "chapter"),
+ "#class" : mangapark.MangaparkChapterExtractor,
+},
+
+{
+ "#url" : "https://mangapark.me/title/114972-aria/6710214-en-ch.60.2",
+ "#category": ("", "mangapark", "chapter"),
+ "#class" : mangapark.MangaparkChapterExtractor,
+},
+
+{
+ "#url" : "https://mangapark.net/title/114972-aria",
+ "#comment" : "'source' option",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+ "#pattern" : mangapark.MangaparkChapterExtractor.pattern,
+ "#count" : 141,
+
+ "chapter" : int,
+ "chapter_id" : int,
+ "chapter_minor": str,
+ "date" : datetime.datetime,
+ "lang" : "en",
+ "language" : "English",
+ "manga_id" : 114972,
+ "source" : r"re:Horse|Koala",
+ "source_id" : int,
+ "title" : str,
+ "volume" : int,
+},
+
+{
+ "#url" : "https://mangapark.net/title/114972-aria",
+ "#comment" : "'source' option",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+ "#options" : {"source": "koala"},
+ "#pattern" : mangapark.MangaparkChapterExtractor.pattern,
+ "#count" : 70,
+
+ "source" : "Koala",
+ "source_id": 15150116,
+},
+
+{
+ "#url" : "https://mangapark.com/title/114972-",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+{
+ "#url" : "https://mangapark.com/title/114972",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+{
+ "#url" : "https://mangapark.com/title/114972-aria",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+{
+ "#url" : "https://mangapark.org/title/114972-aria",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+{
+ "#url" : "https://mangapark.io/title/114972-aria",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+{
+ "#url" : "https://mangapark.me/title/114972-aria",
+ "#category": ("", "mangapark", "manga"),
+ "#class" : mangapark.MangaparkMangaExtractor,
+},
+
+)
diff --git a/test/results/mangaread.py b/test/results/mangaread.py
new file mode 100644
index 00000000..40fe4e21
--- /dev/null
+++ b/test/results/mangaread.py
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangaread
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.mangaread.org/manga/one-piece/chapter-1053-3/",
+ "#category": ("", "mangaread", "chapter"),
+ "#class" : mangaread.MangareadChapterExtractor,
+ "#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
+ "#count" : 11,
+
+ "manga" : "One Piece",
+ "title" : "",
+ "chapter" : 1053,
+ "chapter_minor": ".3",
+ "tags" : ["Oda Eiichiro"],
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/one-piece/chapter-1000000/",
+ "#category": ("", "mangaread", "chapter"),
+ "#class" : mangaread.MangareadChapterExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/kanan-sama-wa-akumade-choroi/chapter-10/",
+ "#category": ("", "mangaread", "chapter"),
+ "#class" : mangaread.MangareadChapterExtractor,
+ "#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
+ "#count" : 9,
+
+ "manga" : "Kanan-sama wa Akumade Choroi",
+ "title" : "",
+ "chapter" : 10,
+ "chapter_minor": "",
+ "tags" : list,
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/above-all-gods/chapter146-5/",
+ "#comment" : "^^ no whitespace",
+ "#category": ("", "mangaread", "chapter"),
+ "#class" : mangaread.MangareadChapterExtractor,
+ "#pattern" : r"https://www\.mangaread\.org/wp-content/uploads/WP-manga/data/manga_[^/]+/[^/]+/[^.]+\.\w+",
+ "#count" : 6,
+
+ "manga" : "Above All Gods",
+ "title" : "",
+ "chapter" : 146,
+ "chapter_minor": ".5",
+ "tags" : list,
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/kanan-sama-wa-akumade-choroi",
+ "#category": ("", "mangaread", "manga"),
+ "#class" : mangaread.MangareadMangaExtractor,
+ "#pattern" : r"https://www\.mangaread\.org/manga/kanan-sama-wa-akumade-choroi/chapter-\d+(-.+)?/",
+ "#count" : ">= 13",
+
+ "manga" : "Kanan-sama wa Akumade Choroi",
+ "author" : ["nonco"],
+ "artist" : ["nonco"],
+ "type" : "Manga",
+ "genres" : [
+ "Comedy",
+ "Romance",
+ "Shounen",
+ "Supernatural",
+ ],
+ "rating" : float,
+ "release" : 2022,
+ "status" : "OnGoing",
+ "lang" : "en",
+ "language" : "English",
+ "manga_alt" : list,
+ "description": str,
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/one-piece",
+ "#category": ("", "mangaread", "manga"),
+ "#class" : mangaread.MangareadMangaExtractor,
+ "#pattern" : r"https://www\.mangaread\.org/manga/one-piece/chapter-\d+(-.+)?/",
+ "#count" : ">= 1066",
+
+ "manga" : "One Piece",
+ "author" : ["Oda Eiichiro"],
+ "artist" : ["Oda Eiichiro"],
+ "type" : "Manga",
+ "genres" : list,
+ "rating" : float,
+ "release" : 1997,
+ "status" : "OnGoing",
+ "lang" : "en",
+ "language" : "English",
+ "manga_alt" : ["One Piece"],
+ "description": str,
+},
+
+{
+ "#url" : "https://www.mangaread.org/manga/doesnotexist",
+ "#category": ("", "mangaread", "manga"),
+ "#class" : mangaread.MangareadMangaExtractor,
+ "#exception": exception.HttpError,
+},
+
+)
diff --git a/test/results/mangasee.py b/test/results/mangasee.py
new file mode 100644
index 00000000..8cf51d4e
--- /dev/null
+++ b/test/results/mangasee.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangasee
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://mangasee123.com/read-online/Tokyo-Innocent-chapter-4.5-page-1.html",
+ "#category": ("", "mangasee", "chapter"),
+ "#class" : mangasee.MangaseeChapterExtractor,
+ "#pattern" : r"https://[^/]+/manga/Tokyo-Innocent/0004\.5-00\d\.png",
+ "#count" : 8,
+
+ "author" : ["NARUMI Naru"],
+ "chapter" : 4,
+ "chapter_minor" : ".5",
+ "chapter_string": "100045",
+ "count" : 8,
+ "date" : "dt:2020-01-20 21:52:53",
+ "extension" : "png",
+ "filename" : r"re:0004\.5-00\d",
+ "genre" : [
+ "Comedy",
+ "Fantasy",
+ "Harem",
+ "Romance",
+ "Shounen",
+ "Supernatural",
+ ],
+ "index" : "1",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Tokyo Innocent",
+ "page" : int,
+ "title" : "",
+},
+
+{
+ "#url" : "https://mangasee123.com/manga/Nakamura-Koedo-To-Daizu-Keisuke-Wa-Umaku-Ikanai",
+ "#category": ("", "mangasee", "manga"),
+ "#class" : mangasee.MangaseeMangaExtractor,
+ "#pattern" : mangasee.MangaseeChapterExtractor.pattern,
+ "#count" : ">= 17",
+
+ "author" : ["TAKASE Masaya"],
+ "chapter" : int,
+ "chapter_minor" : r"re:^|\.5$",
+ "chapter_string": r"re:100\d\d\d",
+ "date" : datetime.datetime,
+ "genre" : [
+ "Comedy",
+ "Romance",
+ "School Life",
+ "Shounen",
+ "Slice of Life",
+ ],
+ "index" : "1",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "Nakamura-Koedo-To-Daizu-Keisuke-Wa-Umaku-Ikanai",
+ "title" : "",
+},
+
+)
diff --git a/test/results/mangoxo.py b/test/results/mangoxo.py
new file mode 100644
index 00000000..b7c392a4
--- /dev/null
+++ b/test/results/mangoxo.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mangoxo
+
+
+__tests__ = (
+{
+ "#url" : "https://www.mangoxo.com/album/lzVOv1Q9",
+ "#category": ("", "mangoxo", "album"),
+ "#class" : mangoxo.MangoxoAlbumExtractor,
+ "#sha1_url": "ad921fe62663b06e7d73997f7d00646cab7bdd0d",
+
+ "channel": {
+ "id" : "gaxO16d8",
+ "name" : "Phoenix",
+ "cover": str,
+ },
+ "album" : {
+ "id" : "lzVOv1Q9",
+ "name" : r"re:池永康晟 Ikenaga Yasunari 透出古朴",
+ "date" : "dt:2019-03-22 14:42:00",
+ "description": str,
+ },
+ "id" : int,
+ "num" : int,
+ "count" : 65,
+},
+
+{
+ "#url" : "https://www.mangoxo.com/phoenix/album",
+ "#category": ("", "mangoxo", "channel"),
+ "#class" : mangoxo.MangoxoChannelExtractor,
+ "#pattern" : mangoxo.MangoxoAlbumExtractor.pattern,
+ "#range" : "1-30",
+ "#count" : "> 20",
+},
+
+)
diff --git a/test/results/mastodonsocial.py b/test/results/mastodonsocial.py
new file mode 100644
index 00000000..a7001fd0
--- /dev/null
+++ b/test/results/mastodonsocial.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mastodon
+
+
+__tests__ = (
+{
+ "#url" : "https://mastodon.social/@jk",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+ "#pattern" : r"https://files.mastodon.social/media_attachments/files/(\d+/){3,}original/\w+",
+ "#range" : "1-60",
+ "#count" : 60,
+},
+
+{
+ "#url" : "https://mastodon.social/@yoru_nine@pawoo.net",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+ "#pattern" : r"https://mastodon\.social/media_proxy/\d+/original",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://mastodon.social/@id:10843",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/users/id:10843",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/users/jk",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/users/yoru_nine@pawoo.net",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/web/@jk",
+ "#category": ("mastodon", "mastodon.social", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/bookmarks",
+ "#category": ("mastodon", "mastodon.social", "bookmark"),
+ "#class" : mastodon.MastodonBookmarkExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/users/0x4f/following",
+ "#category": ("mastodon", "mastodon.social", "following"),
+ "#class" : mastodon.MastodonFollowingExtractor,
+ "#count" : ">= 20",
+ "#extractor": False,
+},
+
+{
+ "#url" : "https://mastodon.social/users/id:10843/following",
+ "#category": ("mastodon", "mastodon.social", "following"),
+ "#class" : mastodon.MastodonFollowingExtractor,
+},
+
+{
+ "#url" : "https://mastodon.social/@jk/103794036899778366",
+ "#category": ("mastodon", "mastodon.social", "status"),
+ "#class" : mastodon.MastodonStatusExtractor,
+ "#count" : 4,
+
+ "count": 4,
+ "num" : int,
+},
+
+)
diff --git a/test/results/mememuseum.py b/test/results/mememuseum.py
new file mode 100644
index 00000000..6a93d3f2
--- /dev/null
+++ b/test/results/mememuseum.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shimmie2
+
+
+__tests__ = (
+{
+ "#url" : "https://meme.museum/post/list/animated/1",
+ "#category": ("shimmie2", "mememuseum", "tag"),
+ "#class" : shimmie2.Shimmie2TagExtractor,
+ "#pattern" : r"https://meme\.museum/_images/\w+/\d+%20-%20",
+ "#count" : ">= 30",
+},
+
+{
+ "#url" : "https://meme.museum/post/view/10243",
+ "#category": ("shimmie2", "mememuseum", "post"),
+ "#class" : shimmie2.Shimmie2PostExtractor,
+ "#pattern" : r"https://meme\.museum/_images/105febebcd5ca791ee332adc49971f78/10243%20-%20g%20beard%20open_source%20richard_stallman%20stallman%20tagme%20text\.jpg",
+ "#sha1_content": "45565f3f141fc960a8ae1168b80e718a494c52d2",
+
+ "extension" : "jpg",
+ "file_url" : "https://meme.museum/_images/105febebcd5ca791ee332adc49971f78/10243%20-%20g%20beard%20open_source%20richard_stallman%20stallman%20tagme%20text.jpg",
+ "filename" : "10243 - g beard open_source richard_stallman stallman tagme text",
+ "height" : 451,
+ "id" : 10243,
+ "md5" : "105febebcd5ca791ee332adc49971f78",
+ "size" : 0,
+ "subcategory": "post",
+ "tags" : "/g/ beard open_source richard_stallman stallman tagme text",
+ "width" : 480,
+},
+
+)
diff --git a/test/results/michaelscameras.py b/test/results/michaelscameras.py
new file mode 100644
index 00000000..42c76bbc
--- /dev/null
+++ b/test/results/michaelscameras.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://michaels.com.au/collections/microphones",
+ "#category": ("shopify", "michaelscameras", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://michaels.com.au/collections/audio/products/boya-by-wm4-pro-k5-2-4ghz-mic-android-1-1-101281",
+ "#category": ("shopify", "michaelscameras", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/misskeyio.py b/test/results/misskeyio.py
new file mode 100644
index 00000000..3a28ae87
--- /dev/null
+++ b/test/results/misskeyio.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import misskey
+
+
+__tests__ = (
+{
+ "#url" : "https://misskey.io/@lithla",
+ "#category": ("misskey", "misskey.io", "user"),
+ "#class" : misskey.MisskeyUserExtractor,
+ "#pattern" : r"https://s\d+\.arkjp\.net/misskey/[\w-]+\.\w+",
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://misskey.io/@blooddj@pawoo.net",
+ "#category": ("misskey", "misskey.io", "user"),
+ "#class" : misskey.MisskeyUserExtractor,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://misskey.io/@blooddj@pawoo.net/following",
+ "#category": ("misskey", "misskey.io", "following"),
+ "#class" : misskey.MisskeyFollowingExtractor,
+ "#count" : ">= 6",
+ "#extractor": False,
+},
+
+{
+ "#url" : "https://misskey.io/notes/9bhqfo835v",
+ "#category": ("misskey", "misskey.io", "note"),
+ "#class" : misskey.MisskeyNoteExtractor,
+ "#pattern" : r"https://s\d+\.arkjp\.net/misskey/[\w-]+\.\w+",
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://misskey.io/notes/9brq7z1re6",
+ "#category": ("misskey", "misskey.io", "note"),
+ "#class" : misskey.MisskeyNoteExtractor,
+},
+
+{
+ "#url" : "https://misskey.io/my/favorites",
+ "#category": ("misskey", "misskey.io", "favorite"),
+ "#class" : misskey.MisskeyFavoriteExtractor,
+},
+
+{
+ "#url" : "https://misskey.io/api/i/favorites",
+ "#category": ("misskey", "misskey.io", "favorite"),
+ "#class" : misskey.MisskeyFavoriteExtractor,
+},
+
+)
diff --git a/test/results/modcloth.py b/test/results/modcloth.py
new file mode 100644
index 00000000..67ad082e
--- /dev/null
+++ b/test/results/modcloth.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://modcloth.com/collections/shoes",
+ "#category": ("shopify", "modcloth", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://modcloth.com/collections/shoes/products/heidii-brn",
+ "#category": ("shopify", "modcloth", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/myhentaigallery.py b/test/results/myhentaigallery.py
new file mode 100644
index 00000000..6ddc2c2f
--- /dev/null
+++ b/test/results/myhentaigallery.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import myhentaigallery
+
+
+__tests__ = (
+{
+ "#url" : "https://myhentaigallery.com/gallery/thumbnails/16247",
+ "#category": ("", "myhentaigallery", "gallery"),
+ "#class" : myhentaigallery.MyhentaigalleryGalleryExtractor,
+ "#pattern" : r"https://images.myhentaicomics\.com/imagesgallery/images/[^/]+/original/\d+\.jpg",
+
+ "artist" : list,
+ "count" : 11,
+ "gallery_id": 16247,
+ "group" : list,
+ "parodies" : list,
+ "tags" : ["Giantess"],
+ "title" : "Attack Of The 50ft Woman 1",
+},
+
+{
+ "#url" : "https://myhentaigallery.com/gallery/show/16247/1",
+ "#category": ("", "myhentaigallery", "gallery"),
+ "#class" : myhentaigallery.MyhentaigalleryGalleryExtractor,
+},
+
+)
diff --git a/test/results/myportfolio.py b/test/results/myportfolio.py
new file mode 100644
index 00000000..71851293
--- /dev/null
+++ b/test/results/myportfolio.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import myportfolio
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://andrewling.myportfolio.com/volvo-xc-90-hybrid",
+ "#category": ("", "myportfolio", "gallery"),
+ "#class" : myportfolio.MyportfolioGalleryExtractor,
+ "#sha1_url" : "acea0690c76db0e5cf267648cefd86e921bc3499",
+ "#sha1_metadata": "6ac6befe2ee0af921d24cf1dd4a4ed71be06db6d",
+},
+
+{
+ "#url" : "https://andrewling.myportfolio.com/",
+ "#category": ("", "myportfolio", "gallery"),
+ "#class" : myportfolio.MyportfolioGalleryExtractor,
+ "#pattern" : r"https://andrewling\.myportfolio\.com/[^/?#+]+$",
+ "#count" : ">= 6",
+},
+
+{
+ "#url" : "https://stevenilousphotography.myportfolio.com/society",
+ "#category": ("", "myportfolio", "gallery"),
+ "#class" : myportfolio.MyportfolioGalleryExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "myportfolio:https://tooco.com.ar/6-of-diamonds-paradise-bird",
+ "#comment" : "custom domain",
+ "#category": ("", "myportfolio", "gallery"),
+ "#class" : myportfolio.MyportfolioGalleryExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "myportfolio:https://tooco.com.ar/",
+ "#category": ("", "myportfolio", "gallery"),
+ "#class" : myportfolio.MyportfolioGalleryExtractor,
+ "#pattern" : myportfolio.MyportfolioGalleryExtractor.pattern,
+ "#count" : ">= 40",
+},
+
+)
diff --git a/test/results/naver.py b/test/results/naver.py
new file mode 100644
index 00000000..81d18efd
--- /dev/null
+++ b/test/results/naver.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import naver
+
+
+__tests__ = (
+{
+ "#url" : "https://blog.naver.com/rlfqjxm0/221430673006",
+ "#category": ("", "naver", "post"),
+ "#class" : naver.NaverPostExtractor,
+ "#sha1_url" : "6c694f3aced075ed5e9511f1e796d14cb26619cc",
+ "#sha1_metadata": "a6e23d19afbee86b37d6e7ad934650c379d2cb1e",
+},
+
+{
+ "#url" : "https://blog.naver.com/PostView.nhn?blogId=rlfqjxm0&logNo=221430673006",
+ "#category": ("", "naver", "post"),
+ "#class" : naver.NaverPostExtractor,
+ "#sha1_url" : "6c694f3aced075ed5e9511f1e796d14cb26619cc",
+ "#sha1_metadata": "a6e23d19afbee86b37d6e7ad934650c379d2cb1e",
+},
+
+{
+ "#url" : "https://blog.naver.com/gukjung",
+ "#category": ("", "naver", "blog"),
+ "#class" : naver.NaverBlogExtractor,
+ "#pattern" : naver.NaverPostExtractor.pattern,
+ "#range" : "1-12",
+ "#count" : 12,
+},
+
+{
+ "#url" : "https://blog.naver.com/PostList.nhn?blogId=gukjung",
+ "#category": ("", "naver", "blog"),
+ "#class" : naver.NaverBlogExtractor,
+ "#pattern" : naver.NaverPostExtractor.pattern,
+ "#range" : "1-12",
+ "#count" : 12,
+},
+
+)
diff --git a/test/results/naverwebtoon.py b/test/results/naverwebtoon.py
new file mode 100644
index 00000000..889e5bce
--- /dev/null
+++ b/test/results/naverwebtoon.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import naverwebtoon
+
+
+__tests__ = (
+{
+ "#url" : "https://comic.naver.com/webtoon/detail?titleId=26458&no=1&weekday=tue",
+ "#category": ("", "naverwebtoon", "episode"),
+ "#class" : naverwebtoon.NaverwebtoonEpisodeExtractor,
+ "#count" : 14,
+ "#sha1_url" : "47a956ba8c7a837213d5985f50c569fcff986f75",
+ "#sha1_content": "3806b6e8befbb1920048de9888dfce6220f69a60",
+
+ "author" : ["김규삼"],
+ "artist" : ["김규삼"],
+ "comic" : "N의등대-눈의등대",
+ "count" : 14,
+ "episode" : "1",
+ "extension": "jpg",
+ "num" : int,
+ "tags" : [
+ "스릴러",
+ "완결무료",
+ "완결스릴러",
+ ],
+ "title" : "n의 등대 - 눈의 등대 1화",
+ "title_id" : "26458",
+},
+
+{
+ "#url" : "https://comic.naver.com/challenge/detail?titleId=765124&no=1",
+ "#category": ("", "naverwebtoon", "episode"),
+ "#class" : naverwebtoon.NaverwebtoonEpisodeExtractor,
+ "#pattern" : r"https://image-comic\.pstatic\.net/user_contents_data/challenge_comic/2021/01/19/342586/upload_7149856273586337846\.jpeg",
+ "#count" : 1,
+
+ "author" : ["kemi****"],
+ "artist" : [],
+ "comic" : "우니 모두의 이야기",
+ "count" : 1,
+ "episode" : "1",
+ "extension": "jpeg",
+ "filename" : "upload_7149856273586337846",
+ "num" : 1,
+ "tags" : [
+ "일상툰",
+ "우니모두의이야기",
+ "퇴사",
+ "입사",
+ "신입사원",
+ "사회초년생",
+ "회사원",
+ "20대",
+ ],
+ "title" : "퇴사하다",
+ "title_id" : "765124",
+},
+
+{
+ "#url" : "https://comic.naver.com/bestChallenge/detail.nhn?titleId=771467&no=3",
+ "#category": ("", "naverwebtoon", "episode"),
+ "#class" : naverwebtoon.NaverwebtoonEpisodeExtractor,
+ "#pattern" : r"https://image-comic\.pstatic\.net/user_contents_data/challenge_comic/2021/04/28/345534/upload_3617293622396203109\.jpeg",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://comic.naver.com/webtoon/list?titleId=22073",
+ "#category": ("", "naverwebtoon", "comic"),
+ "#class" : naverwebtoon.NaverwebtoonComicExtractor,
+ "#pattern" : naverwebtoon.NaverwebtoonEpisodeExtractor.pattern,
+ "#count" : 32,
+},
+
+{
+ "#url" : "https://comic.naver.com/challenge/list?titleId=765124",
+ "#category": ("", "naverwebtoon", "comic"),
+ "#class" : naverwebtoon.NaverwebtoonComicExtractor,
+ "#pattern" : naverwebtoon.NaverwebtoonEpisodeExtractor.pattern,
+ "#count" : 25,
+},
+
+{
+ "#url" : "https://comic.naver.com/bestChallenge/list.nhn?titleId=789786",
+ "#category": ("", "naverwebtoon", "comic"),
+ "#class" : naverwebtoon.NaverwebtoonComicExtractor,
+ "#pattern" : naverwebtoon.NaverwebtoonEpisodeExtractor.pattern,
+ "#count" : ">= 12",
+},
+
+)
diff --git a/test/results/newgrounds.py b/test/results/newgrounds.py
new file mode 100644
index 00000000..3dac724d
--- /dev/null
+++ b/test/results/newgrounds.py
@@ -0,0 +1,303 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import newgrounds
+
+
+__tests__ = (
+{
+ "#url" : "https://www.newgrounds.com/art/view/tomfulp/ryu-is-hawt",
+ "#category": ("", "newgrounds", "image"),
+ "#class" : newgrounds.NewgroundsImageExtractor,
+ "#sha1_url" : "57f182bcbbf2612690c3a54f16ffa1da5105245e",
+ "#sha1_content": "8f395e08333eb2457ba8d8b715238f8910221365",
+
+ "artist" : ["tomfulp"],
+ "comment" : r"re:Consider this the bottom threshold for ",
+ "date" : "dt:2009-06-04 14:44:05",
+ "description": r"re:Consider this the bottom threshold for ",
+ "favorites" : int,
+ "filename" : "94_tomfulp_ryu-is-hawt",
+ "height" : 476,
+ "index" : 94,
+ "rating" : "e",
+ "score" : float,
+ "tags" : [
+ "ryu",
+ "streetfighter",
+ ],
+ "title" : "Ryu is Hawt",
+ "type" : "article",
+ "user" : "tomfulp",
+ "width" : 447,
+},
+
+{
+ "#url" : "https://art.ngfiles.com/images/0/94_tomfulp_ryu-is-hawt.gif",
+ "#category": ("", "newgrounds", "image"),
+ "#class" : newgrounds.NewgroundsImageExtractor,
+ "#sha1_url": "57f182bcbbf2612690c3a54f16ffa1da5105245e",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/art/view/sailoryon/yon-dream-buster",
+ "#category": ("", "newgrounds", "image"),
+ "#class" : newgrounds.NewgroundsImageExtractor,
+ "#count" : 2,
+ "#sha1_url": "84eec95e663041a80630df72719f231e157e5f5d",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/art/view/kekiiro/red",
+ "#comment" : "'adult' rated (#2456)",
+ "#category": ("", "newgrounds", "image"),
+ "#class" : newgrounds.NewgroundsImageExtractor,
+ "#options" : {"username": None},
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.newgrounds.com/portal/view/595355",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#pattern" : r"https://uploads\.ungrounded\.net/alternate/564000/564957_alternate_31\.mp4\?1359712249",
+
+ "artist" : [
+ "kickinthehead",
+ "danpaladin",
+ "tomfulp",
+ ],
+ "comment" : r"re:My fan trailer for Alien Hominid HD!",
+ "date" : "dt:2013-02-01 09:50:49",
+ "description": "Fan trailer for Alien Hominid HD!",
+ "favorites" : int,
+ "filename" : "564957_alternate_31",
+ "index" : 595355,
+ "rating" : "e",
+ "score" : float,
+ "tags" : [
+ "alienhominid",
+ "trailer",
+ ],
+ "title" : "Alien Hominid Fan Trailer",
+ "type" : "movie",
+ "user" : "kickinthehead",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/audio/listen/609768",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#sha1_url": "f4c5490ae559a3b05e46821bb7ee834f93a43c95",
+
+ "artist" : [
+ "zj",
+ "tomfulp",
+ ],
+ "comment" : r"""re:RECORDED 12-09-2014
+
+From The ZJ "Late """,
+ "date" : "dt:2015-02-23 19:31:59",
+ "description": "From The ZJ Report Show!",
+ "favorites" : int,
+ "index" : 609768,
+ "rating" : "",
+ "score" : float,
+ "tags" : [
+ "fulp",
+ "interview",
+ "tom",
+ "zj",
+ ],
+ "title" : "ZJ Interviews Tom Fulp!",
+ "type" : "music.song",
+ "user" : "zj",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/portal/view/161181/format/flash",
+ "#comment" : "flash animation (#1257)",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#pattern" : r"https://uploads\.ungrounded\.net/161000/161181_ddautta_mask__550x281_\.swf\?f1081628129",
+
+ "type": "movie",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/portal/view/758545",
+ "#comment" : "format selection (#1729)",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#options" : {"format": "720p"},
+ "#pattern" : r"https://uploads\.ungrounded\.net/alternate/1482000/1482860_alternate_102516\.720p\.mp4\?\d+",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/portal/view/717744",
+ "#comment" : "'adult' rated (#2456)",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#options" : {"username": None},
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.newgrounds.com/portal/view/829032",
+ "#comment" : "flash game",
+ "#category": ("", "newgrounds", "media"),
+ "#class" : newgrounds.NewgroundsMediaExtractor,
+ "#pattern" : r"https://uploads\.ungrounded\.net/829000/829032_picovsbeardx\.swf\?f1641968445",
+ "#range" : "1",
+
+ "artist" : [
+ "dungeonation",
+ "carpetbakery",
+ "animalspeakandrews",
+ "bill",
+ "chipollo",
+ "dylz49",
+ "gappyshamp",
+ "pinktophat",
+ "rad",
+ "shapeshiftingblob",
+ "tomfulp",
+ "voicesbycorey",
+ "psychogoldfish",
+ ],
+ "comment" : r"re:The children are expendable. Take out the ",
+ "date" : "dt:2022-01-10 23:00:57",
+ "description": "Bloodshed in The Big House that Blew...again!",
+ "favorites" : int,
+ "index" : 829032,
+ "post_url" : "https://www.newgrounds.com/portal/view/829032",
+ "rating" : "m",
+ "score" : float,
+ "tags" : [
+ "assassin",
+ "boyfriend",
+ "darnell",
+ "nene",
+ "pico",
+ "picos-school",
+ ],
+ "title" : "PICO VS BEAR DX",
+ "type" : "game",
+ "url" : "https://uploads.ungrounded.net/829000/829032_picovsbeardx.swf?f1641968445",
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/art",
+ "#category": ("", "newgrounds", "art"),
+ "#class" : newgrounds.NewgroundsArtExtractor,
+ "#pattern" : newgrounds.NewgroundsImageExtractor.pattern,
+ "#count" : ">= 3",
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/audio",
+ "#category": ("", "newgrounds", "audio"),
+ "#class" : newgrounds.NewgroundsAudioExtractor,
+ "#pattern" : r"https://audio.ngfiles.com/\d+/\d+_.+\.mp3",
+ "#count" : ">= 4",
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/movies",
+ "#category": ("", "newgrounds", "movies"),
+ "#class" : newgrounds.NewgroundsMoviesExtractor,
+ "#pattern" : r"https://uploads.ungrounded.net(/alternate)?/\d+/\d+_.+",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/games",
+ "#category": ("", "newgrounds", "games"),
+ "#class" : newgrounds.NewgroundsGamesExtractor,
+ "#pattern" : r"https://uploads.ungrounded.net(/alternate)?/\d+/\d+_.+",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com",
+ "#category": ("", "newgrounds", "user"),
+ "#class" : newgrounds.NewgroundsUserExtractor,
+ "#pattern" : "https://tomfulp.newgrounds.com/art$",
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com",
+ "#category": ("", "newgrounds", "user"),
+ "#class" : newgrounds.NewgroundsUserExtractor,
+ "#options" : {"include": "all"},
+ "#pattern" : "https://tomfulp.newgrounds.com/(art|audio|movies)$",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/favorites/art",
+ "#category": ("", "newgrounds", "favorite"),
+ "#class" : newgrounds.NewgroundsFavoriteExtractor,
+ "#range" : "1-10",
+ "#count" : ">= 10",
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/favorites/audio",
+ "#category": ("", "newgrounds", "favorite"),
+ "#class" : newgrounds.NewgroundsFavoriteExtractor,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/favorites/movies",
+ "#category": ("", "newgrounds", "favorite"),
+ "#class" : newgrounds.NewgroundsFavoriteExtractor,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/favorites/",
+ "#category": ("", "newgrounds", "favorite"),
+ "#class" : newgrounds.NewgroundsFavoriteExtractor,
+},
+
+{
+ "#url" : "https://tomfulp.newgrounds.com/favorites/following",
+ "#category": ("", "newgrounds", "following"),
+ "#class" : newgrounds.NewgroundsFollowingExtractor,
+ "#pattern" : newgrounds.NewgroundsUserExtractor.pattern,
+ "#range" : "76-125",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://www.newgrounds.com/search/conduct/art?terms=tree",
+ "#category": ("", "newgrounds", "search"),
+ "#class" : newgrounds.NewgroundsSearchExtractor,
+ "#pattern" : newgrounds.NewgroundsImageExtractor.pattern,
+ "#range" : "1-10",
+ "#count" : 10,
+
+ "search_tags": "tree",
+},
+
+{
+ "#url" : "https://www.newgrounds.com/search/conduct/movies?terms=tree",
+ "#category": ("", "newgrounds", "search"),
+ "#class" : newgrounds.NewgroundsSearchExtractor,
+ "#pattern" : r"https://uploads.ungrounded.net(/alternate)?/\d+/\d+",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.newgrounds.com/search/conduct/audio?advanced=1&terms=tree+green+nature&match=tdtu&genre=5&suitabilities=e%2Cm",
+ "#category": ("", "newgrounds", "search"),
+ "#class" : newgrounds.NewgroundsSearchExtractor,
+},
+
+)
diff --git a/test/results/nhentai.py b/test/results/nhentai.py
new file mode 100644
index 00000000..946acb3a
--- /dev/null
+++ b/test/results/nhentai.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nhentai
+
+
+__tests__ = (
+{
+ "#url" : "https://nhentai.net/g/147850/",
+ "#category": ("", "nhentai", "gallery"),
+ "#class" : nhentai.NhentaiGalleryExtractor,
+ "#sha1_url": "5179dbf0f96af44005a0ff705a0ad64ac26547d0",
+
+ "title" : r"re:\[Morris\] Amazon no Hiyaku \| Amazon Elixir",
+ "title_en" : str,
+ "title_ja" : str,
+ "gallery_id": 147850,
+ "media_id" : 867789,
+ "count" : 16,
+ "date" : 1446050915,
+ "scanlator" : "",
+ "artist" : ["morris"],
+ "group" : list,
+ "parody" : list,
+ "characters": list,
+ "tags" : list,
+ "type" : "manga",
+ "lang" : "en",
+ "language" : "English",
+ "width" : int,
+ "height" : int,
+},
+
+{
+ "#url" : "https://nhentai.net/tag/sole-female/",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+ "#pattern" : nhentai.NhentaiGalleryExtractor.pattern,
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://nhentai.net/artist/itou-life/",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/group/itou-life/",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/parody/touhou-project/",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/character/patchouli-knowledge/popular",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/category/doujinshi/popular-today",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/language/english/popular-week",
+ "#category": ("", "nhentai", "tag"),
+ "#class" : nhentai.NhentaiTagExtractor,
+},
+
+{
+ "#url" : "https://nhentai.net/search/?q=touhou",
+ "#category": ("", "nhentai", "search"),
+ "#class" : nhentai.NhentaiSearchExtractor,
+ "#pattern" : nhentai.NhentaiGalleryExtractor.pattern,
+ "#range" : "1-30",
+ "#count" : 30,
+},
+
+{
+ "#url" : "https://nhentai.net/favorites/",
+ "#category": ("", "nhentai", "favorite"),
+ "#class" : nhentai.NhentaiFavoriteExtractor,
+},
+
+)
diff --git a/test/results/nijie.py b/test/results/nijie.py
new file mode 100644
index 00000000..b2b10a70
--- /dev/null
+++ b/test/results/nijie.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nijie
+import datetime
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://nijie.info/members.php?id=44",
+ "#category": ("Nijie", "nijie", "user"),
+ "#class" : nijie.NijieUserExtractor,
+},
+
+{
+ "#url" : "https://nijie.info/members_illust.php?id=44",
+ "#category": ("Nijie", "nijie", "illustration"),
+ "#class" : nijie.NijieIllustrationExtractor,
+ "#sha1_url": "1553e5144df50a676f5947d02469299b401ad6c0",
+
+ "artist_id" : 44,
+ "artist_name": "ED",
+ "date" : datetime.datetime,
+ "description": str,
+ "extension" : "jpg",
+ "filename" : str,
+ "image_id" : int,
+ "num" : int,
+ "tags" : list,
+ "title" : str,
+ "url" : r"re:https://pic.nijie.net/\d+/nijie/.*jpg$",
+ "user_id" : 44,
+ "user_name" : "ED",
+},
+
+{
+ "#url" : "https://nijie.info/members_illust.php?id=43",
+ "#category": ("Nijie", "nijie", "illustration"),
+ "#class" : nijie.NijieIllustrationExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://nijie.info/members_dojin.php?id=6782",
+ "#category": ("Nijie", "nijie", "doujin"),
+ "#class" : nijie.NijieDoujinExtractor,
+ "#count" : ">= 18",
+
+ "user_id" : 6782,
+ "user_name": "ジョニー@アビオン村",
+},
+
+{
+ "#url" : "https://nijie.info/user_like_illust_view.php?id=44",
+ "#category": ("Nijie", "nijie", "favorite"),
+ "#class" : nijie.NijieFavoriteExtractor,
+ "#count" : ">= 16",
+
+ "user_id" : 44,
+ "user_name": "ED",
+},
+
+{
+ "#url" : "https://nijie.info/history_nuita.php?id=728995",
+ "#category": ("Nijie", "nijie", "nuita"),
+ "#class" : nijie.NijieNuitaExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+
+ "user_id" : 728995,
+ "user_name": "莚",
+},
+
+{
+ "#url" : "https://nijie.info/like_user_view.php",
+ "#category": ("Nijie", "nijie", "feed"),
+ "#class" : nijie.NijieFeedExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://nijie.info/like_my.php",
+ "#category": ("Nijie", "nijie", "followed"),
+ "#class" : nijie.NijiefollowedExtractor,
+},
+
+{
+ "#url" : "https://nijie.info/view.php?id=70720",
+ "#category": ("Nijie", "nijie", "image"),
+ "#class" : nijie.NijieImageExtractor,
+ "#sha1_url" : "3d654e890212ba823c9647754767336aebc0a743",
+ "#sha1_metadata": "41da5d0e178b04f01fe72460185df52fadc3c91b",
+ "#sha1_content" : "d85e3ea896ed5e4da0bca2390ad310a4df716ca6",
+},
+
+{
+ "#url" : "https://nijie.info/view.php?id=70724",
+ "#category": ("Nijie", "nijie", "image"),
+ "#class" : nijie.NijieImageExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://nijie.info/view_popup.php?id=70720",
+ "#category": ("Nijie", "nijie", "image"),
+ "#class" : nijie.NijieImageExtractor,
+},
+
+)
diff --git a/test/results/nitter1d4us.py b/test/results/nitter1d4us.py
new file mode 100644
index 00000000..4c6c3d12
--- /dev/null
+++ b/test/results/nitter1d4us.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.1d4.us/supernaturepics",
+ "#category": ("nitter", "nitter.1d4.us", "tweets"),
+ "#class" : nitter.NitterTweetsExtractor,
+ "#range" : "1",
+
+ "user": {"id": "2976459548"},
+},
+
+{
+ "#url" : "https://nitter.1d4.us/supernaturepics/with_replies",
+ "#category": ("nitter", "nitter.1d4.us", "replies"),
+ "#class" : nitter.NitterRepliesExtractor,
+},
+
+{
+ "#url" : "https://nitter.1d4.us/supernaturepics/media",
+ "#category": ("nitter", "nitter.1d4.us", "media"),
+ "#class" : nitter.NitterMediaExtractor,
+},
+
+{
+ "#url" : "https://nitter.1d4.us/supernaturepics/search",
+ "#category": ("nitter", "nitter.1d4.us", "search"),
+ "#class" : nitter.NitterSearchExtractor,
+},
+
+{
+ "#url" : "https://nitter.1d4.us/playpokemon/status/1263832915173048321",
+ "#comment" : "content with emoji, newlines, hashtags (#338)",
+ "#category": ("nitter", "nitter.1d4.us", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+
+ "content": r"""re:Gear up for #PokemonSwordShieldEX with special Mystery Gifts!
+
+You’ll be able to receive four Galarian form Pokémon with Hidden Abilities, plus some very useful items. It’s our \(Mystery\) Gift to you, Trainers!
+
+❓🎁➡️ """,
+},
+
+{
+ "#url" : "https://nitter.1d4.us/StobiesGalaxy/status/1270755918330896395",
+ "#comment" : "quoted tweet (#526, #854)",
+ "#category": ("nitter", "nitter.1d4.us", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#pattern" : r"https://nitter\.1d4\.us/pic/orig/enc/bWVkaWEvRWFL\w+LmpwZw==",
+ "#count" : 4,
+
+ "filename": r"re:EaK.{12}",
+},
+
+)
diff --git a/test/results/nitterit.py b/test/results/nitterit.py
new file mode 100644
index 00000000..79d6937f
--- /dev/null
+++ b/test/results/nitterit.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.it/POTUS/status/1639409307878928384",
+ "#category": ("nitter", "nitter.it", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#count" : 0,
+},
+
+)
diff --git a/test/results/nitterkavinrocks.py b/test/results/nitterkavinrocks.py
new file mode 100644
index 00000000..22a72e2e
--- /dev/null
+++ b/test/results/nitterkavinrocks.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.kavin.rocks/id:2976459548",
+ "#category": ("nitter", "nitter.kavin.rocks", "tweets"),
+ "#class" : nitter.NitterTweetsExtractor,
+},
+
+{
+ "#url" : "https://nitter.kavin.rocks/id:2976459548/with_replies",
+ "#category": ("nitter", "nitter.kavin.rocks", "replies"),
+ "#class" : nitter.NitterRepliesExtractor,
+},
+
+{
+ "#url" : "https://nitter.kavin.rocks/id:2976459548/media",
+ "#category": ("nitter", "nitter.kavin.rocks", "media"),
+ "#class" : nitter.NitterMediaExtractor,
+ "#pattern" : r"https://nitter\.kavin\.rocks/pic/orig/media%2F[\w-]+\.(jpg|png)$",
+ "#range" : "1-20",
+},
+
+{
+ "#url" : "https://nitter.kavin.rocks/id:2976459548/search",
+ "#category": ("nitter", "nitter.kavin.rocks", "search"),
+ "#class" : nitter.NitterSearchExtractor,
+},
+
+{
+ "#url" : "https://nitter.kavin.rocks/ed1conf/status/1163841619336007680",
+ "#comment" : "Nitter tweet (#890)",
+ "#category": ("nitter", "nitter.kavin.rocks", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#sha1_url" : "e115bd1c86c660064e392b05269bbcafcd8c8b7a",
+ "#sha1_content": "f29501e44d88437fe460f5c927b7543fda0f6e34",
+},
+
+)
diff --git a/test/results/nitterlacontrevoiefr.py b/test/results/nitterlacontrevoiefr.py
new file mode 100644
index 00000000..b2a81ec1
--- /dev/null
+++ b/test/results/nitterlacontrevoiefr.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.lacontrevoie.fr/supernaturepics",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "tweets"),
+ "#class" : nitter.NitterTweetsExtractor,
+ "#pattern" : r"https://nitter\.lacontrevoie\.fr/pic/orig/media%2FCGMNYZvW0AIVoom\.jpg",
+ "#range" : "1",
+ "#sha1_url": "54f4b55f2099dcc248f3fb7bfacf1349e08d8e2d",
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/supernaturepics/with_replies",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "replies"),
+ "#class" : nitter.NitterRepliesExtractor,
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/supernaturepics/media",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "media"),
+ "#class" : nitter.NitterMediaExtractor,
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/supernaturepics/search",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "search"),
+ "#class" : nitter.NitterSearchExtractor,
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/i/status/894001459754180609",
+ "#comment" : "4 images",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#sha1_url": "9c51b3a4a1114535eb9b168bba97ad95db0d59ff",
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/i/status/1065692031626829824",
+ "#comment" : "video",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#pattern" : r"ytdl:https://nitter\.lacontrevoie\.fr/video/[0-9A-F]{10,}/https%3A%2F%2Fvideo.twimg.com%2Fext_tw_video%2F1065691868439007232%2Fpu%2Fpl%2Fnv8hUQC1R0SjhzcZ.m3u8%3Ftag%3D5",
+
+ "extension": "mp4",
+ "filename" : "nv8hUQC1R0SjhzcZ",
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/i/status/1460044411165888515",
+ "#comment" : "deleted quote tweet (#2225)",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://nitter.lacontrevoie.fr/i/status/1486373748911575046",
+ "#comment" : "'Misleading' content",
+ "#category": ("nitter", "nitter.lacontrevoie.fr", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#count" : 4,
+},
+
+)
diff --git a/test/results/nitternet.py b/test/results/nitternet.py
new file mode 100644
index 00000000..2a1cccf6
--- /dev/null
+++ b/test/results/nitternet.py
@@ -0,0 +1,107 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.net/supernaturepics",
+ "#category": ("nitter", "nitter.net", "tweets"),
+ "#class" : nitter.NitterTweetsExtractor,
+ "#pattern" : r"https://nitter\.net/pic/orig/media%2F[\w-]+\.(jpg|png)$",
+ "#range" : "1-20",
+ "#count" : 20,
+
+ "author" : {
+ "name": "supernaturepics",
+ "nick": "Nature Pictures",
+ },
+ "comments": int,
+ "content" : str,
+ "count" : 1,
+ "date" : datetime.datetime,
+ "likes" : int,
+ "quotes" : int,
+ "retweets": int,
+ "tweet_id": r"re:\d+",
+ "user" : {
+ "date" : "dt:2015-01-12 10:25:00",
+ "description" : "The very best nature pictures.",
+ "favourites_count": int,
+ "followers_count" : int,
+ "friends_count" : int,
+ "id" : "2976459548",
+ "name" : "supernaturepics",
+ "nick" : "Nature Pictures",
+ "profile_banner" : "https://nitter.net/pic/https%3A%2F%2Fpbs.twimg.com%2Fprofile_banners%2F2976459548%2F1421058583%2F1500x500",
+ "profile_image" : "https://nitter.net/pic/pbs.twimg.com%2Fprofile_images%2F554585280938659841%2FFLVAlX18.jpeg",
+ "statuses_count" : 1568,
+ "verified" : False,
+ },
+},
+
+{
+ "#url" : "https://nitter.net/supernaturepics/with_replies",
+ "#category": ("nitter", "nitter.net", "replies"),
+ "#class" : nitter.NitterRepliesExtractor,
+ "#pattern" : r"https://nitter\.net/pic/orig/media%2F[\w-]+\.(jpg|png)$",
+ "#range" : "1-20",
+},
+
+{
+ "#url" : "https://nitter.net/supernaturepics/media",
+ "#category": ("nitter", "nitter.net", "media"),
+ "#class" : nitter.NitterMediaExtractor,
+ "#pattern" : r"https://nitter\.net/pic/orig/media%2F[\w-]+\.(jpg|png)$",
+ "#range" : "1-20",
+},
+
+{
+ "#url" : "https://nitter.net/supernaturepics/search",
+ "#category": ("nitter", "nitter.net", "search"),
+ "#class" : nitter.NitterSearchExtractor,
+ "#pattern" : r"https://nitter\.net/pic/orig/media%2F[\w-]+\.(jpg|png)$",
+ "#range" : "1-20",
+},
+
+{
+ "#url" : "https://nitter.net/supernaturepics/status/604341487988576256",
+ "#category": ("nitter", "nitter.net", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#sha1_url" : "3f2b64e175bf284aa672c3bb53ed275e470b919a",
+ "#sha1_content": "ab05e1d8d21f8d43496df284d31e8b362cd3bcab",
+
+ "comments" : 19,
+ "content" : "Big Wedeene River, Canada",
+ "count" : 1,
+ "date" : "dt:2015-05-29 17:40:00",
+ "extension": "jpg",
+ "filename" : "CGMNYZvW0AIVoom",
+ "likes" : int,
+ "num" : 1,
+ "quotes" : 10,
+ "retweets" : int,
+ "tweet_id" : "604341487988576256",
+ "url" : "https://nitter.net/pic/orig/media%2FCGMNYZvW0AIVoom.jpg",
+ "user" : {
+ "name": "supernaturepics",
+ "nick": "Nature Pictures",
+ },
+},
+
+{
+ "#url" : "https://nitter.net/StobiesGalaxy/status/1270755918330896395",
+ "#comment" : "'quoted' option (#854)",
+ "#category": ("nitter", "nitter.net", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#options" : {"quoted": True},
+ "#pattern" : r"https://nitter\.net/pic/orig/media%2FEa[KG].+\.jpg",
+ "#count" : 8,
+},
+
+)
diff --git a/test/results/nitterunixfoxeu.py b/test/results/nitterunixfoxeu.py
new file mode 100644
index 00000000..d9b216e2
--- /dev/null
+++ b/test/results/nitterunixfoxeu.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nitter
+
+
+__tests__ = (
+{
+ "#url" : "https://nitter.unixfox.eu/supernaturepics",
+ "#category": ("nitter", "nitter.unixfox.eu", "tweets"),
+ "#class" : nitter.NitterTweetsExtractor,
+},
+
+{
+ "#url" : "https://nitter.unixfox.eu/i/user/2976459548/with_replies",
+ "#category": ("nitter", "nitter.unixfox.eu", "replies"),
+ "#class" : nitter.NitterRepliesExtractor,
+},
+
+{
+ "#url" : "https://nitter.unixfox.eu/i/user/2976459548/media",
+ "#category": ("nitter", "nitter.unixfox.eu", "media"),
+ "#class" : nitter.NitterMediaExtractor,
+},
+
+{
+ "#url" : "https://nitter.unixfox.eu/i/user/2976459548/search",
+ "#category": ("nitter", "nitter.unixfox.eu", "search"),
+ "#class" : nitter.NitterSearchExtractor,
+},
+
+{
+ "#url" : "https://nitter.unixfox.eu/i/web/status/1170041925560258560",
+ "#comment" : "Reply to deleted tweet (#403, #838)",
+ "#category": ("nitter", "nitter.unixfox.eu", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#pattern" : r"https://nitter\.unixfox\.eu/pic/orig/media%2FEDzS7VrU0AAFL4_\.jpg",
+},
+
+{
+ "#url" : "https://nitter.unixfox.eu/mightbecurse/status/1492954264909479936",
+ "#comment" : "age-restricted (#2354)",
+ "#category": ("nitter", "nitter.unixfox.eu", "tweet"),
+ "#class" : nitter.NitterTweetExtractor,
+ "#count" : 1,
+
+ "date": "dt:2022-02-13 20:10:00",
+},
+
+)
diff --git a/test/results/nozomi.py b/test/results/nozomi.py
new file mode 100644
index 00000000..042c7920
--- /dev/null
+++ b/test/results/nozomi.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nozomi
+
+
+__tests__ = (
+{
+ "#url" : "https://nozomi.la/post/3649262.html",
+ "#category": ("", "nozomi", "post"),
+ "#class" : nozomi.NozomiPostExtractor,
+ "#pattern" : r"https://w\.nozomi\.la/2/15/aaa9f7c632cde1e1a5baaff3fb6a6d857ec73df7fdc5cf5a358caf604bf73152\.webp",
+ "#sha1_url" : "e5525e717aec712843be8b88592d6406ae9e60ba",
+ "#sha1_content": "6d62c4a7fea50c0a89d499603c4e7a2b4b9bffa8",
+
+ "artist" : ["hammer (sunset beach)"],
+ "character": ["patchouli knowledge"],
+ "copyright": ["touhou"],
+ "dataid" : r"re:aaa9f7c632cde1e1a5baaff3fb6a6d857ec73df7fdc5",
+ "date" : "dt:2016-07-26 02:32:03",
+ "extension": "webp",
+ "filename" : str,
+ "height" : 768,
+ "is_video" : False,
+ "postid" : 3649262,
+ "tags" : list,
+ "type" : "jpg",
+ "url" : str,
+ "width" : 1024,
+},
+
+{
+ "#url" : "https://nozomi.la/post/25588032.html",
+ "#comment" : "multiple images per post",
+ "#category": ("", "nozomi", "post"),
+ "#class" : nozomi.NozomiPostExtractor,
+ "#count" : 7,
+ "#sha1_url" : "fb956ccedcf2cf509739d26e2609e910244aa56c",
+ "#sha1_metadata": "516ca5cbd0d2a46a8ce26679d6e08de5ac42184b",
+},
+
+{
+ "#url" : "https://nozomi.la/post/130309.html",
+ "#comment" : "empty 'date' (#1163)",
+ "#category": ("", "nozomi", "post"),
+ "#class" : nozomi.NozomiPostExtractor,
+
+ "date": None,
+},
+
+{
+ "#url" : "https://nozomi.la/post/1647.html",
+ "#comment" : "gif",
+ "#category": ("", "nozomi", "post"),
+ "#class" : nozomi.NozomiPostExtractor,
+ "#pattern" : r"https://g\.nozomi\.la/a/f0/d1b06469e00d72e4f6346209c149db459d76b58a074416c260ed93cc31fa9f0a\.gif",
+ "#sha1_content": "952efb78252bbc9fb56df2e8fafb68d5e6364181",
+},
+
+{
+ "#url" : "https://nozomi.la/post/2269847.html",
+ "#comment" : "video",
+ "#category": ("", "nozomi", "post"),
+ "#class" : nozomi.NozomiPostExtractor,
+ "#pattern" : r"https://v\.nozomi\.la/d/0e/ff88398862669783691b31519f2bea3a35c24b6e62e3ba2d89b4409e41c660ed\.webm",
+ "#sha1_content": "57065e6c16da7b1c7098a63b36fb0c6c6f1b9bca",
+},
+
+{
+ "#url" : "https://nozomi.la/",
+ "#category": ("", "nozomi", "index"),
+ "#class" : nozomi.NozomiIndexExtractor,
+},
+
+{
+ "#url" : "https://nozomi.la/index-2.html",
+ "#category": ("", "nozomi", "index"),
+ "#class" : nozomi.NozomiIndexExtractor,
+},
+
+{
+ "#url" : "https://nozomi.la/index-Popular-33.html",
+ "#category": ("", "nozomi", "index"),
+ "#class" : nozomi.NozomiIndexExtractor,
+},
+
+{
+ "#url" : "https://nozomi.la/tag/3:1_aspect_ratio-1.html",
+ "#category": ("", "nozomi", "tag"),
+ "#class" : nozomi.NozomiTagExtractor,
+ "#pattern" : r"^https://[wgv]\.nozomi\.la/\w/\w\w/\w+\.\w+$",
+ "#range" : "1-25",
+ "#count" : ">= 25",
+},
+
+{
+ "#url" : "https://nozomi.la/search.html?q=hibiscus%203:4_ratio#1",
+ "#category": ("", "nozomi", "search"),
+ "#class" : nozomi.NozomiSearchExtractor,
+ "#count" : ">= 5",
+},
+
+)
diff --git a/test/results/nsfwalbum.py b/test/results/nsfwalbum.py
new file mode 100644
index 00000000..e89b8fb4
--- /dev/null
+++ b/test/results/nsfwalbum.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nsfwalbum
+
+
+__tests__ = (
+{
+ "#url" : "https://nsfwalbum.com/album/401611",
+ "#category": ("", "nsfwalbum", "album"),
+ "#class" : nsfwalbum.NsfwalbumAlbumExtractor,
+ "#range" : "1-5",
+ "#sha1_url" : "b0481fc7fad5982da397b6359fbed8421b8ba284",
+ "#sha1_metadata": "e98f9b0d473c00000831618d0235863b1dd78294",
+},
+
+)
diff --git a/test/results/nudecollect.py b/test/results/nudecollect.py
new file mode 100644
index 00000000..423c915f
--- /dev/null
+++ b/test/results/nudecollect.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import nudecollect
+
+
+__tests__ = (
+{
+ "#url" : "https://www.nudecollect.com/content/20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust/image-4-pics-108-mirror-43.html",
+ "#category": ("", "nudecollect", "image"),
+ "#class" : nudecollect.NudecollectImageExtractor,
+ "#pattern" : r"https://mirror\d+\.nudecollect\.com/showimage/nudecollect-8769086487/image00004-5896498214-43-9689595623/20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust/9879560327/nudecollect\.com\.jpg",
+
+ "slug" : "20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust",
+ "title" : "20201220 Teenpornstorage Patritcy Vanessa Lesbian Lust",
+ "num" : 4,
+ "count" : 108,
+ "mirror": 43,
+},
+
+{
+ "#url" : "https://www.nudecollect.com/content/20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust/image-10-pics-108-mirror-43.html",
+ "#category": ("", "nudecollect", "image"),
+ "#class" : nudecollect.NudecollectImageExtractor,
+},
+
+{
+ "#url" : "https://www.nudecollect.com/content/20170219_TheWhiteBoxxx_Caprice_Tracy_Loves_Hot_ass_fingering_and_sensual_lesbian_sex_with_alluring_Czech_babes_x125_1080px/index-mirror-67-125.html",
+ "#category": ("", "nudecollect", "album"),
+ "#class" : nudecollect.NudecollectAlbumExtractor,
+ "#pattern" : r"https://mirror\d+\.nudecollect\.com/showimage/nudecollect-8769086487/image00\d\d\d-5896498214-67-9689595623/20170219_TheWhiteBoxxx_Caprice_Tracy_Loves_Hot_ass_fingering_and_sensual_lesbian_sex_with_alluring_Czech_babes_x125_1080px/9879560327/nudecollect\.com\.jpg",
+ "#count" : 125,
+
+ "slug" : "20170219_TheWhiteBoxxx_Caprice_Tracy_Loves_Hot_ass_fingering_and_sensual_lesbian_sex_with_alluring_Czech_babes_x125_1080px",
+ "title" : "20170219 TheWhiteBoxxx Caprice Tracy Loves Hot ass fingering and sensual lesbian sex with alluring Czech babes x125 1080px",
+ "num" : int,
+ "mirror": 67,
+},
+
+{
+ "#url" : "https://www.nudecollect.com/content/20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust/page-1-pics-108-mirror-43.html",
+ "#category": ("", "nudecollect", "album"),
+ "#class" : nudecollect.NudecollectAlbumExtractor,
+ "#pattern" : r"https://mirror\d+\.nudecollect\.com/showimage/nudecollect-8769086487/image00\d\d\d-5896498214-43-9689595623/20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust/9879560327/nudecollect\.com\.jpg",
+ "#count" : 108,
+
+ "slug" : "20201220_Teenpornstorage_Patritcy_Vanessa_Lesbian_Lust",
+ "title" : "20201220 Teenpornstorage Patritcy Vanessa Lesbian Lust",
+ "num" : int,
+ "mirror": 43,
+},
+
+)
diff --git a/test/results/ohpolly.py b/test/results/ohpolly.py
new file mode 100644
index 00000000..3ce1968b
--- /dev/null
+++ b/test/results/ohpolly.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://www.ohpolly.com/collections/dresses-mini-dresses",
+ "#category": ("shopify", "ohpolly", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.ohpolly.com/products/edonia-ruched-triangle-cup-a-line-mini-dress-brown",
+ "#category": ("shopify", "ohpolly", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/omgmiamiswimwear.py b/test/results/omgmiamiswimwear.py
new file mode 100644
index 00000000..27f4d54d
--- /dev/null
+++ b/test/results/omgmiamiswimwear.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://www.omgmiamiswimwear.com/collections/fajas",
+ "#category": ("shopify", "omgmiamiswimwear", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.omgmiamiswimwear.com/products/la-medusa-maxi-dress",
+ "#category": ("shopify", "omgmiamiswimwear", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+ "#pattern" : r"https://cdn\.shopify\.com/s/files/1/1819/6171/",
+ "#count" : 5,
+},
+
+)
diff --git a/test/results/paheal.py b/test/results/paheal.py
new file mode 100644
index 00000000..3ef0ec58
--- /dev/null
+++ b/test/results/paheal.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import paheal
+
+
+__tests__ = (
+{
+ "#url" : "https://rule34.paheal.net/post/list/Ayane_Suzuki/1",
+ "#category": ("shimmie2", "paheal", "tag"),
+ "#class" : paheal.PahealTagExtractor,
+ "#pattern" : r"https://[^.]+\.paheal\.net/_images/\w+/\d+%20-%20",
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://rule34.paheal.net/post/list/Ayane_Suzuki/1",
+ "#category": ("shimmie2", "paheal", "tag"),
+ "#class" : paheal.PahealTagExtractor,
+ "#options" : {"metadata": True},
+ "#range" : "1",
+
+ "date" : "dt:2018-01-07 07:04:05",
+ "duration" : 0.0,
+ "extension" : "jpg",
+ "filename" : "2446128 - Ayane_Suzuki Idolmaster idolmaster_dearly_stars Zanzi",
+ "height" : 768,
+ "id" : 2446128,
+ "md5" : "b0ceda9d860df1d15b60293a7eb465c1",
+ "search_tags": "Ayane_Suzuki",
+ "size" : 205312,
+ "source" : "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=19957280",
+ "tags" : "Ayane_Suzuki Idolmaster idolmaster_dearly_stars Zanzi",
+ "uploader" : "XXXname",
+ "width" : 1024,
+},
+
+{
+ "#url" : "https://rule34.paheal.net/post/view/481609",
+ "#category": ("shimmie2", "paheal", "post"),
+ "#class" : paheal.PahealPostExtractor,
+ "#pattern" : r"https://tulip\.paheal\.net/_images/bbdc1c33410c2cdce7556c7990be26b7/481609%20-%20Azumanga_Daioh%20inanimate%20Osaka%20Vuvuzela\.jpg",
+ "#sha1_content": "7b924bcf150b352ac75c9d281d061e174c851a11",
+
+ "date" : "dt:2010-06-17 15:40:23",
+ "extension": "jpg",
+ "file_url" : r"re:https://tulip.paheal.net/_images/bbdc1c33410c",
+ "filename" : "481609 - Azumanga_Daioh inanimate Osaka Vuvuzela",
+ "height" : 660,
+ "id" : 481609,
+ "md5" : "bbdc1c33410c2cdce7556c7990be26b7",
+ "size" : 157389,
+ "source" : "",
+ "tags" : "Azumanga_Daioh inanimate Osaka Vuvuzela",
+ "uploader" : "CaptainButtface",
+ "width" : 614,
+},
+
+{
+ "#url" : "https://rule34.paheal.net/post/view/488534",
+ "#category": ("shimmie2", "paheal", "post"),
+ "#class" : paheal.PahealPostExtractor,
+
+ "date" : "dt:2010-06-25 13:51:17",
+ "height" : 800,
+ "md5" : "b39edfe455a0381110c710d6ed2ef57d",
+ "size" : 758989,
+ "source" : "http://www.furaffinity.net/view/4057821/",
+ "tags" : "inanimate thelost-dragon Vuvuzela",
+ "uploader": "leacheate_soup",
+ "width" : 1200,
+},
+
+{
+ "#url" : "https://rule34.paheal.net/post/view/3864982",
+ "#comment" : "video",
+ "#category": ("shimmie2", "paheal", "post"),
+ "#class" : paheal.PahealPostExtractor,
+ "#pattern" : r"https://[\w]+\.paheal\.net/_images/7629fc0ff77e32637dde5bf4f992b2cb/3864982%20-%20animated%20Metal_Gear%20Metal_Gear_Solid_V%20Quiet%20Vg_erotica%20webm\.webm",
+
+ "date" : "dt:2020-09-06 01:59:03",
+ "duration" : 30.0,
+ "extension": "webm",
+ "height" : 2500,
+ "id" : 3864982,
+ "md5" : "7629fc0ff77e32637dde5bf4f992b2cb",
+ "size" : 18454938,
+ "source" : "https://twitter.com/VG_Worklog/status/1302407696294055936",
+ "tags" : "animated Metal_Gear Metal_Gear_Solid_V Quiet Vg_erotica webm",
+ "uploader" : "justausername",
+ "width" : 1768,
+},
+
+)
diff --git a/test/results/palanq.py b/test/results/palanq.py
new file mode 100644
index 00000000..046e6e88
--- /dev/null
+++ b/test/results/palanq.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://archive.palanq.win/c/thread/4209598/",
+ "#category": ("foolfuuka", "palanq", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "1f9b5570d228f1f2991c827a6631030bc0e5933c",
+},
+
+{
+ "#url" : "https://archive.palanq.win/c/",
+ "#category": ("foolfuuka", "palanq", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://archive.palanq.win/_/search/text/test/",
+ "#category": ("foolfuuka", "palanq", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://archive.palanq.win/c/gallery",
+ "#category": ("foolfuuka", "palanq", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/patreon.py b/test/results/patreon.py
new file mode 100644
index 00000000..adad12e3
--- /dev/null
+++ b/test/results/patreon.py
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import patreon
+import datetime
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.patreon.com/koveliana",
+ "#category": ("", "patreon", "creator"),
+ "#class" : patreon.PatreonCreatorExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 25",
+
+ "attachments" : list,
+ "comment_count": int,
+ "content" : str,
+ "creator" : dict,
+ "date" : datetime.datetime,
+ "id" : int,
+ "images" : list,
+ "like_count" : int,
+ "post_type" : str,
+ "published_at" : str,
+ "title" : str,
+},
+
+{
+ "#url" : "https://www.patreon.com/koveliana/posts?filters[month]=2020-3",
+ "#category": ("", "patreon", "creator"),
+ "#class" : patreon.PatreonCreatorExtractor,
+ "#count" : 1,
+
+ "date": "dt:2020-03-30 21:21:44",
+},
+
+{
+ "#url" : "https://www.patreon.com/kovelianot",
+ "#category": ("", "patreon", "creator"),
+ "#class" : patreon.PatreonCreatorExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.patreon.com/user?u=2931440",
+ "#category": ("", "patreon", "creator"),
+ "#class" : patreon.PatreonCreatorExtractor,
+},
+
+{
+ "#url" : "https://www.patreon.com/user/posts/?u=2931440",
+ "#category": ("", "patreon", "creator"),
+ "#class" : patreon.PatreonCreatorExtractor,
+},
+
+{
+ "#url" : "https://www.patreon.com/home",
+ "#category": ("", "patreon", "user"),
+ "#class" : patreon.PatreonUserExtractor,
+},
+
+{
+ "#url" : "https://www.patreon.com/posts/precious-metal-23563293",
+ "#comment" : "postfile + attachments",
+ "#category": ("", "patreon", "post"),
+ "#class" : patreon.PatreonPostExtractor,
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://www.patreon.com/posts/56127163",
+ "#comment" : "postfile + content",
+ "#category": ("", "patreon", "post"),
+ "#class" : patreon.PatreonPostExtractor,
+ "#count" : 3,
+
+ "filename": r"re:^(?!1).+$",
+},
+
+{
+ "#url" : "https://www.patreon.com/posts/free-post-12497641",
+ "#comment" : "tags (#1539)",
+ "#category": ("", "patreon", "post"),
+ "#class" : patreon.PatreonPostExtractor,
+
+ "tags": ["AWMedia"],
+},
+
+{
+ "#url" : "https://www.patreon.com/posts/not-found-123",
+ "#category": ("", "patreon", "post"),
+ "#class" : patreon.PatreonPostExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+)
diff --git a/test/results/pawoo.py b/test/results/pawoo.py
new file mode 100644
index 00000000..5a9bfcaa
--- /dev/null
+++ b/test/results/pawoo.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import mastodon
+
+
+__tests__ = (
+{
+ "#url" : "https://pawoo.net/@yoru_nine/",
+ "#category": ("mastodon", "pawoo", "user"),
+ "#class" : mastodon.MastodonUserExtractor,
+ "#range" : "1-60",
+ "#count" : 60,
+},
+
+{
+ "#url" : "https://pawoo.net/bookmarks",
+ "#category": ("mastodon", "pawoo", "bookmark"),
+ "#class" : mastodon.MastodonBookmarkExtractor,
+},
+
+{
+ "#url" : "https://pawoo.net/users/yoru_nine/following",
+ "#category": ("mastodon", "pawoo", "following"),
+ "#class" : mastodon.MastodonFollowingExtractor,
+},
+
+{
+ "#url" : "https://pawoo.net/@yoru_nine/105038878897832922",
+ "#category": ("mastodon", "pawoo", "status"),
+ "#class" : mastodon.MastodonStatusExtractor,
+ "#sha1_content": "b52e807f8ab548d6f896b09218ece01eba83987a",
+},
+
+)
diff --git a/test/results/photobucket.py b/test/results/photobucket.py
new file mode 100644
index 00000000..90b5b83f
--- /dev/null
+++ b/test/results/photobucket.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import photobucket
+
+
+__tests__ = (
+{
+ "#url" : "https://s369.photobucket.com/user/CrpyLrkr/library",
+ "#category": ("", "photobucket", "album"),
+ "#class" : photobucket.PhotobucketAlbumExtractor,
+ "#pattern" : r"https?://[oi]+\d+.photobucket.com/albums/oo139/",
+ "#count" : ">= 50",
+},
+
+{
+ "#url" : "https://s271.photobucket.com/user/lakerfanryan/library/",
+ "#comment" : "subalbums of main 'directory'",
+ "#category": ("", "photobucket", "album"),
+ "#class" : photobucket.PhotobucketAlbumExtractor,
+ "#options" : {"image-filter": "False"},
+ "#pattern" : photobucket.PhotobucketAlbumExtractor.pattern,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://s271.photobucket.com/user/lakerfanryan/library/Basketball",
+ "#comment" : "subalbums of subalbum without images",
+ "#category": ("", "photobucket", "album"),
+ "#class" : photobucket.PhotobucketAlbumExtractor,
+ "#pattern" : photobucket.PhotobucketAlbumExtractor.pattern,
+ "#count" : ">= 9",
+},
+
+{
+ "#url" : "https://s1277.photobucket.com/user/sinisterkat44/library/",
+ "#comment" : "private (missing JSON data)",
+ "#category": ("", "photobucket", "album"),
+ "#class" : photobucket.PhotobucketAlbumExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://s1110.photobucket.com/user/chndrmhn100/library/Chandu%20is%20the%20King?sort=3&page=1",
+ "#category": ("", "photobucket", "album"),
+ "#class" : photobucket.PhotobucketAlbumExtractor,
+},
+
+{
+ "#url" : "https://s271.photobucket.com/user/lakerfanryan/media/Untitled-3-1.jpg.html",
+ "#category": ("", "photobucket", "image"),
+ "#class" : photobucket.PhotobucketImageExtractor,
+ "#sha1_url" : "3b647deeaffc184cc48c89945f67574559c9051f",
+ "#sha1_metadata": "69732741b2b351db7ecaa77ace2fdb39f08ca5a3",
+},
+
+{
+ "#url" : "https://s271.photobucket.com/user/lakerfanryan/media/IsotopeswBros.jpg.html?sort=3&o=2",
+ "#category": ("", "photobucket", "image"),
+ "#class" : photobucket.PhotobucketImageExtractor,
+ "#sha1_url" : "12c1890c09c9cdb8a88fba7eec13f324796a8d7b",
+ "#sha1_metadata": "61200a223df6c06f45ac3d30c88b3f5b048ce9a8",
+},
+
+)
diff --git a/test/results/photovogue.py b/test/results/photovogue.py
new file mode 100644
index 00000000..6898f5d9
--- /dev/null
+++ b/test/results/photovogue.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import photovogue
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://www.vogue.com/photovogue/photographers/221252",
+ "#category": ("", "photovogue", "user"),
+ "#class" : photovogue.PhotovogueUserExtractor,
+},
+
+{
+ "#url" : "https://vogue.com/photovogue/photographers/221252",
+ "#category": ("", "photovogue", "user"),
+ "#class" : photovogue.PhotovogueUserExtractor,
+ "#pattern" : "https://images.vogue.it/Photovogue/[^/]+_gallery.jpg",
+
+ "date" : datetime.datetime,
+ "favorite_count" : int,
+ "favorited" : list,
+ "id" : int,
+ "image_id" : str,
+ "is_favorite" : False,
+ "orientation" : r"re:portrait|landscape",
+ "photographer" : {
+ "biography" : "Born in 1995. Live in Bologna.",
+ "city" : "Bologna",
+ "country_id" : 106,
+ "favoritedCount": int,
+ "id" : 221252,
+ "isGold" : bool,
+ "isPro" : bool,
+ "latitude" : str,
+ "longitude" : str,
+ "name" : "Arianna Mattarozzi",
+ "user_id" : "38cb0601-4a85-453c-b7dc-7650a037f2ab",
+ "websites" : list,
+ },
+ "photographer_id": 221252,
+ "tags" : list,
+ "title" : str,
+},
+
+)
diff --git a/test/results/picarto.py b/test/results/picarto.py
new file mode 100644
index 00000000..07456260
--- /dev/null
+++ b/test/results/picarto.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import picarto
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://picarto.tv/fnook/gallery/default/",
+ "#category": ("", "picarto", "gallery"),
+ "#class" : picarto.PicartoGalleryExtractor,
+ "#pattern" : r"https://images\.picarto\.tv/gallery/\d/\d\d/\d+/artwork/[0-9a-f-]+/large-[0-9a-f]+\.(jpg|png|gif)",
+ "#count" : ">= 7",
+
+ "date": datetime.datetime,
+},
+
+)
diff --git a/test/results/piczel.py b/test/results/piczel.py
new file mode 100644
index 00000000..84d1d01b
--- /dev/null
+++ b/test/results/piczel.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import piczel
+
+
+__tests__ = (
+{
+ "#url" : "https://piczel.tv/gallery/Bikupan",
+ "#category": ("", "piczel", "user"),
+ "#class" : piczel.PiczelUserExtractor,
+ "#range" : "1-100",
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://piczel.tv/gallery/Lulena/1114",
+ "#category": ("", "piczel", "folder"),
+ "#class" : piczel.PiczelFolderExtractor,
+ "#count" : ">= 4",
+},
+
+{
+ "#url" : "https://piczel.tv/gallery/image/7807",
+ "#category": ("", "piczel", "image"),
+ "#class" : piczel.PiczelImageExtractor,
+ "#pattern" : r"https://(\w+\.)?piczel\.tv/static/uploads/gallery_image/32920/image/7807/1532236438-Lulena\.png",
+ "#sha1_content": "df9a053a24234474a19bce2b7e27e0dec23bff87",
+
+ "created_at" : "2018-07-22T05:13:58.000Z",
+ "date" : "dt:2018-07-22 05:13:58",
+ "description" : None,
+ "extension" : "png",
+ "favorites_count" : int,
+ "folder_id" : 1113,
+ "id" : 7807,
+ "is_flash" : False,
+ "is_video" : False,
+ "multi" : False,
+ "nsfw" : False,
+ "num" : 0,
+ "password_protected": False,
+ "tags" : [
+ "fanart",
+ "commission",
+ "altair",
+ "recreators",
+ ],
+ "title" : "Altair",
+ "user" : dict,
+ "views" : int,
+},
+
+)
diff --git a/test/results/pillowfort.py b/test/results/pillowfort.py
new file mode 100644
index 00000000..a7c73beb
--- /dev/null
+++ b/test/results/pillowfort.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pillowfort
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://www.pillowfort.social/posts/27510",
+ "#category": ("", "pillowfort", "post"),
+ "#class" : pillowfort.PillowfortPostExtractor,
+ "#pattern" : r"https://img\d+\.pillowfort\.social/posts/\w+_out\d+\.png",
+ "#count" : 4,
+
+ "avatar_url" : str,
+ "col" : 0,
+ "commentable" : True,
+ "comments_count" : int,
+ "community_id" : None,
+ "content" : str,
+ "created_at" : str,
+ "date" : datetime.datetime,
+ "deleted" : None,
+ "deleted_at" : None,
+ "deleted_by_mod" : None,
+ "deleted_for_flag_id": None,
+ "embed_code" : None,
+ "id" : int,
+ "last_activity" : str,
+ "last_activity_elapsed": str,
+ "last_edited_at" : str,
+ "likes_count" : int,
+ "media_type" : "picture",
+ "nsfw" : False,
+ "num" : int,
+ "original_post_id": None,
+ "original_post_user_id": None,
+ "picture_content_type": None,
+ "picture_file_name": None,
+ "picture_file_size": None,
+ "picture_updated_at": None,
+ "post_id" : 27510,
+ "post_type" : "picture",
+ "privacy" : "public",
+ "reblog_copy_info": list,
+ "rebloggable" : True,
+ "reblogged_from_post_id": None,
+ "reblogged_from_user_id": None,
+ "reblogs_count" : int,
+ "row" : int,
+ "small_image_url" : None,
+ "tags" : list,
+ "time_elapsed" : str,
+ "timestamp" : str,
+ "title" : "What is Pillowfort.social?",
+ "updated_at" : str,
+ "url" : r"re:https://img3.pillowfort.social/posts/.*\.png",
+ "user_id" : 5,
+ "username" : "Staff",
+},
+
+{
+ "#url" : "https://www.pillowfort.social/posts/1557500",
+ "#category": ("", "pillowfort", "post"),
+ "#class" : pillowfort.PillowfortPostExtractor,
+ "#options" : {
+ "external": True,
+ "inline" : False,
+ },
+ "#pattern" : r"https://twitter\.com/Aliciawitdaart/status/1282862493841457152",
+},
+
+{
+ "#url" : "https://www.pillowfort.social/posts/1672518",
+ "#category": ("", "pillowfort", "post"),
+ "#class" : pillowfort.PillowfortPostExtractor,
+ "#options" : {"inline": True},
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.pillowfort.social/Pome",
+ "#category": ("", "pillowfort", "user"),
+ "#class" : pillowfort.PillowfortUserExtractor,
+ "#pattern" : r"https://img\d+\.pillowfort\.social/posts/",
+ "#range" : "1-15",
+ "#count" : 15,
+},
+
+)
diff --git a/test/results/pinterest.py b/test/results/pinterest.py
new file mode 100644
index 00000000..26671bff
--- /dev/null
+++ b/test/results/pinterest.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pinterest
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.pinterest.com/pin/858146903966145189/",
+ "#category": ("", "pinterest", "pin"),
+ "#class" : pinterest.PinterestPinExtractor,
+ "#sha1_url" : "afb3c26719e3a530bb0e871c480882a801a4e8a5",
+ "#sha1_content": [
+ "4c435a66f6bb82bb681db2ecc888f76cf6c5f9ca",
+ "d3e24bc9f7af585e8c23b9136956bd45a4d9b947",
+ ],
+},
+
+{
+ "#url" : "https://www.pinterest.com/pin/422564377542934214/",
+ "#comment" : "video pin (#1189)",
+ "#category": ("", "pinterest", "pin"),
+ "#class" : pinterest.PinterestPinExtractor,
+ "#pattern" : r"https://v\d*\.pinimg\.com/videos/mc/hls/d7/22/ff/d722ff00ab2352981b89974b37909de8.m3u8",
+},
+
+{
+ "#url" : "https://www.pinterest.com/pin/858146903966145188/",
+ "#category": ("", "pinterest", "pin"),
+ "#class" : pinterest.PinterestPinExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/test-/",
+ "#category": ("", "pinterest", "board"),
+ "#class" : pinterest.PinterestBoardExtractor,
+ "#pattern" : r"https://i\.pinimg\.com/originals/",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/stuff/",
+ "#comment" : "board with sections (#835)",
+ "#category": ("", "pinterest", "board"),
+ "#class" : pinterest.PinterestBoardExtractor,
+ "#options" : {"sections": True},
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://www.pinterest.de/g1952849/secret/",
+ "#comment" : "secret board (#1055)",
+ "#category": ("", "pinterest", "board"),
+ "#class" : pinterest.PinterestBoardExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952848/test/",
+ "#category": ("", "pinterest", "board"),
+ "#class" : pinterest.PinterestBoardExtractor,
+ "#exception": exception.GalleryDLException,
+},
+
+{
+ "#url" : "https://www.pinterest.co.uk/hextra7519/based-animals/",
+ "#comment" : ".co.uk TLD (#914)",
+ "#category": ("", "pinterest", "board"),
+ "#class" : pinterest.PinterestBoardExtractor,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/",
+ "#category": ("", "pinterest", "user"),
+ "#class" : pinterest.PinterestUserExtractor,
+ "#pattern" : pinterest.PinterestBoardExtractor.pattern,
+ "#count" : ">= 2",
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/_saved/",
+ "#category": ("", "pinterest", "user"),
+ "#class" : pinterest.PinterestUserExtractor,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/pins/",
+ "#category": ("", "pinterest", "allpins"),
+ "#class" : pinterest.PinterestAllpinsExtractor,
+ "#pattern" : r"https://i\.pinimg\.com/originals/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{32}\.\w{3}",
+ "#count" : 7,
+},
+
+{
+ "#url" : "https://www.pinterest.de/digitalmomblog/_created/",
+ "#category": ("", "pinterest", "created"),
+ "#class" : pinterest.PinterestCreatedExtractor,
+ "#pattern" : r"https://i\.pinimg\.com/originals/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{2}/[0-9a-f]{32}\.(jpg|png)",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/stuff/section",
+ "#category": ("", "pinterest", "section"),
+ "#class" : pinterest.PinterestSectionExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.pinterest.com/search/pins/?q=nature",
+ "#category": ("", "pinterest", "search"),
+ "#class" : pinterest.PinterestSearchExtractor,
+ "#range" : "1-50",
+ "#count" : ">= 50",
+},
+
+{
+ "#url" : "https://www.pinterest.com/pin/858146903966145189/#related",
+ "#category": ("", "pinterest", "related-pin"),
+ "#class" : pinterest.PinterestRelatedPinExtractor,
+ "#range" : "31-70",
+ "#count" : 40,
+ "#archive" : False,
+},
+
+{
+ "#url" : "https://www.pinterest.com/g1952849/test-/#related",
+ "#category": ("", "pinterest", "related-board"),
+ "#class" : pinterest.PinterestRelatedBoardExtractor,
+ "#range" : "31-70",
+ "#count" : 40,
+ "#archive" : False,
+},
+
+{
+ "#url" : "https://pin.it/Hvt8hgT",
+ "#category": ("", "pinterest", "pinit"),
+ "#class" : pinterest.PinterestPinitExtractor,
+ "#sha1_url": "8daad8558382c68f0868bdbd17d05205184632fa",
+},
+
+{
+ "#url" : "https://pin.it/Hvt8hgS",
+ "#category": ("", "pinterest", "pinit"),
+ "#class" : pinterest.PinterestPinitExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+)
diff --git a/test/results/pinupgirlclothing.py b/test/results/pinupgirlclothing.py
new file mode 100644
index 00000000..ac82ad53
--- /dev/null
+++ b/test/results/pinupgirlclothing.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://pinupgirlclothing.com/collections/evening",
+ "#category": ("shopify", "pinupgirlclothing", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://pinupgirlclothing.com/collections/evening/products/clarice-coat-dress-in-olive-green-poly-crepe-laura-byrnes-design",
+ "#category": ("shopify", "pinupgirlclothing", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/pixhost.py b/test/results/pixhost.py
new file mode 100644
index 00000000..82fbea98
--- /dev/null
+++ b/test/results/pixhost.py
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://pixhost.to/show/190/130327671_test-.png",
+ "#category": ("imagehost", "pixhost", "image"),
+ "#class" : imagehosts.PixhostImageExtractor,
+ "#sha1_url" : "4e5470dcf6513944773044d40d883221bbc46cff",
+ "#sha1_metadata": "3bad6d59db42a5ebbd7842c2307e1c3ebd35e6b0",
+ "#sha1_content" : "0c8768055e4e20e7c7259608b67799171b691140",
+},
+
+{
+ "#url" : "https://pixhost.to/gallery/jSMFq",
+ "#category": ("imagehost", "pixhost", "gallery"),
+ "#class" : imagehosts.PixhostGalleryExtractor,
+ "#pattern" : imagehosts.PixhostImageExtractor.pattern,
+ "#count" : 3,
+},
+
+)
diff --git a/test/results/pixiv.py b/test/results/pixiv.py
new file mode 100644
index 00000000..34c44f8c
--- /dev/null
+++ b/test/results/pixiv.py
@@ -0,0 +1,520 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pixiv
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.pixiv.net/en/users/173530",
+ "#category": ("", "pixiv", "user"),
+ "#class" : pixiv.PixivUserExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/u/173530",
+ "#category": ("", "pixiv", "user"),
+ "#class" : pixiv.PixivUserExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/member.php?id=173530",
+ "#category": ("", "pixiv", "user"),
+ "#class" : pixiv.PixivUserExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/mypage.php#id=173530",
+ "#category": ("", "pixiv", "user"),
+ "#class" : pixiv.PixivUserExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/#id=173530",
+ "#category": ("", "pixiv", "user"),
+ "#class" : pixiv.PixivUserExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/artworks",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+ "#sha1_url": "852c31ad83b6840bacbce824d85f2a997889efb7",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/artworks/%E6%89%8B%E3%81%B6%E3%82%8D",
+ "#comment" : "illusts with specific tag",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+ "#sha1_url": "25b1cd81153a8ff82eec440dd9f20a4a22079658",
+},
+
+{
+ "#url" : "https://www.pixiv.net/member_illust.php?id=173530&tag=%E6%89%8B%E3%81%B6%E3%82%8D",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+ "#sha1_url": "25b1cd81153a8ff82eec440dd9f20a4a22079658",
+},
+
+{
+ "#url" : "http://www.pixiv.net/member_illust.php?id=173531",
+ "#comment" : "deleted account",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+ "#options" : {"metadata": True},
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/manga",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/illustrations",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/member_illust.php?id=173530",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+},
+
+{
+ "#url" : "https://touch.pixiv.net/member_illust.php?id=173530",
+ "#category": ("", "pixiv", "artworks"),
+ "#class" : pixiv.PixivArtworksExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/avatar",
+ "#category": ("", "pixiv", "avatar"),
+ "#class" : pixiv.PixivAvatarExtractor,
+ "#sha1_content": "4e57544480cc2036ea9608103e8f024fa737fe66",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/194921/background",
+ "#category": ("", "pixiv", "background"),
+ "#class" : pixiv.PixivBackgroundExtractor,
+ "#pattern" : r"https://i\.pximg\.net/background/img/2021/01/30/16/12/02/194921_af1f71e557a42f499213d4b9eaccc0f8\.jpg",
+},
+
+{
+ "#url" : "https://pixiv.me/del_shannon",
+ "#category": ("", "pixiv", "me"),
+ "#class" : pixiv.PixivMeExtractor,
+ "#sha1_url": "29c295ce75150177e6b0a09089a949804c708fbf",
+},
+
+{
+ "#url" : "https://pixiv.me/del_shanno",
+ "#category": ("", "pixiv", "me"),
+ "#class" : pixiv.PixivMeExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.pixiv.net/artworks/966412",
+ "#comment" : "related works (#1237)",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+ "#sha1_url" : "90c1715b07b0d1aad300bce256a0bc71f42540ba",
+ "#sha1_content": "69a8edfb717400d1c2e146ab2b30d2c235440c5a",
+
+ "date" : "dt:2008-06-12 15:29:13",
+ "date_url": "dt:2008-06-12 15:29:13",
+},
+
+{
+ "#url" : "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=966411",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://www.pixiv.net/member_illust.php?mode=medium&illust_id=66806629",
+ "#comment" : "ugoira",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+ "#sha1_url": "7267695a985c4db8759bebcf8d21dbdd2d2317ef",
+
+ "frames" : list,
+ "date" : "dt:2018-01-14 15:06:08",
+ "date_url": "dt:2018-01-15 04:24:48",
+},
+
+{
+ "#url" : "https://www.pixiv.net/artworks/966412",
+ "#comment" : "related works (#1237)",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+ "#options" : {"related": True},
+ "#range" : "1-10",
+ "#count" : ">= 10",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/artworks/966412",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=96641",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "http://i1.pixiv.net/c/600x600/img-master/img/2008/06/13/00/29/13/966412_p0_master1200.jpg",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "https://i.pximg.net/img-original/img/2017/04/25/07/33/29/62568267_p0.png",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/i/966412",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "http://img.pixiv.net/img/soundcross/42626136.jpg",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "http://i2.pixiv.net/img76/img/snailrin/42672235.jpg",
+ "#category": ("", "pixiv", "work"),
+ "#class" : pixiv.PixivWorkExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/bookmarks/artworks",
+ "#category": ("", "pixiv", "favorite"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#sha1_url": "85a3104eaaaf003c7b3947117ca2f1f0b1cfc949",
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark.php?id=173530",
+ "#category": ("", "pixiv", "favorite"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#sha1_url": "85a3104eaaaf003c7b3947117ca2f1f0b1cfc949",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/3137110/bookmarks/artworks/%E3%81%AF%E3%82%93%E3%82%82%E3%82%93",
+ "#comment" : "bookmarks with specific tag",
+ "#category": ("", "pixiv", "favorite"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#sha1_url": "379b28275f786d946e01f721e54afe346c148a8c",
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark.php?id=3137110&tag=%E3%81%AF%E3%82%93%E3%82%82%E3%82%93&p=1",
+ "#comment" : "bookmarks with specific tag (legacy url)",
+ "#category": ("", "pixiv", "favorite"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#sha1_url": "379b28275f786d946e01f721e54afe346c148a8c",
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark.php",
+ "#comment" : "own bookmarks",
+ "#category": ("", "pixiv", "bookmark"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#options" : {"metadata-bookmark": True},
+ "#sha1_url": "90c1715b07b0d1aad300bce256a0bc71f42540ba",
+
+ "tags_bookmark": [
+ "47",
+ "hitman",
+ ],
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark.php?tag=foobar",
+ "#comment" : "own bookmarks with tag (#596)",
+ "#category": ("", "pixiv", "bookmark"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/173530/following",
+ "#comment" : "followed users (#515)",
+ "#category": ("", "pixiv", "following"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#pattern" : pixiv.PixivUserExtractor.pattern,
+ "#count" : ">= 12",
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark.php?id=173530&type=user",
+ "#comment" : "followed users (legacy url) (#515)",
+ "#category": ("", "pixiv", "following"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+ "#pattern" : pixiv.PixivUserExtractor.pattern,
+ "#count" : ">= 12",
+},
+
+{
+ "#url" : "https://touch.pixiv.net/bookmark.php?id=173530",
+ "#comment" : "touch URLs",
+ "#category": ("", "pixiv", "favorite"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+},
+
+{
+ "#url" : "https://touch.pixiv.net/bookmark.php",
+ "#category": ("", "pixiv", "bookmark"),
+ "#class" : pixiv.PixivFavoriteExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/ranking.php?mode=daily&date=20170818",
+ "#category": ("", "pixiv", "ranking"),
+ "#class" : pixiv.PixivRankingExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/ranking.php",
+ "#category": ("", "pixiv", "ranking"),
+ "#class" : pixiv.PixivRankingExtractor,
+},
+
+{
+ "#url" : "https://touch.pixiv.net/ranking.php",
+ "#category": ("", "pixiv", "ranking"),
+ "#class" : pixiv.PixivRankingExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/ranking.php?mode=unknown",
+ "#category": ("", "pixiv", "ranking"),
+ "#class" : pixiv.PixivRankingExtractor,
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/tags/Original",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://pixiv.net/en/tags/foo/artworks?order=week&s_mode=s_tag",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://pixiv.net/en/tags/foo/artworks?order=date&s_mode=tag",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://www.pixiv.net/search.php?s_mode=s_tag&name=Original",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/tags/foo/artworks?order=date&s_mode=s_tag",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/search.php?s_mode=s_tag&word=Original",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+},
+
+{
+ "#url" : "https://touch.pixiv.net/search.php?word=Original",
+ "#category": ("", "pixiv", "search"),
+ "#class" : pixiv.PixivSearchExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/bookmark_new_illust.php",
+ "#category": ("", "pixiv", "follow"),
+ "#class" : pixiv.PixivFollowExtractor,
+},
+
+{
+ "#url" : "https://touch.pixiv.net/bookmark_new_illust.php",
+ "#category": ("", "pixiv", "follow"),
+ "#class" : pixiv.PixivFollowExtractor,
+},
+
+{
+ "#url" : "https://www.pixivision.net/en/a/2791",
+ "#category": ("", "pixiv", "pixivision"),
+ "#class" : pixiv.PixivPixivisionExtractor,
+},
+
+{
+ "#url" : "https://pixivision.net/a/2791",
+ "#category": ("", "pixiv", "pixivision"),
+ "#class" : pixiv.PixivPixivisionExtractor,
+ "#count" : 7,
+
+ "pixivision_id" : "2791",
+ "pixivision_title": "What's your favorite music? Editor’s picks featuring: “CD Covers”!",
+},
+
+{
+ "#url" : "https://www.pixiv.net/user/10509347/series/21859",
+ "#category": ("", "pixiv", "series"),
+ "#class" : pixiv.PixivSeriesExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+
+ "num_series": int,
+ "series" : {
+ "canonical" : "https://www.pixiv.net/user/10509347/series/21859",
+ "description": str,
+ "ogp" : dict,
+ "title" : "先輩がうざい後輩の話",
+ "total" : int,
+ "twitter" : dict,
+ },
+},
+
+{
+ "#url" : "https://www.pixiv.net/novel/show.php?id=19612040",
+ "#comment" : "full series",
+ "#category": ("", "pixiv", "novel"),
+ "#class" : pixiv.PixivNovelExtractor,
+ "#count" : 1,
+ "#sha1_content": "8c818474153cbd2f221ee08766e1d634c821d8b4",
+
+ "caption" : r"re:「無能な名無し」と呼ばれ虐げられて育った鈴\(すず\)は、",
+ "comment_access_control": 0,
+ "create_date" : "2023-04-02T15:18:58+09:00",
+ "date" : "dt:2023-04-02 06:18:58",
+ "id" : 19612040,
+ "is_bookmarked" : False,
+ "is_muted" : False,
+ "is_mypixiv_only" : False,
+ "is_original" : True,
+ "is_x_restricted" : False,
+ "novel_ai_type" : 1,
+ "page_count" : 1,
+ "rating" : "General",
+ "restrict" : 0,
+ "series" : {
+ "id" : 10278364,
+ "title": "龍の贄嫁〜無能な名無しと虐げられていましたが、どうやら異母妹に霊力を搾取されていたようです〜",
+ },
+ "tags" : [
+ "和風ファンタジー",
+ "溺愛",
+ "神様",
+ "ヤンデレ",
+ "執着",
+ "異能",
+ "ざまぁ",
+ "学園",
+ "神嫁",
+ ],
+ "text_length" : 5974,
+ "title" : "異母妹から「無能な名無し」と虐げられていた私、どうやら異母妹に霊力を搾取されていたようです(1)",
+ "user" : {
+ "account": "yukinaga_chifuyu",
+ "id" : 77055466,
+ },
+ "visible" : True,
+ "x_restrict" : 0,
+},
+
+{
+ "#url" : "https://www.pixiv.net/novel/show.php?id=16422450",
+ "#comment" : "embeds",
+ "#category": ("", "pixiv", "novel"),
+ "#class" : pixiv.PixivNovelExtractor,
+ "#options" : {"embeds": True},
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.pixiv.net/novel/show.php?id=19612040",
+ "#comment" : "full series",
+ "#category": ("", "pixiv", "novel"),
+ "#class" : pixiv.PixivNovelExtractor,
+ "#options" : {"full-series": True},
+ "#count" : 4,
+},
+
+{
+ "#url" : "https://www.pixiv.net/n/19612040",
+ "#comment" : "short URL",
+ "#category": ("", "pixiv", "novel"),
+ "#class" : pixiv.PixivNovelExtractor,
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/77055466/novels",
+ "#category": ("", "pixiv", "novel-user"),
+ "#class" : pixiv.PixivNovelUserExtractor,
+ "#pattern" : "^text:",
+ "#range" : "1-5",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://www.pixiv.net/novel/series/10278364",
+ "#category": ("", "pixiv", "novel-series"),
+ "#class" : pixiv.PixivNovelSeriesExtractor,
+ "#count" : 4,
+ "#sha1_content": "b06abed001b3f6ccfb1579699e9a238b46d38ea2",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/77055466/bookmarks/novels",
+ "#category": ("", "pixiv", "novel-bookmark"),
+ "#class" : pixiv.PixivNovelBookmarkExtractor,
+ "#count" : 1,
+ "#sha1_content": "7194e8faa876b2b536f185ee271a2b6e46c69089",
+},
+
+{
+ "#url" : "https://www.pixiv.net/en/users/11/bookmarks/novels/TAG?rest=hide",
+ "#category": ("", "pixiv", "novel-bookmark"),
+ "#class" : pixiv.PixivNovelBookmarkExtractor,
+},
+
+{
+ "#url" : "https://sketch.pixiv.net/@nicoby",
+ "#category": ("", "pixiv", "sketch"),
+ "#class" : pixiv.PixivSketchExtractor,
+ "#pattern" : r"https://img\-sketch\.pixiv\.net/uploads/medium/file/\d+/\d+\.(jpg|png)",
+ "#count" : ">= 35",
+},
+
+)
diff --git a/test/results/pixnet.py b/test/results/pixnet.py
new file mode 100644
index 00000000..9c086526
--- /dev/null
+++ b/test/results/pixnet.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pixnet
+
+
+__tests__ = (
+{
+ "#url" : "https://albertayu773.pixnet.net/album/photo/159443828",
+ "#category": ("", "pixnet", "image"),
+ "#class" : pixnet.PixnetImageExtractor,
+ "#sha1_url" : "156564c422138914c9fa5b42191677b45c414af4",
+ "#sha1_metadata": "19971bcd056dfef5593f4328a723a9602be0f087",
+ "#sha1_content" : "0e097bdf49e76dd9b9d57a016b08b16fa6a33280",
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/album/set/15078995",
+ "#category": ("", "pixnet", "set"),
+ "#class" : pixnet.PixnetSetExtractor,
+ "#sha1_url" : "6535712801af47af51110542f4938a7cef44557f",
+ "#sha1_metadata": "bf25d59e5b0959cb1f53e7fd2e2a25f2f67e5925",
+},
+
+{
+ "#url" : "https://anrine910070.pixnet.net/album/set/5917493",
+ "#category": ("", "pixnet", "set"),
+ "#class" : pixnet.PixnetSetExtractor,
+ "#sha1_url" : "b3eb6431aea0bcf5003432a4a0f3a3232084fc13",
+ "#sha1_metadata": "bf7004faa1cea18cf9bd856f0955a69be51b1ec6",
+},
+
+{
+ "#url" : "https://sky92100.pixnet.net/album/set/17492544",
+ "#comment" : "password-protected",
+ "#category": ("", "pixnet", "set"),
+ "#class" : pixnet.PixnetSetExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/album/folder/1405768",
+ "#category": ("", "pixnet", "folder"),
+ "#class" : pixnet.PixnetFolderExtractor,
+ "#pattern" : pixnet.PixnetSetExtractor.pattern,
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/",
+ "#category": ("", "pixnet", "user"),
+ "#class" : pixnet.PixnetUserExtractor,
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/blog",
+ "#category": ("", "pixnet", "user"),
+ "#class" : pixnet.PixnetUserExtractor,
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/album",
+ "#category": ("", "pixnet", "user"),
+ "#class" : pixnet.PixnetUserExtractor,
+},
+
+{
+ "#url" : "https://albertayu773.pixnet.net/album/list",
+ "#category": ("", "pixnet", "user"),
+ "#class" : pixnet.PixnetUserExtractor,
+ "#pattern" : pixnet.PixnetFolderExtractor.pattern,
+ "#count" : ">= 30",
+},
+
+{
+ "#url" : "https://anrine910070.pixnet.net/album/list",
+ "#category": ("", "pixnet", "user"),
+ "#class" : pixnet.PixnetUserExtractor,
+ "#pattern" : pixnet.PixnetSetExtractor.pattern,
+ "#count" : ">= 14",
+},
+
+)
diff --git a/test/results/plurk.py b/test/results/plurk.py
new file mode 100644
index 00000000..11600bae
--- /dev/null
+++ b/test/results/plurk.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import plurk
+
+
+__tests__ = (
+{
+ "#url" : "https://www.plurk.com/plurkapi",
+ "#category": ("", "plurk", "timeline"),
+ "#class" : plurk.PlurkTimelineExtractor,
+ "#pattern" : "https?://.+",
+ "#count" : ">= 23",
+},
+
+{
+ "#url" : "https://www.plurk.com/p/i701j1",
+ "#category": ("", "plurk", "post"),
+ "#class" : plurk.PlurkPostExtractor,
+ "#count" : 3,
+ "#sha1_url": "2115f208564591b8748525c2807a84596aaaaa5f",
+},
+
+{
+ "#url" : "https://www.plurk.com/p/i701j1",
+ "#category": ("", "plurk", "post"),
+ "#class" : plurk.PlurkPostExtractor,
+ "#options" : {"comments": True},
+ "#count" : ">= 210",
+},
+
+)
diff --git a/test/results/poipiku.py b/test/results/poipiku.py
new file mode 100644
index 00000000..08658bae
--- /dev/null
+++ b/test/results/poipiku.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import poipiku
+
+
+__tests__ = (
+{
+ "#url" : "https://poipiku.com/25049/",
+ "#category": ("", "poipiku", "user"),
+ "#class" : poipiku.PoipikuUserExtractor,
+ "#pattern" : r"https://img-org\.poipiku\.com/user_img\d+/000025049/\d+_\w+\.(jpe?g|png)$",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://poipiku.com/IllustListPcV.jsp?PG=1&ID=25049&KWD=",
+ "#category": ("", "poipiku", "user"),
+ "#class" : poipiku.PoipikuUserExtractor,
+},
+
+{
+ "#url" : "https://poipiku.com/25049/5864576.html",
+ "#category": ("", "poipiku", "post"),
+ "#class" : poipiku.PoipikuPostExtractor,
+ "#pattern" : r"https://img-org\.poipiku\.com/user_img\d+/000025049/005864576_EWN1Y65gQ\.png$",
+
+ "count" : "1",
+ "description" : "",
+ "extension" : "png",
+ "filename" : "005864576_EWN1Y65gQ",
+ "num" : 1,
+ "post_category": "DOODLE",
+ "post_id" : "5864576",
+ "user_id" : "25049",
+ "user_name" : "ユキウサギ",
+},
+
+{
+ "#url" : "https://poipiku.com/2166245/6411749.html",
+ "#category": ("", "poipiku", "post"),
+ "#class" : poipiku.PoipikuPostExtractor,
+ "#pattern" : r"https://img-org\.poipiku\.com/user_img\d+/002166245/006411749_\w+\.jpeg$",
+ "#count" : 4,
+
+ "count" : "4",
+ "description" : "絵茶の産物ネタバレあるやつ",
+ "num" : int,
+ "post_category": "SPOILER",
+ "post_id" : "6411749",
+ "user_id" : "2166245",
+ "user_name" : "wadahito",
+},
+
+{
+ "#url" : "https://poipiku.com/3572553/5776587.html",
+ "#comment" : "different warning button style",
+ "#category": ("", "poipiku", "post"),
+ "#class" : poipiku.PoipikuPostExtractor,
+ "#pattern" : r"https://img-org\.poipiku.com/user_img\d+/003572553/005776587_(\d+_)?\w+\.jpeg$",
+ "#count" : 3,
+
+ "count" : "3",
+ "description" : "ORANGE OASISボスネタバレ
曲も大好き
2枚目以降はほとんど見えなかった1枚目背景のヒエログリフ小ネタです𓀀",
+ "num" : int,
+ "post_category": "SPOILER",
+ "post_id" : "5776587",
+ "user_id" : "3572553",
+ "user_name" : "nagakun",
+},
+
+)
diff --git a/test/results/ponybooru.py b/test/results/ponybooru.py
new file mode 100644
index 00000000..6955bb49
--- /dev/null
+++ b/test/results/ponybooru.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import philomena
+
+
+__tests__ = (
+{
+ "#url" : "https://ponybooru.org/images/1",
+ "#category": ("philomena", "ponybooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+ "#sha1_content": "bca26f58fafd791fe07adcd2a28efd7751824605",
+},
+
+{
+ "#url" : "https://www.ponybooru.org/images/1",
+ "#category": ("philomena", "ponybooru", "post"),
+ "#class" : philomena.PhilomenaPostExtractor,
+},
+
+{
+ "#url" : "https://ponybooru.org/search?q=cute",
+ "#category": ("philomena", "ponybooru", "search"),
+ "#class" : philomena.PhilomenaSearchExtractor,
+ "#range" : "40-60",
+ "#count" : 21,
+},
+
+{
+ "#url" : "https://ponybooru.org/galleries/27",
+ "#category": ("philomena", "ponybooru", "gallery"),
+ "#class" : philomena.PhilomenaGalleryExtractor,
+ "#count" : ">= 24",
+},
+
+)
diff --git a/test/results/pornhub.py b/test/results/pornhub.py
new file mode 100644
index 00000000..e7aaf8da
--- /dev/null
+++ b/test/results/pornhub.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pornhub
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://www.pornhub.com/album/19289801",
+ "#category": ("", "pornhub", "gallery"),
+ "#class" : pornhub.PornhubGalleryExtractor,
+ "#pattern" : r"https://\w+.phncdn.com/pics/albums/\d+/\d+/\d+/\d+/",
+ "#count" : ">= 300",
+
+ "id" : int,
+ "num" : int,
+ "score" : int,
+ "views" : int,
+ "caption": str,
+ "user" : "Danika Mori",
+ "gallery": {
+ "id" : 19289801,
+ "score": int,
+ "views": int,
+ "tags" : list,
+ "title": "Danika Mori Best Moments",
+ },
+},
+
+{
+ "#url" : "https://www.pornhub.com/album/69040172",
+ "#category": ("", "pornhub", "gallery"),
+ "#class" : pornhub.PornhubGalleryExtractor,
+ "#exception": exception.AuthorizationError,
+},
+
+{
+ "#url" : "https://www.pornhub.com/gif/33643461",
+ "#category": ("", "pornhub", "gif"),
+ "#class" : pornhub.PornhubGifExtractor,
+ "#pattern" : r"https://\w+\.phncdn\.com/pics/gifs/033/643/461/33643461a\.webm",
+
+ "date" : "dt:2020-10-31 00:00:00",
+ "extension": "webm",
+ "filename" : "33643461a",
+ "id" : "33643461",
+ "tags" : [
+ "big boobs",
+ "lana rhoades",
+ ],
+ "title" : "Big boobs",
+ "url" : str,
+ "user" : "Lana Rhoades",
+},
+
+{
+ "#url" : "https://www.pornhub.com/pornstar/danika-mori",
+ "#category": ("", "pornhub", "user"),
+ "#class" : pornhub.PornhubUserExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/pornstar/danika-mori/photos",
+ "#category": ("", "pornhub", "photos"),
+ "#class" : pornhub.PornhubPhotosExtractor,
+ "#pattern" : pornhub.PornhubGalleryExtractor.pattern,
+ "#count" : ">= 6",
+},
+
+{
+ "#url" : "https://www.pornhub.com/users/flyings0l0/photos/public",
+ "#category": ("", "pornhub", "photos"),
+ "#class" : pornhub.PornhubPhotosExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/users/flyings0l0/photos/private",
+ "#category": ("", "pornhub", "photos"),
+ "#class" : pornhub.PornhubPhotosExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/users/flyings0l0/photos/favorites",
+ "#category": ("", "pornhub", "photos"),
+ "#class" : pornhub.PornhubPhotosExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/model/bossgirl/photos",
+ "#category": ("", "pornhub", "photos"),
+ "#class" : pornhub.PornhubPhotosExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/pornstar/danika-mori/gifs",
+ "#category": ("", "pornhub", "gifs"),
+ "#class" : pornhub.PornhubGifsExtractor,
+ "#pattern" : pornhub.PornhubGifExtractor.pattern,
+ "#count" : ">= 42",
+},
+
+{
+ "#url" : "https://www.pornhub.com/users/flyings0l0/gifs",
+ "#category": ("", "pornhub", "gifs"),
+ "#class" : pornhub.PornhubGifsExtractor,
+},
+
+{
+ "#url" : "https://www.pornhub.com/model/bossgirl/gifs/video",
+ "#category": ("", "pornhub", "gifs"),
+ "#class" : pornhub.PornhubGifsExtractor,
+},
+
+)
diff --git a/test/results/pornpics.py b/test/results/pornpics.py
new file mode 100644
index 00000000..91a10ca0
--- /dev/null
+++ b/test/results/pornpics.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pornpics
+
+
+__tests__ = (
+{
+ "#url" : "https://www.pornpics.com/galleries/british-beauty-danielle-flashes-hot-breasts-ass-and-snatch-in-the-forest-62610699/",
+ "#category": ("", "pornpics", "gallery"),
+ "#class" : pornpics.PornpicsGalleryExtractor,
+ "#pattern" : r"https://cdni\.pornpics\.com/1280/7/160/62610699/62610699_\d+_[0-9a-f]{4}\.jpg",
+
+ "categories": [
+ "MILF",
+ "Amateur",
+ "Sexy",
+ "Outdoor",
+ ],
+ "channel" : "FTV MILFs",
+ "count" : 17,
+ "gallery_id": 62610699,
+ "models" : ["Danielle"],
+ "num" : int,
+ "slug" : "british-beauty-danielle-flashes-hot-breasts-ass-and-snatch-in-the-forest",
+ "tags" : [
+ "Amateur MILF",
+ "Sexy MILF",
+ ],
+ "title" : "British beauty Danielle flashes hot breasts, ass and snatch in the forest",
+ "views" : int,
+},
+
+{
+ "#url" : "https://pornpics.com/es/galleries/62610699",
+ "#category": ("", "pornpics", "gallery"),
+ "#class" : pornpics.PornpicsGalleryExtractor,
+
+ "slug": "british-beauty-danielle-flashes-hot-breasts-ass-and-snatch-in-the-forest",
+},
+
+{
+ "#url" : "https://www.pornpics.com/tags/summer-dress/",
+ "#category": ("", "pornpics", "tag"),
+ "#class" : pornpics.PornpicsTagExtractor,
+ "#pattern" : pornpics.PornpicsGalleryExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://pornpics.com/fr/tags/summer-dress",
+ "#category": ("", "pornpics", "tag"),
+ "#class" : pornpics.PornpicsTagExtractor,
+},
+
+{
+ "#url" : "https://www.pornpics.com/?q=nature",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+ "#pattern" : pornpics.PornpicsGalleryExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://www.pornpics.com/channels/femjoy/",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+ "#pattern" : pornpics.PornpicsGalleryExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://www.pornpics.com/pornstars/emma-brown/",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+ "#pattern" : pornpics.PornpicsGalleryExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://pornpics.com/jp/?q=nature",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+},
+
+{
+ "#url" : "https://pornpics.com/it/channels/femjoy",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+},
+
+{
+ "#url" : "https://pornpics.com/pt/pornstars/emma-brown",
+ "#category": ("", "pornpics", "search"),
+ "#class" : pornpics.PornpicsSearchExtractor,
+},
+
+)
diff --git a/test/results/pornreactor.py b/test/results/pornreactor.py
new file mode 100644
index 00000000..0062d19a
--- /dev/null
+++ b/test/results/pornreactor.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import reactor
+
+
+__tests__ = (
+{
+ "#url" : "http://pornreactor.cc/tag/RiceGnat",
+ "#category": ("reactor", "pornreactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 25",
+},
+
+{
+ "#url" : "http://fapreactor.com/tag/RiceGnat",
+ "#category": ("reactor", "pornreactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+},
+
+{
+ "#url" : "http://pornreactor.cc/search?q=ecchi+hentai",
+ "#category": ("reactor", "pornreactor", "search"),
+ "#class" : reactor.ReactorSearchExtractor,
+},
+
+{
+ "#url" : "http://fapreactor.com/search/ecchi+hentai",
+ "#category": ("reactor", "pornreactor", "search"),
+ "#class" : reactor.ReactorSearchExtractor,
+},
+
+{
+ "#url" : "http://pornreactor.cc/user/Disillusion",
+ "#category": ("reactor", "pornreactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+ "#range" : "1-25",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "http://fapreactor.com/user/Disillusion",
+ "#category": ("reactor", "pornreactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+},
+
+{
+ "#url" : "http://pornreactor.cc/post/863166",
+ "#category": ("reactor", "pornreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url" : "a09fb0577489e1f9564c25d0ad576f81b19c2ef3",
+ "#sha1_content": "ec6b0568bfb1803648744077da082d14de844340",
+},
+
+{
+ "#url" : "http://fapreactor.com/post/863166",
+ "#category": ("reactor", "pornreactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url": "2a956ce0c90e8bc47b4392db4fa25ad1342f3e54",
+},
+
+)
diff --git a/test/results/postimg.py b/test/results/postimg.py
new file mode 100644
index 00000000..ba4b8a86
--- /dev/null
+++ b/test/results/postimg.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import imagehosts
+
+
+__tests__ = (
+{
+ "#url" : "https://postimages.org/Wtn2b3hC",
+ "#category": ("imagehost", "postimg", "image"),
+ "#class" : imagehosts.PostimgImageExtractor,
+},
+
+{
+ "#url" : "https://www.postimages.org/Wtn2b3hC",
+ "#category": ("imagehost", "postimg", "image"),
+ "#class" : imagehosts.PostimgImageExtractor,
+},
+
+{
+ "#url" : "https://pixxxels.cc/Wtn2b3hC",
+ "#category": ("imagehost", "postimg", "image"),
+ "#class" : imagehosts.PostimgImageExtractor,
+},
+
+{
+ "#url" : "https://postimg.cc/Wtn2b3hC",
+ "#category": ("imagehost", "postimg", "image"),
+ "#class" : imagehosts.PostimgImageExtractor,
+ "#sha1_url" : "72f3c8b1d6c6601a20ad58f35635494b4891a99e",
+ "#sha1_metadata": "2d05808d04e4e83e33200db83521af06e3147a84",
+ "#sha1_content" : "cfaa8def53ed1a575e0c665c9d6d8cf2aac7a0ee",
+},
+
+{
+ "#url" : "https://postimg.cc/gallery/wxpDLgX",
+ "#category": ("imagehost", "postimg", "gallery"),
+ "#class" : imagehosts.PostimgGalleryExtractor,
+ "#pattern" : imagehosts.PostimgImageExtractor.pattern,
+ "#count" : 22,
+},
+
+)
diff --git a/test/results/powermanga.py b/test/results/powermanga.py
new file mode 100644
index 00000000..fb02b0cc
--- /dev/null
+++ b/test/results/powermanga.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolslide
+
+
+__tests__ = (
+{
+ "#url" : "https://read.powermanga.org/read/one_piece_digital_colour_comics/en/0/75/",
+ "#category": ("foolslide", "powermanga", "chapter"),
+ "#class" : foolslide.FoolslideChapterExtractor,
+ "#sha1_url" : "854c5817f8f767e1bccd05fa9d58ffb5a4b09384",
+ "#sha1_metadata": "a60c42f2634b7387899299d411ff494ed0ad6dbe",
+},
+
+{
+ "#url" : "https://read.powermanga.org/series/one_piece_digital_colour_comics/",
+ "#category": ("foolslide", "powermanga", "manga"),
+ "#class" : foolslide.FoolslideMangaExtractor,
+ "#count" : ">= 1",
+
+ "chapter" : int,
+ "chapter_minor" : str,
+ "chapter_string": str,
+ "group" : "PowerManga",
+ "lang" : "en",
+ "language" : "English",
+ "manga" : "One Piece Digital Colour Comics",
+ "title" : str,
+ "volume" : int,
+},
+
+)
diff --git a/test/results/pururin.py b/test/results/pururin.py
new file mode 100644
index 00000000..e57c7fe7
--- /dev/null
+++ b/test/results/pururin.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import pururin
+
+
+__tests__ = (
+{
+ "#url" : "https://pururin.to/gallery/38661/iowant-2",
+ "#category": ("", "pururin", "gallery"),
+ "#class" : pururin.PururinGalleryExtractor,
+ "#pattern" : r"https://i\.pururin\.to/38661/\d+\.jpg",
+
+ "title" : r"re:I ?owant 2!!",
+ "title_en" : r"re:I ?owant 2!!",
+ "title_ja" : "",
+ "gallery_id": 38661,
+ "count" : 19,
+ "artist" : ["Shoda Norihiro"],
+ "group" : ["Obsidian Order"],
+ "parody" : ["Kantai Collection"],
+ "characters": [
+ "Iowa",
+ "Teitoku",
+ ],
+ "tags" : list,
+ "type" : "Doujinshi",
+ "collection": ["I owant you!"],
+ "convention": ["C92"],
+ "rating" : float,
+ "uploader" : "demo",
+ "scanlator" : [
+ "mrwayne",
+ "The Lost Light",
+ ],
+ "lang" : "en",
+ "language" : "English",
+},
+
+{
+ "#url" : "https://pururin.to/gallery/7661/unisis-team-vanilla",
+ "#category": ("", "pururin", "gallery"),
+ "#class" : pururin.PururinGalleryExtractor,
+ "#count" : 17,
+},
+
+{
+ "#url" : "https://pururin.io/gallery/38661/iowant-2",
+ "#category": ("", "pururin", "gallery"),
+ "#class" : pururin.PururinGalleryExtractor,
+},
+
+)
diff --git a/test/results/raidlondon.py b/test/results/raidlondon.py
new file mode 100644
index 00000000..93aab265
--- /dev/null
+++ b/test/results/raidlondon.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import shopify
+
+
+__tests__ = (
+{
+ "#url" : "https://www.raidlondon.com/collections/flats",
+ "#category": ("shopify", "raidlondon", "collection"),
+ "#class" : shopify.ShopifyCollectionExtractor,
+},
+
+{
+ "#url" : "https://www.raidlondon.com/collections/flats/products/raid-addyson-chunky-flat-shoe-in-white",
+ "#category": ("shopify", "raidlondon", "product"),
+ "#class" : shopify.ShopifyProductExtractor,
+},
+
+)
diff --git a/test/results/rbt.py b/test/results/rbt.py
new file mode 100644
index 00000000..5a81ad1a
--- /dev/null
+++ b/test/results/rbt.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import foolfuuka
+
+
+__tests__ = (
+{
+ "#url" : "https://rbt.asia/g/thread/61487650/",
+ "#category": ("foolfuuka", "rbt", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "fadd274b25150a1bdf03a40c58db320fa3b617c4",
+},
+
+{
+ "#url" : "https://archive.rebeccablacktech.com/g/thread/61487650/",
+ "#category": ("foolfuuka", "rbt", "thread"),
+ "#class" : foolfuuka.FoolfuukaThreadExtractor,
+ "#sha1_url": "fadd274b25150a1bdf03a40c58db320fa3b617c4",
+},
+
+{
+ "#url" : "https://rbt.asia/g/",
+ "#category": ("foolfuuka", "rbt", "board"),
+ "#class" : foolfuuka.FoolfuukaBoardExtractor,
+},
+
+{
+ "#url" : "https://rbt.asia/_/search/text/test/",
+ "#category": ("foolfuuka", "rbt", "search"),
+ "#class" : foolfuuka.FoolfuukaSearchExtractor,
+},
+
+{
+ "#url" : "https://rbt.asia/g/gallery/8",
+ "#category": ("foolfuuka", "rbt", "gallery"),
+ "#class" : foolfuuka.FoolfuukaGalleryExtractor,
+},
+
+)
diff --git a/test/results/reactor.py b/test/results/reactor.py
new file mode 100644
index 00000000..7ff6dcce
--- /dev/null
+++ b/test/results/reactor.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import reactor
+
+
+__tests__ = (
+{
+ "#url" : "http://reactor.cc/tag/gif",
+ "#category": ("reactor", "reactor", "tag"),
+ "#class" : reactor.ReactorTagExtractor,
+},
+
+{
+ "#url" : "http://reactor.cc/search?q=Art",
+ "#category": ("reactor", "reactor", "search"),
+ "#class" : reactor.ReactorSearchExtractor,
+},
+
+{
+ "#url" : "http://reactor.cc/user/Dioklet",
+ "#category": ("reactor", "reactor", "user"),
+ "#class" : reactor.ReactorUserExtractor,
+},
+
+{
+ "#url" : "http://reactor.cc/post/4999736",
+ "#category": ("reactor", "reactor", "post"),
+ "#class" : reactor.ReactorPostExtractor,
+ "#sha1_url": "dfc74d150d7267384d8c229c4b82aa210755daa0",
+},
+
+)
diff --git a/test/results/readcomiconline.py b/test/results/readcomiconline.py
new file mode 100644
index 00000000..883ed321
--- /dev/null
+++ b/test/results/readcomiconline.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import readcomiconline
+
+
+__tests__ = (
+{
+ "#url" : "https://readcomiconline.li/Comic/W-i-t-c-h/Issue-130?id=22289",
+ "#category": ("", "readcomiconline", "issue"),
+ "#class" : readcomiconline.ReadcomiconlineIssueExtractor,
+ "#pattern" : r"https://2\.bp\.blogspot\.com/[\w-]+=s0\?.+",
+ "#count" : 36,
+ "#sha1_metadata": "2d9ec81ce1b11fac06ebf96ce33cdbfca0e85eb5",
+},
+
+{
+ "#url" : "https://readcomiconline.li/Comic/W-i-t-c-h",
+ "#category": ("", "readcomiconline", "comic"),
+ "#class" : readcomiconline.ReadcomiconlineComicExtractor,
+ "#sha1_url" : "74eb8b9504b4084fcc9367b341300b2c52260918",
+ "#sha1_metadata": "3986248e4458fa44a201ec073c3684917f48ee0c",
+},
+
+{
+ "#url" : "https://readcomiconline.to/Comic/Bazooka-Jules",
+ "#category": ("", "readcomiconline", "comic"),
+ "#class" : readcomiconline.ReadcomiconlineComicExtractor,
+ "#sha1_url" : "2f66a467a772df4d4592e97a059ddbc3e8991799",
+ "#sha1_metadata": "f5ba5246cd787bb750924d9690cb1549199bd516",
+},
+
+)
diff --git a/test/results/realbooru.py b/test/results/realbooru.py
new file mode 100644
index 00000000..e99634b4
--- /dev/null
+++ b/test/results/realbooru.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v02
+
+
+__tests__ = (
+{
+ "#url" : "https://realbooru.com/index.php?page=post&s=list&tags=wine",
+ "#category": ("gelbooru_v02", "realbooru", "tag"),
+ "#class" : gelbooru_v02.GelbooruV02TagExtractor,
+ "#count" : ">= 64",
+},
+
+{
+ "#url" : "https://realbooru.com/index.php?page=pool&s=show&id=1",
+ "#category": ("gelbooru_v02", "realbooru", "pool"),
+ "#class" : gelbooru_v02.GelbooruV02PoolExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://realbooru.com/index.php?page=favorites&s=view&id=274",
+ "#category": ("gelbooru_v02", "realbooru", "favorite"),
+ "#class" : gelbooru_v02.GelbooruV02FavoriteExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://realbooru.com/index.php?page=post&s=view&id=668483",
+ "#category": ("gelbooru_v02", "realbooru", "post"),
+ "#class" : gelbooru_v02.GelbooruV02PostExtractor,
+ "#options" : {"tags": True},
+ "#pattern" : r"https://realbooru\.com//?images/dc/b5/dcb5c0ce9ec0bf74a6930608985f4719\.jpeg",
+ "#sha1_content": "7f5873ce3b6cd295ea2e81fcb49583098ea9c8da",
+
+ "tags_general": "1girl blonde blonde_hair blue_eyes cute female female_only looking_at_viewer smile solo solo_female teeth",
+ "tags_model" : "jennifer_lawrence",
+},
+
+)
diff --git a/test/results/recursive.py b/test/results/recursive.py
new file mode 100644
index 00000000..2ad31dd4
--- /dev/null
+++ b/test/results/recursive.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import recursive
+
+
+__tests__ = (
+{
+ "#url" : "recursive:https://pastebin.com/raw/FLwrCYsT",
+ "#category": ("", "recursive", ""),
+ "#class" : recursive.RecursiveExtractor,
+ "#sha1_url": "eee86d65c346361b818e8f4b2b307d9429f136a2",
+},
+
+)
diff --git a/test/results/reddit.py b/test/results/reddit.py
new file mode 100644
index 00000000..330ef5b6
--- /dev/null
+++ b/test/results/reddit.py
@@ -0,0 +1,243 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import reddit
+
+
+__tests__ = (
+{
+ "#url" : "https://www.reddit.com/r/lavaporn/",
+ "#category": ("", "reddit", "subreddit"),
+ "#class" : reddit.RedditSubredditExtractor,
+ "#range" : "1-20",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "https://www.reddit.com/r/lavaporn/top/?sort=top&t=month",
+ "#category": ("", "reddit", "subreddit-top"),
+ "#class" : reddit.RedditSubredditExtractor,
+},
+
+{
+ "#url" : "https://old.reddit.com/r/lavaporn/",
+ "#category": ("", "reddit", "subreddit"),
+ "#class" : reddit.RedditSubredditExtractor,
+},
+
+{
+ "#url" : "https://np.reddit.com/r/lavaporn/",
+ "#category": ("", "reddit", "subreddit"),
+ "#class" : reddit.RedditSubredditExtractor,
+},
+
+{
+ "#url" : "https://m.reddit.com/r/lavaporn/",
+ "#category": ("", "reddit", "subreddit"),
+ "#class" : reddit.RedditSubredditExtractor,
+},
+
+{
+ "#url" : "https://www.reddit.com/",
+ "#category": ("", "reddit", "home"),
+ "#class" : reddit.RedditHomeExtractor,
+ "#range" : "1-20",
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "https://old.reddit.com/top/?sort=top&t=month",
+ "#category": ("", "reddit", "home-top"),
+ "#class" : reddit.RedditHomeExtractor,
+},
+
+{
+ "#url" : "https://www.reddit.com/user/username/",
+ "#category": ("", "reddit", "user"),
+ "#class" : reddit.RedditUserExtractor,
+ "#count" : ">= 2",
+},
+
+{
+ "#url" : "https://www.reddit.com/user/username/gilded/?sort=top&t=month",
+ "#category": ("", "reddit", "user-gilded"),
+ "#class" : reddit.RedditUserExtractor,
+},
+
+{
+ "#url" : "https://old.reddit.com/user/username/",
+ "#category": ("", "reddit", "user"),
+ "#class" : reddit.RedditUserExtractor,
+},
+
+{
+ "#url" : "https://www.reddit.com/u/username/",
+ "#category": ("", "reddit", "user"),
+ "#class" : reddit.RedditUserExtractor,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/lavaporn/comments/8cqhub/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : r"https://c2.staticflickr.com/8/7272/\w+_k.jpg",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/lavaporn/comments/8cqhub/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#options" : {"comments": 500},
+ "#pattern" : "https://",
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://www.reddit.com/gallery/hrrh23",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#count" : 3,
+ "#sha1_url" : "25b91ede15459470274dd17291424b037ed8b0ae",
+ "#sha1_content": "1e7dde4ee7d5f4c4b45749abfd15b2dbfa27df3f",
+},
+
+{
+ "#url" : "https://www.reddit.com/r/aww/comments/90bu6w/",
+ "#comment" : "video (dash)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : "ytdl:https://v.redd.it/gyh95hiqc0b11",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/aww/comments/90bu6w/",
+ "#comment" : "video (dash)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#options" : {"videos": "ytdl"},
+ "#pattern" : "ytdl:https://www.reddit.com/r/aww/comments/90bu6w/heat_index_was_110_degrees_so_we_offered_him_a/",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/aww/comments/90bu6w/",
+ "#comment" : "video (dash)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#options" : {"videos": "dash"},
+ "#pattern" : r"ytdl:https://v.redd.it/gyh95hiqc0b11/DASHPlaylist.mpd\?a=",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/gallery/icfgzv",
+ "#comment" : "deleted gallery (#953)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/araragi/comments/ib32hm",
+ "#comment" : "animated gallery items (#955)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : r"https://i\.redd\.it/\w+\.gif",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/cosplay/comments/jvwaqr",
+ "#comment" : "'failed' gallery item (#1127)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/kpopfap/comments/qjj04q/",
+ "#comment" : "gallery with no 'media_metadata' (#2001)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "https://www.reddit.com/user/TheSpiritTree/comments/srilyf/",
+ "#comment" : "user page submission (#2301)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : "https://i.redd.it/8fpgv17yqlh81.jpg",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://www.reddit.com/r/kittengifs/comments/12m0b8d",
+ "#comment" : "cross-posted video (#887, #3586, #3976)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : r"ytdl:https://v\.redd\.it/cvabpjacrvta1",
+},
+
+{
+ "#url" : "https://www.reddit.com/r/europe/comments/pm4531/the_name_of/",
+ "#comment" : "preview.redd.it (#4470)",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+ "#pattern" : "https://preview.redd.it/u9ud4k6xaf271.jpg?auto=webp&s=19b1334cb4409111cda136c01f7b44c2c42bf9fb",
+},
+
+{
+ "#url" : "https://old.reddit.com/r/lavaporn/comments/2a00np/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+},
+
+{
+ "#url" : "https://np.reddit.com/r/lavaporn/comments/2a00np/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+},
+
+{
+ "#url" : "https://m.reddit.com/r/lavaporn/comments/2a00np/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+},
+
+{
+ "#url" : "https://redd.it/2a00np/",
+ "#category": ("", "reddit", "submission"),
+ "#class" : reddit.RedditSubmissionExtractor,
+},
+
+{
+ "#url" : "https://i.redd.it/upjtjcx2npzz.jpg",
+ "#category": ("", "reddit", "image"),
+ "#class" : reddit.RedditImageExtractor,
+ "#sha1_url" : "0de614900feef103e580b632190458c0b62b641a",
+ "#sha1_content": "cc9a68cf286708d5ce23c68e79cd9cf7826db6a3",
+},
+
+{
+ "#url" : "https://i.reddituploads.com/0f44f1b1fca2461f957c713d9592617d?fit=max&h=1536&w=1536&s=e96ce7846b3c8e1f921d2ce2671fb5e2",
+ "#category": ("", "reddit", "image"),
+ "#class" : reddit.RedditImageExtractor,
+ "#sha1_url" : "f24f25efcedaddeec802e46c60d77ef975dc52a5",
+ "#sha1_content": "541dbcc3ad77aa01ee21ca49843c5e382371fae7",
+},
+
+{
+ "#url" : "https://preview.redd.it/00af44lpn0u51.jpg?width=960&crop=smart&auto=webp&v=enabled&s=dbca8ab84033f4a433772d9c15dbe0429c74e8ac",
+ "#comment" : "preview.redd.it -> i.redd.it",
+ "#category": ("", "reddit", "image"),
+ "#class" : reddit.RedditImageExtractor,
+ "#pattern" : r"^https://i\.redd\.it/00af44lpn0u51\.jpg$",
+},
+
+)
diff --git a/test/results/redgifs.py b/test/results/redgifs.py
new file mode 100644
index 00000000..2ae76485
--- /dev/null
+++ b/test/results/redgifs.py
@@ -0,0 +1,152 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import redgifs
+
+
+__tests__ = (
+{
+ "#url" : "https://www.redgifs.com/users/Natalifiction",
+ "#category": ("", "redgifs", "user"),
+ "#class" : redgifs.RedgifsUserExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.mp4",
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://v3.redgifs.com/users/lamsinka89",
+ "#category": ("", "redgifs", "user"),
+ "#class" : redgifs.RedgifsUserExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.(mp4|jpg)",
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://www.redgifs.com/users/boombah123/collections/2631326bbd",
+ "#category": ("", "redgifs", "collection"),
+ "#class" : redgifs.RedgifsCollectionExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.mp4",
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.redgifs.com/users/boombah123/collections/9e6f7dd41f",
+ "#category": ("", "redgifs", "collection"),
+ "#class" : redgifs.RedgifsCollectionExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.mp4",
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.redgifs.com/users/boombah123/collections",
+ "#category": ("", "redgifs", "collections"),
+ "#class" : redgifs.RedgifsCollectionsExtractor,
+ "#pattern" : r"https://www\.redgifs\.com/users/boombah123/collections/\w+",
+ "#count" : ">= 3",
+},
+
+{
+ "#url" : "https://www.redgifs.com/niches/boobs",
+ "#category": ("", "redgifs", "niches"),
+ "#class" : redgifs.RedgifsNichesExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.mp4",
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.redgifs.com/niches/ass",
+ "#category": ("", "redgifs", "niches"),
+ "#class" : redgifs.RedgifsNichesExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[\w-]+\.mp4",
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://www.redgifs.com/gifs/jav",
+ "#category": ("", "redgifs", "search"),
+ "#class" : redgifs.RedgifsSearchExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[A-Za-z-]+\.(mp4|jpg)",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.redgifs.com/browse?tags=JAV",
+ "#category": ("", "redgifs", "search"),
+ "#class" : redgifs.RedgifsSearchExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[A-Za-z-]+\.(mp4|jpg)",
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.redgifs.com/gifs/jav?order=best&verified=1",
+ "#category": ("", "redgifs", "search"),
+ "#class" : redgifs.RedgifsSearchExtractor,
+},
+
+{
+ "#url" : "https://www.redgifs.com/browse?type=i&verified=y&order=top7",
+ "#category": ("", "redgifs", "search"),
+ "#class" : redgifs.RedgifsSearchExtractor,
+},
+
+{
+ "#url" : "https://v3.redgifs.com/browse?tags=JAV",
+ "#category": ("", "redgifs", "search"),
+ "#class" : redgifs.RedgifsSearchExtractor,
+},
+
+{
+ "#url" : "https://redgifs.com/watch/foolishforkedabyssiniancat",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/FoolishForkedAbyssiniancat\.mp4",
+ "#sha1_content": "f6e03f1df9a2ff2a74092f53ee7580d2fb943533",
+},
+
+{
+ "#url" : "https://www.redgifs.com/watch/desertedbaregraywolf",
+ "#comment" : "gallery (#4021)",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+ "#pattern" : r"https://\w+\.redgifs\.com/[A-Za-z-]+\.jpg",
+ "#count" : 4,
+
+ "num" : int,
+ "count" : 4,
+ "gallery": "187ad979693-1922-fc66-0000-a96fb07b8a5d",
+},
+
+{
+ "#url" : "https://redgifs.com/ifr/FoolishForkedAbyssiniancat",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+},
+
+{
+ "#url" : "https://i.redgifs.com/i/FoolishForkedAbyssiniancat",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+},
+
+{
+ "#url" : "https://www.gifdeliverynetwork.com/foolishforkedabyssiniancat",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+},
+
+{
+ "#url" : "https://v3.redgifs.com/watch/FoolishForkedAbyssiniancat",
+ "#category": ("", "redgifs", "image"),
+ "#class" : redgifs.RedgifsImageExtractor,
+},
+
+)
diff --git a/test/results/rule34.py b/test/results/rule34.py
new file mode 100644
index 00000000..ca90e511
--- /dev/null
+++ b/test/results/rule34.py
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v02
+
+
+__tests__ = (
+{
+ "#url" : "https://rule34.xxx/index.php?page=post&s=list&tags=danraku",
+ "#category": ("gelbooru_v02", "rule34", "tag"),
+ "#class" : gelbooru_v02.GelbooruV02TagExtractor,
+ "#pattern" : r"https?://.*rule34\.xxx/images/\d+/[0-9a-f]+\.jpg",
+ "#count" : 2,
+ "#sha1_content": [
+ "5c6ae9ee13e6d4bc9cb8bdce224c84e67fbfa36c",
+ "622e80be3f496672c44aab5c47fbc6941c61bc79",
+ ],
+},
+
+{
+ "#url" : "https://rule34.xxx/index.php?page=pool&s=show&id=179",
+ "#category": ("gelbooru_v02", "rule34", "pool"),
+ "#class" : gelbooru_v02.GelbooruV02PoolExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://rule34.xxx/index.php?page=favorites&s=view&id=1030218",
+ "#category": ("gelbooru_v02", "rule34", "favorite"),
+ "#class" : gelbooru_v02.GelbooruV02FavoriteExtractor,
+ "#count" : 3,
+},
+
+{
+ "#url" : "https://rule34.xxx/index.php?page=post&s=view&id=863",
+ "#category": ("gelbooru_v02", "rule34", "post"),
+ "#class" : gelbooru_v02.GelbooruV02PostExtractor,
+ "#options" : {
+ "tags" : True,
+ "notes": True,
+ },
+ "#pattern" : r"https://api-cdn\.rule34\.xxx/images/1/6aafbdb3e22f3f3b412ea2cf53321317a37063f3\.jpg",
+ "#sha1_content": [
+ "a43f418aa350039af0d11cae501396a33bbe2201",
+ "67b516295950867e1c1ab6bc13b35d3b762ed2a3",
+ ],
+
+ "tags_artist" : "reverse_noise yamu_(reverse_noise)",
+ "tags_character": "hong_meiling",
+ "tags_copyright": "touhou",
+ "tags_general" : str,
+ "tags_metadata" : "censored translated",
+ "notes" : [
+ {
+ "body" : "It feels angry, I'm losing myself... It won't calm down!",
+ "height": 65,
+ "id" : 93586,
+ "width" : 116,
+ "x" : 22,
+ "y" : 333,
+ },
+ {
+ "body" : "REPUTATION OF RAGE",
+ "height": 272,
+ "id" : 93587,
+ "width" : 199,
+ "x" : 78,
+ "y" : 442,
+ },
+ ],
+},
+
+)
diff --git a/test/results/rule34us.py b/test/results/rule34us.py
new file mode 100644
index 00000000..43d8f66a
--- /dev/null
+++ b/test/results/rule34us.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import rule34us
+
+
+__tests__ = (
+{
+ "#url" : "https://rule34.us/index.php?r=posts/index&q=[terios]_elysion",
+ "#category": ("booru", "rule34us", "tag"),
+ "#class" : rule34us.Rule34usTagExtractor,
+ "#pattern" : r"https://img\d*\.rule34\.us/images/../../[0-9a-f]{32}\.\w+",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://rule34.us/index.php?r=posts/view&id=3709005",
+ "#category": ("booru", "rule34us", "post"),
+ "#class" : rule34us.Rule34usPostExtractor,
+ "#pattern" : r"https://img\d*\.rule34\.us/images/14/7b/147bee6fc2e13f73f5f9bac9d4930b13\.png",
+ "#sha1_content": "d714342ea84050f82dda5f0c194d677337abafc5",
+},
+
+{
+ "#url" : "https://rule34.us/index.php?r=posts/view&id=4576310",
+ "#category": ("booru", "rule34us", "post"),
+ "#class" : rule34us.Rule34usPostExtractor,
+ "#pattern" : r"https://video\.rule34\.us/images/a2/94/a294ff8e1f8e0efa041e5dc9d1480011\.mp4",
+
+ "extension" : "mp4",
+ "file_url" : str,
+ "filename" : "a294ff8e1f8e0efa041e5dc9d1480011",
+ "height" : "3982",
+ "id" : "4576310",
+ "md5" : "a294ff8e1f8e0efa041e5dc9d1480011",
+ "score" : r"re:\d+",
+ "tags" : "tagme, video",
+ "tags_general" : "video",
+ "tags_metadata": "tagme",
+ "uploader" : "Anonymous",
+ "width" : "3184",
+},
+
+)
diff --git a/test/results/safebooru.py b/test/results/safebooru.py
new file mode 100644
index 00000000..0c183204
--- /dev/null
+++ b/test/results/safebooru.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import gelbooru_v02
+
+
+__tests__ = (
+{
+ "#url" : "https://safebooru.org/index.php?page=post&s=list&tags=bonocho",
+ "#category": ("gelbooru_v02", "safebooru", "tag"),
+ "#class" : gelbooru_v02.GelbooruV02TagExtractor,
+ "#sha1_url" : "17c61b386530cf4c30842c9f580d15ef1cd09586",
+ "#sha1_content": "e5ad4c5bf241b1def154958535bef6c2f6b733eb",
+},
+
+{
+ "#url" : "https://safebooru.org/index.php?page=pool&s=show&id=11",
+ "#category": ("gelbooru_v02", "safebooru", "pool"),
+ "#class" : gelbooru_v02.GelbooruV02PoolExtractor,
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://safebooru.org/index.php?page=favorites&s=view&id=17567",
+ "#category": ("gelbooru_v02", "safebooru", "favorite"),
+ "#class" : gelbooru_v02.GelbooruV02FavoriteExtractor,
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://safebooru.org/index.php?page=post&s=view&id=1169132",
+ "#category": ("gelbooru_v02", "safebooru", "post"),
+ "#class" : gelbooru_v02.GelbooruV02PostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_url" : "cf05e37a3c62b2d55788e2080b8eabedb00f999b",
+ "#sha1_content": "93b293b27dabd198afafabbaf87c49863ac82f27",
+
+ "tags_artist" : "kawanakajima",
+ "tags_character": "heath_ledger ronald_mcdonald the_joker",
+ "tags_copyright": "dc_comics mcdonald's the_dark_knight",
+ "tags_general" : str,
+},
+
+)
diff --git a/test/results/sakugabooru.py b/test/results/sakugabooru.py
new file mode 100644
index 00000000..73d38316
--- /dev/null
+++ b/test/results/sakugabooru.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import moebooru
+
+
+__tests__ = (
+{
+ "#url" : "https://www.sakugabooru.com/post/show/125570",
+ "#category": ("moebooru", "sakugabooru", "post"),
+ "#class" : moebooru.MoebooruPostExtractor,
+},
+
+{
+ "#url" : "https://www.sakugabooru.com/post?tags=nichijou",
+ "#category": ("moebooru", "sakugabooru", "tag"),
+ "#class" : moebooru.MoebooruTagExtractor,
+},
+
+{
+ "#url" : "https://www.sakugabooru.com/pool/show/54",
+ "#category": ("moebooru", "sakugabooru", "pool"),
+ "#class" : moebooru.MoebooruPoolExtractor,
+},
+
+{
+ "#url" : "https://www.sakugabooru.com/post/popular_recent",
+ "#category": ("moebooru", "sakugabooru", "popular"),
+ "#class" : moebooru.MoebooruPopularExtractor,
+},
+
+)
diff --git a/test/results/sankaku.py b/test/results/sankaku.py
new file mode 100644
index 00000000..e4fbf5c1
--- /dev/null
+++ b/test/results/sankaku.py
@@ -0,0 +1,194 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import sankaku
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://sankaku.app/?tags=bonocho",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+ "#pattern" : r"https://s\.sankakucomplex\.com/data/[^/]{2}/[^/]{2}/[0-9a-f]{32}\.\w+\?e=\d+&(expires=\d+&)?m=[^]+",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://beta.sankakucomplex.com/?tags=bonocho",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/?tags=bonocho",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://black.sankakucomplex.com/?tags=bonocho",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://white.sankakucomplex.com/?tags=bonocho",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://sankaku.app/ja?tags=order%3Apopularity",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://sankaku.app/no/?tags=order%3Apopularity",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/?tags=bonocho+a+b+c+d",
+ "#comment" : "error on five or more tags",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+ "#options" : {"username": None},
+ "#exception": exception.StopExtraction,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/?tags=marie_rose&page=98&next=3874906&commit=Search",
+ "#comment" : "match arbitrary query parameters",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/?tags=date:2023-03-20",
+ "#comment" : "'date:' tags (#1790)",
+ "#category": ("booru", "sankaku", "tag"),
+ "#class" : sankaku.SankakuTagExtractor,
+ "#range" : "1",
+ "#count" : 1,
+},
+
+{
+ "#url" : "https://sankaku.app/books/90",
+ "#category": ("booru", "sankaku", "pool"),
+ "#class" : sankaku.SankakuPoolExtractor,
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://beta.sankakucomplex.com/books/90",
+ "#category": ("booru", "sankaku", "pool"),
+ "#class" : sankaku.SankakuPoolExtractor,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/pool/show/90",
+ "#category": ("booru", "sankaku", "pool"),
+ "#class" : sankaku.SankakuPoolExtractor,
+},
+
+{
+ "#url" : "https://sankaku.app/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+ "#options" : {"tags": True},
+ "#sha1_content": "5e255713cbf0a8e0801dc423563c34d896bb9229",
+
+ "tags_artist" : ["bonocho"],
+ "tags_studio" : ["dc_comics"],
+ "tags_medium" : list,
+ "tags_copyright": list,
+ "tags_character": list,
+ "tags_general" : list,
+},
+
+{
+ "#url" : "https://sankaku.app/post/show/21418978",
+ "#comment" : "'contentious_content'",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+ "#pattern" : r"https://s\.sankakucomplex\.com/data/13/3c/133cda3bfde249c504284493903fb985\.jpg",
+},
+
+{
+ "#url" : "https://sankaku.app/post/show/20758561",
+ "#comment" : "empty tags (#1617)",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+ "#options" : {"tags": True},
+ "#count" : 1,
+
+ "tags" : list,
+ "tags_general": [
+ "key(mangaka)",
+ "key(mangaka)",
+ ],
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/post/show/f8ba89043078f0e4be2d9c46550b840a",
+ "#comment" : "md5 hexdigest instead of ID (#3952)",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+ "#pattern" : r"https://s\.sankakucomplex\.com/data/f8/ba/f8ba89043078f0e4be2d9c46550b840a\.jpg",
+ "#count" : 1,
+
+ "id" : 33195194,
+ "md5": "f8ba89043078f0e4be2d9c46550b840a",
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+},
+
+{
+ "#url" : "https://chan.sankakucomplex.com/ja/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+},
+
+{
+ "#url" : "https://beta.sankakucomplex.com/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+},
+
+{
+ "#url" : "https://white.sankakucomplex.com/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+},
+
+{
+ "#url" : "https://black.sankakucomplex.com/post/show/360451",
+ "#category": ("booru", "sankaku", "post"),
+ "#class" : sankaku.SankakuPostExtractor,
+},
+
+{
+ "#url" : "https://sankaku.app/books?tags=aiue_oka",
+ "#category": ("booru", "sankaku", "books"),
+ "#class" : sankaku.SankakuBooksExtractor,
+ "#range" : "1-20",
+ "#count" : 20,
+},
+
+{
+ "#url" : "https://beta.sankakucomplex.com/books?tags=aiue_oka",
+ "#category": ("booru", "sankaku", "books"),
+ "#class" : sankaku.SankakuBooksExtractor,
+},
+
+)
diff --git a/test/results/sankakucomplex.py b/test/results/sankakucomplex.py
new file mode 100644
index 00000000..f944df16
--- /dev/null
+++ b/test/results/sankakucomplex.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import sankakucomplex
+
+
+__tests__ = (
+{
+ "#url" : "https://www.sankakucomplex.com/2019/05/11/twitter-cosplayers",
+ "#category": ("", "sankakucomplex", "article"),
+ "#class" : sankakucomplex.SankakucomplexArticleExtractor,
+ "#sha1_url" : "4a9ecc5ae917fbce469280da5b6a482510cae84d",
+ "#sha1_metadata": "bfe08310e7d9a572f568f6900e0ed0eb295aa2b3",
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/2009/12/01/sexy-goddesses-of-2ch",
+ "#category": ("", "sankakucomplex", "article"),
+ "#class" : sankakucomplex.SankakucomplexArticleExtractor,
+ "#sha1_url" : "a1e249173fd6c899a8134fcfbd9c925588a63f7c",
+ "#sha1_metadata": "e78fcc23c2711befc0969a45ea5082a29efccf68",
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/2019/06/11/darling-ol-goddess-shows-off-her-plump-lower-area/",
+ "#comment" : "videos (#308)",
+ "#category": ("", "sankakucomplex", "article"),
+ "#class" : sankakucomplex.SankakucomplexArticleExtractor,
+ "#pattern" : r"/wp-content/uploads/2019/06/[^/]+\d\.mp4",
+ "#range" : "26-",
+ "#count" : 5,
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/2015/02/12/snow-miku-2015-live-magical-indeed/",
+ "#comment" : "youtube embeds (#308)",
+ "#category": ("", "sankakucomplex", "article"),
+ "#class" : sankakucomplex.SankakucomplexArticleExtractor,
+ "#options" : {"embeds": True},
+ "#pattern" : "https://www.youtube.com/embed/",
+ "#range" : "2-",
+ "#count" : 2,
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/tag/cosplay/",
+ "#category": ("", "sankakucomplex", "tag"),
+ "#class" : sankakucomplex.SankakucomplexTagExtractor,
+ "#pattern" : sankakucomplex.SankakucomplexArticleExtractor.pattern,
+ "#range" : "1-50",
+ "#count" : 50,
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/category/anime/",
+ "#category": ("", "sankakucomplex", "tag"),
+ "#class" : sankakucomplex.SankakucomplexTagExtractor,
+},
+
+{
+ "#url" : "https://www.sankakucomplex.com/author/rift/page/5/",
+ "#category": ("", "sankakucomplex", "tag"),
+ "#class" : sankakucomplex.SankakucomplexTagExtractor,
+},
+
+)
diff --git a/test/results/seiga.py b/test/results/seiga.py
new file mode 100644
index 00000000..3749adc4
--- /dev/null
+++ b/test/results/seiga.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import seiga
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://seiga.nicovideo.jp/user/illust/39537793",
+ "#category": ("", "seiga", "user"),
+ "#class" : seiga.SeigaUserExtractor,
+ "#pattern" : r"https://lohas\.nicoseiga\.jp/priv/[0-9a-f]+/\d+/\d+",
+ "#count" : ">= 4",
+
+ "user" : {
+ "id" : 39537793,
+ "message": str,
+ "name" : str,
+ },
+ "clips" : int,
+ "comments" : int,
+ "count" : int,
+ "extension": None,
+ "image_id" : int,
+ "title" : str,
+ "views" : int,
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/user/illust/79433",
+ "#category": ("", "seiga", "user"),
+ "#class" : seiga.SeigaUserExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/user/illust/39537793?sort=image_view&target=illust_all",
+ "#category": ("", "seiga", "user"),
+ "#class" : seiga.SeigaUserExtractor,
+},
+
+{
+ "#url" : "https://sp.seiga.nicovideo.jp/user/illust/39537793",
+ "#category": ("", "seiga", "user"),
+ "#class" : seiga.SeigaUserExtractor,
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/seiga/im5977527",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+ "#sha1_metadata": "c8339781da260f7fc44894ad9ada016f53e3b12a",
+ "#sha1_content" : "d9202292012178374d57fb0126f6124387265297",
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/seiga/im123",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+ "#exception": exception.NotFoundError,
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/seiga/im10877923",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+ "#pattern" : r"https://lohas\.nicoseiga\.jp/priv/5936a2a6c860a600e465e0411c0822e0b510e286/1688757110/10877923",
+},
+
+{
+ "#url" : "https://seiga.nicovideo.jp/image/source/5977527",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+},
+
+{
+ "#url" : "https://sp.seiga.nicovideo.jp/seiga/#!/im5977527",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+},
+
+{
+ "#url" : "https://lohas.nicoseiga.jp/thumb/5977527i",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+},
+
+{
+ "#url" : "https://lohas.nicoseiga.jp/priv/759a4ef1c639106ba4d665ee6333832e647d0e4e/1549727594/5977527",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+},
+
+{
+ "#url" : "https://lohas.nicoseiga.jp/o/759a4ef1c639106ba4d665ee6333832e647d0e4e/1549727594/5977527",
+ "#category": ("", "seiga", "image"),
+ "#class" : seiga.SeigaImageExtractor,
+},
+
+)
diff --git a/test/results/senmanga.py b/test/results/senmanga.py
new file mode 100644
index 00000000..8192cfad
--- /dev/null
+++ b/test/results/senmanga.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import senmanga
+
+
+__tests__ = (
+{
+ "#url" : "https://raw.senmanga.com/Bokura-wa-Minna-Kawaisou/37A/1",
+ "#category": ("", "senmanga", "chapter"),
+ "#class" : senmanga.SenmangaChapterExtractor,
+ "#pattern" : r"https://raw\.senmanga\.com/viewer/Bokura-wa-Minna-Kawaisou/37A/[12]",
+ "#sha1_url" : "5f95140ff511d8497e2ec08fa7267c6bb231faec",
+ "#sha1_content": "556a16d5ca3441d7a5807b6b5ac06ec458a3e4ba",
+
+ "chapter" : "37A",
+ "count" : 2,
+ "extension": "",
+ "filename" : r"re:[12]",
+ "lang" : "ja",
+ "language" : "Japanese",
+ "manga" : "Bokura wa Minna Kawaisou",
+ "page" : int,
+},
+
+{
+ "#url" : "http://raw.senmanga.com/Love-Lab/2016-03/1",
+ "#category": ("", "senmanga", "chapter"),
+ "#class" : senmanga.SenmangaChapterExtractor,
+ "#pattern" : r"https://raw\.senmanga\.com/viewer/Love-Lab/2016-03/\d",
+ "#sha1_url": "8347b9f00c14b864dd3c19a1f5ae52adb2ef00de",
+
+ "chapter" : "2016-03",
+ "count" : 9,
+ "extension": "",
+ "filename" : r"re:\d",
+ "manga" : "Renai Lab 恋愛ラボ",
+},
+
+{
+ "#url" : "https://raw.senmanga.com/akabane-honeko-no-bodyguard/1",
+ "#category": ("", "senmanga", "chapter"),
+ "#class" : senmanga.SenmangaChapterExtractor,
+ "#pattern" : r"https://i\d\.wp\.com/kumacdn.club/image-new-2/a/akabane-honeko-no-bodyguard/chapter-1/\d+-[0-9a-f]{13}\.jpg",
+
+ "chapter" : "1",
+ "count" : 65,
+ "extension": "jpg",
+ "filename" : r"re:\d+-\w+",
+ "manga" : "Akabane Honeko no Bodyguard",
+},
+
+{
+ "#url" : "https://raw.senmanga.com/amama-cinderella/3",
+ "#comment" : "no http scheme ()",
+ "#category": ("", "senmanga", "chapter"),
+ "#class" : senmanga.SenmangaChapterExtractor,
+ "#pattern" : r"^https://kumacdn.club/image-new-2/a/amama-cinderella/chapter-3/.+\.jpg",
+ "#count" : 30,
+},
+
+)
diff --git a/test/results/sexcom.py b/test/results/sexcom.py
new file mode 100644
index 00000000..079bb5fa
--- /dev/null
+++ b/test/results/sexcom.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import sexcom
+
+
+__tests__ = (
+{
+ "#url" : "https://www.sex.com/pin/21241874-sexy-ecchi-girls-166/",
+ "#comment" : "picture",
+ "#category": ("", "sexcom", "pin"),
+ "#class" : sexcom.SexcomPinExtractor,
+ "#pattern" : "https://cdn.sex.com/images/.+/2014/08/26/7637609.jpg",
+ "#sha1_content": "ebe1814dadfebf15d11c6af4f6afb1a50d6c2a1c",
+
+ "comments" : int,
+ "date" : "dt:2014-10-19 15:45:44",
+ "extension": "jpg",
+ "filename" : "7637609",
+ "likes" : int,
+ "pin_id" : 21241874,
+ "repins" : int,
+ "tags" : list,
+ "thumbnail": str,
+ "title" : "Sexy Ecchi Girls 166",
+ "type" : "picture",
+ "uploader" : "mangazeta",
+ "url" : str,
+},
+
+{
+ "#url" : "https://www.sex.com/pin/55435122-ecchi/",
+ "#comment" : "gif",
+ "#category": ("", "sexcom", "pin"),
+ "#class" : sexcom.SexcomPinExtractor,
+ "#pattern" : "https://cdn.sex.com/images/.+/2017/12/07/18760842.gif",
+ "#sha1_content": "176cc63fa05182cb0438c648230c0f324a5965fe",
+},
+
+{
+ "#url" : "https://www.sex.com/pin/55748341/",
+ "#comment" : "video",
+ "#category": ("", "sexcom", "pin"),
+ "#class" : sexcom.SexcomPinExtractor,
+ "#pattern" : r"https://cdn\.sex\.com/videos/pinporn/2018/02/10/776229_hd\.mp4",
+ "#sha1_content": "e1a5834869163e2c4d1ca2677f5b7b367cf8cfff",
+},
+
+{
+ "#url" : "https://www.sex.com/pin/55847384-very-nicely-animated/",
+ "#comment" : "pornhub embed",
+ "#category": ("", "sexcom", "pin"),
+ "#class" : sexcom.SexcomPinExtractor,
+ "#pattern" : "ytdl:https://www.pornhub.com/embed/ph56ef24b6750f2",
+},
+
+{
+ "#url" : "https://www.sex.com/pin/21241874/#related",
+ "#category": ("", "sexcom", "related-pin"),
+ "#class" : sexcom.SexcomRelatedPinExtractor,
+ "#count" : ">= 20",
+},
+
+{
+ "#url" : "https://www.sex.com/user/sirjuan79/pins/",
+ "#category": ("", "sexcom", "pins"),
+ "#class" : sexcom.SexcomPinsExtractor,
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://www.sex.com/user/ronin17/exciting-hentai/",
+ "#category": ("", "sexcom", "board"),
+ "#class" : sexcom.SexcomBoardExtractor,
+ "#count" : ">= 15",
+},
+
+{
+ "#url" : "https://www.sex.com/search/pics?query=ecchi",
+ "#category": ("", "sexcom", "search"),
+ "#class" : sexcom.SexcomSearchExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.sex.com/videos/hentai/",
+ "#category": ("", "sexcom", "search"),
+ "#class" : sexcom.SexcomSearchExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.sex.com/pics/?sort=popular&sub=all&page=1",
+ "#category": ("", "sexcom", "search"),
+ "#class" : sexcom.SexcomSearchExtractor,
+},
+
+)
diff --git a/test/results/simplyhentai.py b/test/results/simplyhentai.py
new file mode 100644
index 00000000..561ce426
--- /dev/null
+++ b/test/results/simplyhentai.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import simplyhentai
+from gallery_dl import exception
+
+
+__tests__ = (
+{
+ "#url" : "https://original-work.simply-hentai.com/amazon-no-hiyaku-amazon-elixir",
+ "#category": ("", "simplyhentai", "gallery"),
+ "#class" : simplyhentai.SimplyhentaiGalleryExtractor,
+ "#sha1_url" : "21613585ae5ec2f69ea579e9713f536fceab5bd5",
+ "#sha1_metadata": "9e87a0973553b2922ddee37958b8f5d87910af72",
+},
+
+{
+ "#url" : "https://www.simply-hentai.com/notfound",
+ "#category": ("", "simplyhentai", "gallery"),
+ "#class" : simplyhentai.SimplyhentaiGalleryExtractor,
+ "#exception": exception.GalleryDLException,
+},
+
+{
+ "#url" : "https://pokemon.simply-hentai.com/mao-friends-9bc39",
+ "#comment" : "custom subdomain",
+ "#category": ("", "simplyhentai", "gallery"),
+ "#class" : simplyhentai.SimplyhentaiGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.simply-hentai.com/vocaloid/black-magnet",
+ "#comment" : "www subdomain, two path segments",
+ "#category": ("", "simplyhentai", "gallery"),
+ "#class" : simplyhentai.SimplyhentaiGalleryExtractor,
+},
+
+{
+ "#url" : "https://www.simply-hentai.com/image/pheromomania-vol-1-kanzenban-isao-3949d8b3-400c-4b6",
+ "#category": ("", "simplyhentai", "image"),
+ "#class" : simplyhentai.SimplyhentaiImageExtractor,
+ "#sha1_url" : "3d8eb55240a960134891bd77fe1df7988fcdc455",
+ "#sha1_metadata": "e10e5588481cab68329ef6ec1e5325206b2079a2",
+},
+
+{
+ "#url" : "https://www.simply-hentai.com/gif/8915dfcf-0b6a-47c",
+ "#category": ("", "simplyhentai", "image"),
+ "#class" : simplyhentai.SimplyhentaiImageExtractor,
+ "#sha1_url" : "f73916527211b4a40f26568ee26cd8999f5f4f30",
+ "#sha1_metadata": "f94d775177fed918759c8a78a50976f867425b48",
+},
+
+{
+ "#url" : "https://videos.simply-hentai.com/creamy-pie-episode-02",
+ "#category": ("", "simplyhentai", "video"),
+ "#class" : simplyhentai.SimplyhentaiVideoExtractor,
+ "#options" : {"verify": False},
+ "#pattern" : r"https://www\.googleapis\.com/drive/v3/files/0B1ecQ8ZVLm3JcHZzQzBnVy1ZUmc\?alt=media&key=[\w-]+",
+ "#count" : 1,
+ "#sha1_metadata": "706790708b14773efc1e075ddd3b738a375348a5",
+},
+
+{
+ "#url" : "https://videos.simply-hentai.com/1715-tifa-in-hentai-gang-bang-3d-movie",
+ "#category": ("", "simplyhentai", "video"),
+ "#class" : simplyhentai.SimplyhentaiVideoExtractor,
+ "#sha1_url" : "ad9a36ae06c601b6490e3c401834b4949d947eb0",
+ "#sha1_metadata": "f9dad94fbde9c95859e631ff4f07297a9567b874",
+},
+
+)
diff --git a/test/results/skeb.py b/test/results/skeb.py
new file mode 100644
index 00000000..f956986b
--- /dev/null
+++ b/test/results/skeb.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import skeb
+
+
+__tests__ = (
+{
+ "#url" : "https://skeb.jp/@kanade_cocotte/works/38",
+ "#category": ("", "skeb", "post"),
+ "#class" : skeb.SkebPostExtractor,
+ "#count" : 2,
+
+ "anonymous" : False,
+ "body" : r"re:はじめまして。私はYouTubeにてVTuberとして活動をしている湊ラ",
+ "client" : {
+ "avatar_url" : r"re:https://pbs.twimg.com/profile_images/\d+/\w+\.jpg",
+ "header_url" : r"re:https://pbs.twimg.com/profile_banners/1375007870291300358/\d+/1500x500",
+ "id" : 1196514,
+ "name" : str,
+ "screen_name": "minato_ragi",
+ },
+ "content_category": "preview",
+ "creator" : {
+ "avatar_url" : "https://pbs.twimg.com/profile_images/1225470417063645184/P8_SiB0V.jpg",
+ "header_url" : "https://pbs.twimg.com/profile_banners/71243217/1647958329/1500x500",
+ "id" : 159273,
+ "name" : "イチノセ奏",
+ "screen_name": "kanade_cocotte",
+ },
+ "file_id" : int,
+ "file_url" : str,
+ "genre" : "art",
+ "nsfw" : False,
+ "original" : {
+ "byte_size" : int,
+ "duration" : None,
+ "extension" : r"re:psd|png",
+ "frame_rate": None,
+ "height" : 3727,
+ "is_movie" : False,
+ "width" : 2810,
+ },
+ "post_num" : "38",
+ "post_url" : "https://skeb.jp/@kanade_cocotte/works/38",
+ "source_body" : None,
+ "source_thanks" : None,
+ "tags" : list,
+ "thanks" : None,
+ "translated_body" : False,
+ "translated_thanks": None,
+},
+
+{
+ "#url" : "https://skeb.jp/@kanade_cocotte",
+ "#category": ("", "skeb", "user"),
+ "#class" : skeb.SkebUserExtractor,
+ "#pattern" : r"https://skeb\.imgix\.net/uploads/origins/[\w-]+\?bg=%23fff&auto=format&txtfont=bold&txtshad=70&txtclr=BFFFFFFF&txtalign=middle%2Ccenter&txtsize=150&txt=SAMPLE&fm=webp&w=800&s=\w+",
+ "#range" : "1-5",
+},
+
+{
+ "#url" : "https://skeb.jp/search?q=bunny%20tree&t=works",
+ "#category": ("", "skeb", "search"),
+ "#class" : skeb.SkebSearchExtractor,
+ "#count" : ">= 18",
+
+ "search_tags": "bunny tree",
+},
+
+{
+ "#url" : "https://skeb.jp/@user/following_creators",
+ "#category": ("", "skeb", "following"),
+ "#class" : skeb.SkebFollowingExtractor,
+},
+
+)
diff --git a/test/results/slickpic.py b/test/results/slickpic.py
new file mode 100644
index 00000000..ff1eb1ff
--- /dev/null
+++ b/test/results/slickpic.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import slickpic
+
+
+__tests__ = (
+{
+ "#url" : "https://mattcrandall.slickpic.com/albums/LamborghiniMurcielago/",
+ "#category": ("", "slickpic", "album"),
+ "#class" : slickpic.SlickpicAlbumExtractor,
+ "#pattern" : r"https://stored-cf\.slickpic\.com/NDk5MjNmYTc1MzU0MQ,,/20160807/\w+/p/o/JSBFSS-\d+\.jpg",
+ "#count" : 102,
+ "#sha1_metadata": "c37c4ce9c54c09abc6abdf295855d46f11529cbf",
+},
+
+{
+ "#url" : "https://mattcrandall.slickpic.com/albums/LamborghiniMurcielago/",
+ "#category": ("", "slickpic", "album"),
+ "#class" : slickpic.SlickpicAlbumExtractor,
+ "#range" : "34",
+ "#sha1_content": [
+ "276eb2c902187bb177ae8013e310e1d6641fba9a",
+ "52b5a310587de1048030ab13a912f6a3a9cc7dab",
+ "cec6630e659dc72db1ee1a9a6f3b525189261988",
+ "6f81e1e74c6cd6db36844e7211eef8e7cd30055d",
+ "22e83645fc242bc3584eca7ec982c8a53a4d8a44",
+ ],
+},
+
+{
+ "#url" : "https://mattcrandall.slickpic.com/gallery/",
+ "#category": ("", "slickpic", "user"),
+ "#class" : slickpic.SlickpicUserExtractor,
+ "#pattern" : slickpic.SlickpicAlbumExtractor.pattern,
+ "#count" : ">= 358",
+},
+
+{
+ "#url" : "https://mattcrandall.slickpic.com/",
+ "#category": ("", "slickpic", "user"),
+ "#class" : slickpic.SlickpicUserExtractor,
+},
+
+)
diff --git a/test/results/slideshare.py b/test/results/slideshare.py
new file mode 100644
index 00000000..561f0676
--- /dev/null
+++ b/test/results/slideshare.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import slideshare
+
+
+__tests__ = (
+{
+ "#url" : "https://www.slideshare.net/Slideshare/get-started-with-slide-share",
+ "#category": ("", "slideshare", "presentation"),
+ "#class" : slideshare.SlidesharePresentationExtractor,
+ "#pattern" : r"https://image\.slidesharecdn\.com/getstartedwithslideshare-150520173821-lva1-app6892/95/get-started-with-slide-share-\d+-1024\.jpg\?cb=\d+",
+ "#count" : 19,
+ "#sha1_content": "2b6a191eab60b3978fdacfecf2da302dd45bc108",
+
+ "description" : "Get Started with SlideShare - A Beginngers Guide for Creators",
+ "likes" : int,
+ "presentation": "get-started-with-slide-share",
+ "date" : "dt:2015-05-20 17:38:21",
+ "title" : "Getting Started With SlideShare",
+ "user" : "Slideshare",
+ "views" : int,
+},
+
+{
+ "#url" : "https://www.slideshare.net/pragmaticsolutions/warum-sie-nicht-ihren-mitarbeitenden-ndern-sollten-sondern-ihr-managementsystem",
+ "#comment" : "long title and description",
+ "#category": ("", "slideshare", "presentation"),
+ "#class" : slideshare.SlidesharePresentationExtractor,
+ "#sha1_url": "d8952260f8bec337dd809a958ec8091350393f6b",
+
+ "title" : "Warum Sie nicht Ihren Mitarbeitenden ändern sollten, sondern Ihr Managementsystem",
+ "description": "Mitarbeitende verhalten sich mehrheitlich so, wie das System es ihnen vorgibt. Welche Voraussetzungen es braucht, damit Ihre Mitarbeitenden ihr ganzes Herzblut einsetzen, bespricht Fredi Schmidli in diesem Referat.",
+},
+
+{
+ "#url" : "https://www.slideshare.net/mobile/uqudent/introduction-to-fixed-prosthodontics",
+ "#comment" : "mobile URL",
+ "#category": ("", "slideshare", "presentation"),
+ "#class" : slideshare.SlidesharePresentationExtractor,
+ "#sha1_url": "72c431cb1eccbb6794f608ecbbc01d52e8768159",
+},
+
+)
diff --git a/test/results/smugloli.py b/test/results/smugloli.py
new file mode 100644
index 00000000..5d044123
--- /dev/null
+++ b/test/results/smugloli.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import vichan
+
+
+__tests__ = (
+{
+ "#url" : "https://smuglo.li/a/res/1154380.html",
+ "#category": ("vichan", "smugloli", "thread"),
+ "#class" : vichan.VichanThreadExtractor,
+ "#pattern" : r"https://smug.+/a/src/\d+(-\d)?\.\w+",
+ "#count" : ">= 18",
+
+ "board" : "a",
+ "thread": "1154380",
+ "title" : "Mob Psycho 100 Season 3",
+},
+
+{
+ "#url" : "https://smugloli.net/a/res/1145409.html",
+ "#category": ("vichan", "smugloli", "thread"),
+ "#class" : vichan.VichanThreadExtractor,
+},
+
+{
+ "#url" : "https://smuglo.li/a",
+ "#category": ("vichan", "smugloli", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+ "#pattern" : vichan.VichanThreadExtractor.pattern,
+ "#count" : ">= 100",
+},
+
+{
+ "#url" : "https://smuglo.li/a/1.html",
+ "#category": ("vichan", "smugloli", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+},
+
+{
+ "#url" : "https://smugloli.net/cute/catalog.html",
+ "#category": ("vichan", "smugloli", "board"),
+ "#class" : vichan.VichanBoardExtractor,
+},
+
+)
diff --git a/test/results/smugmug.py b/test/results/smugmug.py
new file mode 100644
index 00000000..fd30a6b9
--- /dev/null
+++ b/test/results/smugmug.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import smugmug
+
+
+__tests__ = (
+{
+ "#url" : "smugmug:album:cr4C7f",
+ "#category": ("", "smugmug", "album"),
+ "#class" : smugmug.SmugmugAlbumExtractor,
+ "#sha1_url": "2c2e576e47d4e9ce60b44871f08a8c66b5ebaceb",
+},
+
+{
+ "#url" : "smugmug:album:Fb7hMs",
+ "#comment" : "empty",
+ "#category": ("", "smugmug", "album"),
+ "#class" : smugmug.SmugmugAlbumExtractor,
+ "#count" : 0,
+},
+
+{
+ "#url" : "smugmug:album:6VRT8G",
+ "#comment" : "no 'User'",
+ "#category": ("", "smugmug", "album"),
+ "#class" : smugmug.SmugmugAlbumExtractor,
+ "#sha1_url": "c4a0f4c4bfd514b93cbdeb02b3345bf7ef6604df",
+},
+
+{
+ "#url" : "https://tdm.smugmug.com/Nature/Dove/i-kCsLJT6",
+ "#category": ("", "smugmug", "image"),
+ "#class" : smugmug.SmugmugImageExtractor,
+ "#sha1_url" : "e6408fd2c64e721fd146130dceb56a971ceb4259",
+ "#sha1_metadata": "b31a63d07c9c26eb0f79f52d60d171a98938f99b",
+ "#sha1_content" : "ecbd9d7b4f75a637abc8d35319be9ec065a44eb0",
+},
+
+{
+ "#url" : "https://tstravels.smugmug.com/Dailies/Daily-Dose-2015/i-39JFNzB",
+ "#comment" : "video",
+ "#category": ("", "smugmug", "image"),
+ "#class" : smugmug.SmugmugImageExtractor,
+ "#sha1_url" : "04d0ab1ff829ca7d78f5acb5548953df08e9a5ee",
+ "#sha1_metadata": "2b545184592c282b365fcbb7df6ca7952b8a3173",
+},
+
+{
+ "#url" : "https://tdm.smugmug.com/Nature/Dove",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+ "#pattern" : "smugmug:album:cr4C7f$",
+},
+
+{
+ "#url" : "https://tdm.smugmug.com/",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+ "#pattern" : smugmug.SmugmugAlbumExtractor.pattern,
+ "#sha1_url": "1640028712875b90974e5aecd91b60e6de6138c7",
+},
+
+{
+ "#url" : "https://www.smugmug.com/gallery/n-GLCjnD/",
+ "#comment" : "gallery node without owner",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+ "#pattern" : "smugmug:album:6VRT8G$",
+},
+
+{
+ "#url" : "smugmug:www.sitkapics.com/TREES-and-TRAILS/",
+ "#comment" : "custom domain",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+ "#pattern" : "smugmug:album:ct8Nds$",
+},
+
+{
+ "#url" : "smugmug:www.sitkapics.com/",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+ "#pattern" : r"smugmug:album:\w{6}$",
+ "#count" : ">= 14",
+},
+
+{
+ "#url" : "smugmug:https://www.sitkapics.com/",
+ "#category": ("", "smugmug", "path"),
+ "#class" : smugmug.SmugmugPathExtractor,
+},
+
+)
diff --git a/test/results/soundgasm.py b/test/results/soundgasm.py
new file mode 100644
index 00000000..16f0a17c
--- /dev/null
+++ b/test/results/soundgasm.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import soundgasm
+
+
+__tests__ = (
+{
+ "#url" : "https://soundgasm.net/u/ClassWarAndPuppies2/687-Otto-von-Toontown-12822",
+ "#category": ("", "soundgasm", "audio"),
+ "#class" : soundgasm.SoundgasmAudioExtractor,
+ "#pattern" : r"https://media\.soundgasm\.net/sounds/26cb2b23b2f2c6094b40ee3a9167271e274b570a\.m4a",
+
+ "description": "We celebrate today’s important prisoner swap, and finally bring the 2022 mid-terms to a close with Raphael Warnock’s defeat of Herschel Walker in Georgia. Then, we take a look at the Qanon-addled attempt to overthrow the German government and install Heinrich XIII Prince of Reuss as kaiser.",
+ "extension" : "m4a",
+ "filename" : "26cb2b23b2f2c6094b40ee3a9167271e274b570a",
+ "slug" : "687-Otto-von-Toontown-12822",
+ "title" : "687 - Otto von Toontown (12/8/22)",
+ "user" : "ClassWarAndPuppies2",
+},
+
+{
+ "#url" : "https://www.soundgasm.net/user/ClassWarAndPuppies2/687-Otto-von-Toontown-12822",
+ "#category": ("", "soundgasm", "audio"),
+ "#class" : soundgasm.SoundgasmAudioExtractor,
+},
+
+{
+ "#url" : "https://soundgasm.net/u/fierce-aphrodite",
+ "#category": ("", "soundgasm", "user"),
+ "#class" : soundgasm.SoundgasmUserExtractor,
+ "#pattern" : r"https://media\.soundgasm\.net/sounds/[0-9a-f]{40}\.m4a",
+ "#count" : ">= 15",
+
+ "description": str,
+ "extension" : "m4a",
+ "filename" : r"re:^[0-9a-f]{40}$",
+ "slug" : str,
+ "title" : str,
+ "url" : str,
+ "user" : "fierce-aphrodite",
+},
+
+)
diff --git a/test/results/speakerdeck.py b/test/results/speakerdeck.py
new file mode 100644
index 00000000..5e63a4cb
--- /dev/null
+++ b/test/results/speakerdeck.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import speakerdeck
+
+
+__tests__ = (
+{
+ "#url" : "https://speakerdeck.com/speakerdeck/introduction-to-speakerdeck",
+ "#category": ("", "speakerdeck", "presentation"),
+ "#class" : speakerdeck.SpeakerdeckPresentationExtractor,
+ "#pattern" : r"https://files.speakerdeck.com/presentations/50021f75cf1db900020005e7/slide_\d+.jpg",
+ "#count" : 6,
+ "#sha1_content": "75c7abf0969b0bcab23e0da9712c95ee5113db3a",
+},
+
+)
diff --git a/test/results/subscribestar.py b/test/results/subscribestar.py
new file mode 100644
index 00000000..8fe6d8dc
--- /dev/null
+++ b/test/results/subscribestar.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+
+from gallery_dl.extractor import subscribestar
+import datetime
+
+
+__tests__ = (
+{
+ "#url" : "https://www.subscribestar.com/subscribestar",
+ "#category": ("", "subscribestar", "user"),
+ "#class" : subscribestar.SubscribestarUserExtractor,
+ "#pattern" : r"https://(ss-uploads-prod\.b-cdn|\w+\.cloudfront)\.net/uploads(_v2)?/users/11/",
+ "#count" : ">= 20",
+
+ "author_id" : 11,
+ "author_name": "subscribestar",
+ "author_nick": "SubscribeStar",
+ "content" : str,
+ "date" : datetime.datetime,
+ "id" : int,
+ "num" : int,
+ "post_id" : int,
+ "type" : r"re:image|video|attachment",
+ "url" : str,
+ "?pinned" : bool,
+},
+
+{
+ "#url" : "https://www.subscribestar.com/subscribestar",
+ "#category": ("", "subscribestar", "user"),
+ "#class" : subscribestar.SubscribestarUserExtractor,
+ "#options" : {"metadata": True},
+ "#range" : "1",
+
+ "date": datetime.datetime,
+},
+
+{
+ "#url" : "https://subscribestar.adult/kanashiipanda",
+ "#category": ("", "subscribestar", "user-adult"),
+ "#class" : subscribestar.SubscribestarUserExtractor,
+ "#range" : "1-10",
+ "#count" : 10,
+},
+
+{
+ "#url" : "https://www.subscribestar.com/posts/102468",
+ "#category": ("", "subscribestar", "post"),
+ "#class" : subscribestar.SubscribestarPostExtractor,
+ "#count" : 1,
+
+ "author_id" : 11,
+ "author_name": "subscribestar",
+ "author_nick": "SubscribeStar",
+ "content" : r"re:
(flex)
+""", + "favorites" : int, + "folder_name" : "Wesley Stuff", + "folderid" : 2081, + "friends_only": False, + "owner" : "Fiz", + "owner_login" : "fiz", + "rating" : "general", + "submitid" : 2031, + "subtype" : "visual", + "tags" : list, + "title" : "A Wesley!", + "type" : "submission", + "views" : int, +}, + +{ + "#url" : "https://www.weasyl.com/submission/2031/a-wesley", + "#category": ("", "weasyl", "submission"), + "#class" : weasyl.WeasylSubmissionExtractor, +}, + +{ + "#url" : "https://www.weasyl.com/~tanidareal", + "#category": ("", "weasyl", "submissions"), + "#class" : weasyl.WeasylSubmissionsExtractor, + "#count" : ">= 200", +}, + +{ + "#url" : "https://www.weasyl.com/submissions/tanidareal", + "#category": ("", "weasyl", "submissions"), + "#class" : weasyl.WeasylSubmissionsExtractor, +}, + +{ + "#url" : "https://www.weasyl.com/~aro~so", + "#category": ("", "weasyl", "submissions"), + "#class" : weasyl.WeasylSubmissionsExtractor, +}, + +{ + "#url" : "https://www.weasyl.com/submissions/tanidareal?folderid=7403", + "#category": ("", "weasyl", "folder"), + "#class" : weasyl.WeasylFolderExtractor, + "#count" : ">= 12", +}, + +{ + "#url" : "https://www.weasyl.com/journal/17647/bbcode", + "#category": ("", "weasyl", "journal"), + "#class" : weasyl.WeasylJournalExtractor, + + "title" : "BBCode", + "date" : "dt:2013-09-19 23:11:23", + "content": """ + +No more of that!
+""", +}, + +{ + "#url" : "https://www.weasyl.com/journals/charmander", + "#category": ("", "weasyl", "journals"), + "#class" : weasyl.WeasylJournalsExtractor, + "#count" : ">= 2", +}, + +{ + "#url" : "https://www.weasyl.com/favorites?userid=184616&feature=submit", + "#category": ("", "weasyl", "favorite"), + "#class" : weasyl.WeasylFavoriteExtractor, + "#count" : ">= 5", +}, + +) diff --git a/test/results/webmshare.py b/test/results/webmshare.py new file mode 100644 index 00000000..007a12b4 --- /dev/null +++ b/test/results/webmshare.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import webmshare + + +__tests__ = ( +{ + "#url" : "https://webmshare.com/O9mWY", + "#category": ("", "webmshare", "video"), + "#class" : webmshare.WebmshareVideoExtractor, + + "date" : "dt:2022-12-04 00:00:00", + "extension": "webm", + "filename" : "O9mWY", + "height" : 568, + "id" : "O9mWY", + "thumb" : "https://s1.webmshare.com/t/O9mWY.jpg", + "title" : "Yeah buddy over here", + "url" : "https://s1.webmshare.com/O9mWY.webm", + "views" : int, + "width" : 320, +}, + +{ + "#url" : "https://s1.webmshare.com/zBGAg.webm", + "#category": ("", "webmshare", "video"), + "#class" : webmshare.WebmshareVideoExtractor, + + "date" : "dt:2018-12-07 00:00:00", + "height": 1080, + "id" : "zBGAg", + "thumb" : "https://s1.webmshare.com/t/zBGAg.jpg", + "title" : "", + "url" : "https://s1.webmshare.com/zBGAg.webm", + "views" : int, + "width" : 1920, +}, + +{ + "#url" : "https://webmshare.com/play/zBGAg", + "#category": ("", "webmshare", "video"), + "#class" : webmshare.WebmshareVideoExtractor, +}, + +{ + "#url" : "https://webmshare.com/download-webm/zBGAg", + "#category": ("", "webmshare", "video"), + "#class" : webmshare.WebmshareVideoExtractor, +}, + +) diff --git a/test/results/webtoons.py b/test/results/webtoons.py new file mode 100644 index 00000000..d2a177fd --- /dev/null +++ b/test/results/webtoons.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import webtoons +from gallery_dl import exception + + +__tests__ = ( +{ + "#url" : "https://www.webtoons.com/en/comedy/safely-endangered/ep-572-earth/viewer?title_no=352&episode_no=572", + "#category": ("", "webtoons", "episode"), + "#class" : webtoons.WebtoonsEpisodeExtractor, + "#count" : 5, + "#sha1_url" : "55bec5d7c42aba19e3d0d56db25fdf0b0b13be38", + "#sha1_content": [ + "1748c7e82b6db910fa179f6dc7c4281b0f680fa7", + "42055e44659f6ffc410b3fb6557346dfbb993df3", + "49e1f2def04c6f7a6a3dacf245a1cd9abe77a6a9", + ], +}, + +{ + "#url" : "https://www.webtoons.com/en/challenge/punderworld/happy-earth-day-/viewer?title_no=312584&episode_no=40", + "#category": ("", "webtoons", "episode"), + "#class" : webtoons.WebtoonsEpisodeExtractor, + "#exception": exception.NotFoundError, + + "comic" : "punderworld", + "description": str, + "episode" : "36", + "episode_no" : "40", + "genre" : "challenge", + "title" : r"re:^Punderworld - .+", + "title_no" : "312584", +}, + +{ + "#url" : "https://www.webtoons.com/en/comedy/live-with-yourself/list?title_no=919", + "#comment" : "english", + "#category": ("", "webtoons", "comic"), + "#class" : webtoons.WebtoonsComicExtractor, + "#pattern" : webtoons.WebtoonsEpisodeExtractor.pattern, + "#range" : "1-15", + "#count" : ">= 15", +}, + +{ + "#url" : "https://www.webtoons.com/fr/romance/subzero/list?title_no=1845&page=3", + "#comment" : "french", + "#category": ("", "webtoons", "comic"), + "#class" : webtoons.WebtoonsComicExtractor, + "#count" : ">= 15", +}, + +{ + "#url" : "https://www.webtoons.com/en/challenge/scoob-and-shag/list?title_no=210827&page=9", + "#comment" : "(#820)", + "#category": ("", "webtoons", "comic"), + "#class" : webtoons.WebtoonsComicExtractor, + "#count" : ">= 18", +}, + +{ + "#url" : "https://www.webtoons.com/es/romance/lore-olympus/list?title_no=1725", + "#comment" : "(#1643)", + "#category": ("", "webtoons", "comic"), + "#class" : webtoons.WebtoonsComicExtractor, +}, + +) diff --git a/test/results/weibo.py b/test/results/weibo.py new file mode 100644 index 00000000..f98b7fd9 --- /dev/null +++ b/test/results/weibo.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import weibo +from gallery_dl import exception + + +__tests__ = ( +{ + "#url" : "https://weibo.com/1758989602", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, + "#pattern" : r"^https://weibo\.com/u/1758989602\?tabtype=feed$", +}, + +{ + "#url" : "https://weibo.com/u/1758989602", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, +}, + +{ + "#url" : "https://weibo.com/p/1758989602", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, +}, + +{ + "#url" : "https://m.weibo.cn/profile/2314621010", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, +}, + +{ + "#url" : "https://m.weibo.cn/p/2304132314621010_-_WEIBO_SECOND_PROFILE_WEIBO", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, +}, + +{ + "#url" : "https://www.weibo.com/p/1003062314621010/home", + "#category": ("", "weibo", "user"), + "#class" : weibo.WeiboUserExtractor, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=home", + "#category": ("", "weibo", "home"), + "#class" : weibo.WeiboHomeExtractor, + "#range" : "1-30", + "#count" : 30, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=feed", + "#category": ("", "weibo", "feed"), + "#class" : weibo.WeiboFeedExtractor, + "#range" : "1-30", + "#count" : 30, +}, + +{ + "#url" : "https://weibo.com/zhouyuxi77?tabtype=feed", + "#category": ("", "weibo", "feed"), + "#class" : weibo.WeiboFeedExtractor, + "#range" : "1", + + "status": {"user": { + "id" : 7488709788, +}}, +}, + +{ + "#url" : "https://www.weibo.com/n/周于希Sally?tabtype=feed", + "#category": ("", "weibo", "feed"), + "#class" : weibo.WeiboFeedExtractor, + "#range" : "1", + + "status": {"user": { + "id" : 7488709788, +}}, +}, + +{ + "#url" : "https://weibo.com/u/7500315942?tabtype=feed", + "#comment" : "deleted (#2521)", + "#category": ("", "weibo", "feed"), + "#class" : weibo.WeiboFeedExtractor, + "#count" : 0, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=video", + "#category": ("", "weibo", "videos"), + "#class" : weibo.WeiboVideosExtractor, + "#pattern" : r"https://f\.(video\.weibocdn\.com|us\.sinaimg\.cn)/(../)?\w+\.mp4\?label=mp", + "#range" : "1-30", + "#count" : 30, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=newVideo", + "#category": ("", "weibo", "newvideo"), + "#class" : weibo.WeiboNewvideoExtractor, + "#pattern" : r"https://f\.video\.weibocdn\.com/(../)?\w+\.mp4\?label=mp", + "#range" : "1-30", + "#count" : 30, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=article", + "#category": ("", "weibo", "article"), + "#class" : weibo.WeiboArticleExtractor, + "#count" : 0, +}, + +{ + "#url" : "https://weibo.com/1758989602?tabtype=album", + "#category": ("", "weibo", "album"), + "#class" : weibo.WeiboAlbumExtractor, + "#pattern" : r"https://(wx\d+\.sinaimg\.cn/large/\w{32}\.(jpg|png|gif)|g\.us\.sinaimg\.cn/../\w+\.mp4)", + "#range" : "1-3", + "#count" : 3, +}, + +{ + "#url" : "https://m.weibo.cn/detail/4323047042991618", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#pattern" : r"https?://wx\d+.sinaimg.cn/large/\w+.jpg", + + "status": { + "count": 1, + "date" : "dt:2018-12-30 13:56:36", + }, +}, + +{ + "#url" : "https://m.weibo.cn/detail/4339748116375525", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#pattern" : r"https?://f.us.sinaimg.cn/\w+\.mp4\?label=mp4_1080p", +}, + +{ + "#url" : "https://m.weibo.cn/status/4268682979207023", + "#comment" : "unavailable video (#427)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#exception": exception.NotFoundError, +}, + +{ + "#url" : "https://weibo.com/3314883543/Iy7fj4qVg", + "#comment" : "non-numeric status ID (#664)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, +}, + +{ + "#url" : "https://m.weibo.cn/detail/4600272267522211", + "#comment" : "original retweets (#1542)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#options" : {"retweets": "original"}, + + "status": {"id": 4600167083287033}, +}, + +{ + "#url" : "https://weibo.com/5643044717/KkuDZ4jAA", + "#comment" : "type == livephoto (#2146)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#pattern" : r"https://video\.weibo\.com/media/play\?livephoto=https%3A%2F%2Fus.sinaimg.cn%2F\w+\.mov", + "#range" : "2,4,6", +}, + +{ + "#url" : "https://weibo.com/1758989602/LvBhm5DiP", + "#comment" : "type == gif", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#pattern" : r"https://g\.us\.sinaimg.cn/o0/qNZcaAAglx07Wuf921CM0104120005tc0E010\.mp4\?label=gif_mp4", +}, + +{ + "#url" : "https://weibo.com/2909128931/4409545658754086", + "#comment" : "missing 'playback_list' (#2792)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#count" : 10, +}, + +{ + "#url" : "https://weibo.com/1501933722/4142890299009993", + "#comment" : "empty 'playback_list' (#3301)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#pattern" : r"https://f\.us\.sinaimg\.cn/004zstGKlx07dAHg4ZVu010f01000OOl0k01\.mp4\?label=mp4_hd&template=template_7&ori=0&ps=1CwnkDw1GXwCQx.+&KID=unistore,video", + "#count" : 1, +}, + +{ + "#url" : "https://weibo.com/2427303621/MxojLlLgQ", + "#comment" : "mix_media_info (#3793)", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, + "#count" : 9, +}, + +{ + "#url" : "https://m.weibo.cn/status/4339748116375525", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, +}, + +{ + "#url" : "https://m.weibo.cn/5746766133/4339748116375525", + "#category": ("", "weibo", "status"), + "#class" : weibo.WeiboStatusExtractor, +}, + +) diff --git a/test/results/wikiart.py b/test/results/wikiart.py new file mode 100644 index 00000000..fef4bad5 --- /dev/null +++ b/test/results/wikiart.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import wikiart + + +__tests__ = ( +{ + "#url" : "https://www.wikiart.org/en/thomas-cole", + "#category": ("", "wikiart", "artist"), + "#class" : wikiart.WikiartArtistExtractor, + "#sha1_url" : "6844f207a5063c499fc1d5651b03127bc4fe2f73", + "#sha1_metadata": "09230b5f504697119e267349bf92487e657a7384", +}, + +{ + "#url" : "https://www.wikiart.org/en/thomas-cole/the-departure-1838", + "#category": ("", "wikiart", "image"), + "#class" : wikiart.WikiartImageExtractor, + "#sha1_url" : "976cc2545f308a650b5dbb35c29d3cee0f4673b3", + "#sha1_metadata": "8e80cdcb01c1fedb934633d1c4c3ab0419cfbedf", +}, + +{ + "#url" : "https://www.wikiart.org/en/huang-shen/summer", + "#comment" : "no year or '-' in slug", + "#category": ("", "wikiart", "image"), + "#class" : wikiart.WikiartImageExtractor, + "#sha1_url": "d7f60118c34067b2b37d9577e412dc1477b94207", +}, + +{ + "#url" : "https://www.wikiart.org/en/paintings-by-media/grisaille", + "#category": ("", "wikiart", "artworks"), + "#class" : wikiart.WikiartArtworksExtractor, + "#sha1_url": "36e054fcb3363b7f085c81f4778e6db3994e56a3", +}, + +{ + "#url" : "https://www.wikiart.org/en/artists-by-century/12", + "#category": ("", "wikiart", "artists"), + "#class" : wikiart.WikiartArtistsExtractor, + "#pattern" : wikiart.WikiartArtistExtractor.pattern, + "#count" : ">= 8", +}, + +) diff --git a/test/results/wikieat.py b/test/results/wikieat.py new file mode 100644 index 00000000..f3c0d7f4 --- /dev/null +++ b/test/results/wikieat.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import vichan + + +__tests__ = ( +{ + "#url" : "https://wikieat.club/cel/res/25321.html", + "#category": ("vichan", "wikieat", "thread"), + "#class" : vichan.VichanThreadExtractor, + "#pattern" : r"https://wikieat\.club/cel/src/\d+(-\d)?\.\w+", + "#count" : ">= 200", +}, + +{ + "#url" : "https://wikieat.club/cel/index.html", + "#category": ("vichan", "wikieat", "board"), + "#class" : vichan.VichanBoardExtractor, + "#pattern" : vichan.VichanThreadExtractor.pattern, + "#count" : ">= 100", +}, + +{ + "#url" : "https://wikieat.club/cel/catalog.html", + "#category": ("vichan", "wikieat", "board"), + "#class" : vichan.VichanBoardExtractor, +}, + +{ + "#url" : "https://wikieat.club/cel/2.html", + "#category": ("vichan", "wikieat", "board"), + "#class" : vichan.VichanBoardExtractor, +}, + +) diff --git a/test/results/wikifeet.py b/test/results/wikifeet.py new file mode 100644 index 00000000..dade42e7 --- /dev/null +++ b/test/results/wikifeet.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import wikifeet + + +__tests__ = ( +{ + "#url" : "https://www.wikifeet.com/Madison_Beer", + "#category": ("", "wikifeet", "gallery"), + "#class" : wikifeet.WikifeetGalleryExtractor, + "#pattern" : r"https://pics\.wikifeet\.com/Madison_Beer-Feet-\d+\.jpg", + "#count" : ">= 352", + + "celeb" : "Madison_Beer", + "celebrity" : "Madison Beer", + "birthday" : "dt:1999-03-05 00:00:00", + "birthplace": "United States", + "rating" : float, + "pid" : int, + "width" : int, + "height" : int, + "shoesize" : "9 US", + "type" : "women", + "tags" : list, +}, + +{ + "#url" : "https://men.wikifeet.com/Chris_Hemsworth", + "#category": ("", "wikifeet", "gallery"), + "#class" : wikifeet.WikifeetGalleryExtractor, + "#pattern" : r"https://pics\.wikifeet\.com/Chris_Hemsworth-Feet-\d+\.jpg", + "#count" : ">= 860", + + "celeb" : "Chris_Hemsworth", + "celebrity" : "Chris Hemsworth", + "birthday" : "dt:1983-08-11 00:00:00", + "birthplace": "Australia", + "rating" : float, + "pid" : int, + "width" : int, + "height" : int, + "shoesize" : "12.5 US", + "type" : "men", + "tags" : list, +}, + +) diff --git a/test/results/wikifeetx.py b/test/results/wikifeetx.py new file mode 100644 index 00000000..a3d2be6e --- /dev/null +++ b/test/results/wikifeetx.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import wikifeet + + +__tests__ = ( +{ + "#url" : "https://www.wikifeetx.com/Tifa_Quinn", + "#category": ("", "wikifeetx", "gallery"), + "#class" : wikifeet.WikifeetGalleryExtractor, + "#pattern" : r"https://pics\.wikifeet\.com/Tifa_Quinn-Feet-\d+\.jpg", + "#count" : ">= 9", + + "celeb" : "Tifa_Quinn", + "celebrity" : "Tifa Quinn", + "birthday" : "[NOT SET]", + "birthplace": "United States", + "rating" : float, + "pid" : int, + "width" : int, + "height" : int, + "shoesize" : "4 US", + "type" : "women", + "tags" : list, +}, + +) diff --git a/test/results/windsorstore.py b/test/results/windsorstore.py new file mode 100644 index 00000000..c7cfd698 --- /dev/null +++ b/test/results/windsorstore.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import shopify + + +__tests__ = ( +{ + "#url" : "https://www.windsorstore.com/collections/dresses-ball-gowns", + "#category": ("shopify", "windsorstore", "collection"), + "#class" : shopify.ShopifyCollectionExtractor, +}, + +{ + "#url" : "https://www.windsorstore.com/collections/accessories-belts/products/rhine-buckle-dbl-o-ring-pu-strap-belt-073010158001", + "#category": ("shopify", "windsorstore", "product"), + "#class" : shopify.ShopifyProductExtractor, +}, + +) diff --git a/test/results/xbooru.py b/test/results/xbooru.py new file mode 100644 index 00000000..11160b42 --- /dev/null +++ b/test/results/xbooru.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import gelbooru_v02 + + +__tests__ = ( +{ + "#url" : "https://xbooru.com/index.php?page=post&s=list&tags=konoyan", + "#category": ("gelbooru_v02", "xbooru", "tag"), + "#class" : gelbooru_v02.GelbooruV02TagExtractor, + "#count" : 11, +}, + +{ + "#url" : "https://xbooru.com/index.php?page=pool&s=show&id=757", + "#category": ("gelbooru_v02", "xbooru", "pool"), + "#class" : gelbooru_v02.GelbooruV02PoolExtractor, + "#count" : 5, + "#sha1_url": "ceeac56c179ec72301bd0b6add6355a138fdea01", +}, + +{ + "#url" : "https://xbooru.com/index.php?page=favorites&s=view&id=45206", + "#category": ("gelbooru_v02", "xbooru", "favorite"), + "#class" : gelbooru_v02.GelbooruV02FavoriteExtractor, + "#count" : 4, +}, + +{ + "#url" : "https://xbooru.com/index.php?page=post&s=view&id=1025649", + "#category": ("gelbooru_v02", "xbooru", "post"), + "#class" : gelbooru_v02.GelbooruV02PostExtractor, + "#pattern" : r"https://img\.xbooru\.com/images/444/f3eda549ad8b9db244ac335c7406c92f\.jpeg", + "#sha1_content": "086668afd445438d491ecc11cee3ac69b4d65530", +}, + +) diff --git a/test/results/xbunkr.py b/test/results/xbunkr.py new file mode 100644 index 00000000..a188d2e6 --- /dev/null +++ b/test/results/xbunkr.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import lolisafe + + +__tests__ = ( +{ + "#url" : "https://xbunkr.com/a/TA0bu3F4", + "#category": ("lolisafe", "xbunkr", "album"), + "#class" : lolisafe.LolisafeAlbumExtractor, + "#pattern" : r"https://media\.xbunkr\.com/[^.]+\.\w+", + "#count" : 861, + + "album_id" : "TA0bu3F4", + "album_name": "Hannahowo Onlyfans Photos", +}, + +{ + "#url" : "https://xbunkr.com/a/GNQc2I5d", + "#category": ("lolisafe", "xbunkr", "album"), + "#class" : lolisafe.LolisafeAlbumExtractor, +}, + +) diff --git a/test/results/xhamster.py b/test/results/xhamster.py new file mode 100644 index 00000000..93436d06 --- /dev/null +++ b/test/results/xhamster.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import xhamster + + +__tests__ = ( +{ + "#url" : "https://xhamster.com/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, + "#pattern" : r"https://thumb-p\d+.xhcdn.com/./[\w/-]+_1000.jpg$", + "#count" : ">= 144", + + "comments": int, + "count" : int, + "favorite": bool, + "id" : int, + "num" : int, + "height" : int, + "width" : int, + "imageURL": str, + "pageURL" : str, + "thumbURL": str, + "gallery" : { + "date" : "dt:2019-04-16 00:07:31", + "description": "", + "dislikes" : int, + "id" : 11748968, + "likes" : int, + "tags" : ["NON-Porn"], + "thumbnail" : str, + "title" : "Make the world better.", + "views" : int, + }, + "user" : { + "id" : 16874672, + "name" : "Anonymousrants", + "retired" : bool, + "subscribers": int, + "url" : "https://xhamster.com/users/anonymousrants", + "verified" : bool, + }, +}, + +{ + "#url" : "https://jp.xhamster2.com/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, + "#pattern" : r"https://thumb-p\d+.xhcdn.com/./[\w/-]+_1000.jpg$", + "#count" : ">= 144", +}, + +{ + "#url" : "https://xhamster.com/photos/gallery/make-the-world-better-11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster.com/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster.one/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster.desi/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster2.com/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://en.xhamster.com/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster.porncache.net/photos/gallery/11748968", + "#category": ("", "xhamster", "gallery"), + "#class" : xhamster.XhamsterGalleryExtractor, +}, + +{ + "#url" : "https://xhamster.com/users/goldenpalomino/photos", + "#category": ("", "xhamster", "user"), + "#class" : xhamster.XhamsterUserExtractor, + "#pattern" : xhamster.XhamsterGalleryExtractor.pattern, + "#range" : "1-50", + "#count" : 50, +}, + +{ + "#url" : "https://xhamster.com/users/nickname68", + "#category": ("", "xhamster", "user"), + "#class" : xhamster.XhamsterUserExtractor, +}, + +) diff --git a/test/results/xvideos.py b/test/results/xvideos.py new file mode 100644 index 00000000..d7a682c0 --- /dev/null +++ b/test/results/xvideos.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import xvideos + + +__tests__ = ( +{ + "#url" : "https://www.xvideos.com/profiles/pervertedcouple/photos/751031", + "#category": ("", "xvideos", "gallery"), + "#class" : xvideos.XvideosGalleryExtractor, + "#pattern" : r"https://profile-pics-cdn\d+\.xvideos-cdn\.com/[^/]+\,\d+/videos/profiles/galleries/84/ca/37/pervertedcouple/gal751031/pic_\d+_big\.jpg", + "#count" : 8, + + "gallery": { + "id" : 751031, + "title": "Random Stuff", + "tags" : list, + }, + "user" : { + "id" : 20245371, + "name" : "pervertedcouple", + "display" : "Pervertedcouple", + "sex" : "Woman", + "description": str, + }, +}, + +{ + "#url" : "https://www.xvideos.com/amateur-channels/pervertedcouple/photos/12", + "#category": ("", "xvideos", "gallery"), + "#class" : xvideos.XvideosGalleryExtractor, +}, + +{ + "#url" : "https://www.xvideos.com/model-channels/pervertedcouple/photos/12", + "#category": ("", "xvideos", "gallery"), + "#class" : xvideos.XvideosGalleryExtractor, +}, + +{ + "#url" : "https://www.xvideos.com/profiles/pervertedcouple", + "#category": ("", "xvideos", "user"), + "#class" : xvideos.XvideosUserExtractor, + "#sha1_url" : "a413f3e60d6d3a2de79bd44fa3b7a9c03db4336e", + "#sha1_metadata": "335a3304941ff2e666c0201e9122819b61b34adb", +}, + +{ + "#url" : "https://www.xvideos.com/profiles/pervertedcouple#_tabPhotos", + "#category": ("", "xvideos", "user"), + "#class" : xvideos.XvideosUserExtractor, +}, + +) diff --git a/test/results/yandere.py b/test/results/yandere.py new file mode 100644 index 00000000..3b4d9a96 --- /dev/null +++ b/test/results/yandere.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import moebooru + + +__tests__ = ( +{ + "#url" : "https://yande.re/post/show/51824", + "#category": ("moebooru", "yandere", "post"), + "#class" : moebooru.MoebooruPostExtractor, + "#options" : {"tags": True}, + "#sha1_content": "59201811c728096b2d95ce6896fd0009235fe683", + + "tags_artist" : "sasaki_tamaru", + "tags_circle" : "softhouse_chara", + "tags_copyright": "ouzoku", + "tags_general" : str, +}, + +{ + "#url" : "https://yande.re/post/show/993156", + "#category": ("moebooru", "yandere", "post"), + "#class" : moebooru.MoebooruPostExtractor, + "#options" : {"notes": True}, + "#sha1_content": "fed722bd90f48de41ec163692befc701056e2b1e", + + "notes": [ + { + "id" : 7096, + "x" : 90, + "y" : 626, + "width" : 283, + "height": 529, + "body" : "Please keep this as a secret for me!!", + }, + { + "id" : 7095, + "x" : 900, + "y" : 438, + "width" : 314, + "height": 588, + "body" : "The facts that I love playing games", + }, + ], +}, + +{ + "#url" : "https://yande.re/post?tags=ouzoku+armor", + "#category": ("moebooru", "yandere", "tag"), + "#class" : moebooru.MoebooruTagExtractor, + "#sha1_content": "59201811c728096b2d95ce6896fd0009235fe683", +}, + +{ + "#url" : "https://yande.re/pool/show/318", + "#category": ("moebooru", "yandere", "pool"), + "#class" : moebooru.MoebooruPoolExtractor, + "#sha1_content": "2a35b9d6edecce11cc2918c6dce4de2198342b68", +}, + +{ + "#url" : "https://yande.re/post/popular_by_month?month=6&year=2014", + "#category": ("moebooru", "yandere", "popular"), + "#class" : moebooru.MoebooruPopularExtractor, + "#count" : 40, +}, + +{ + "#url" : "https://yande.re/post/popular_recent", + "#category": ("moebooru", "yandere", "popular"), + "#class" : moebooru.MoebooruPopularExtractor, +}, + +) diff --git a/test/results/ytdl.py b/test/results/ytdl.py new file mode 100644 index 00000000..1aecee91 --- /dev/null +++ b/test/results/ytdl.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import ytdl + + +__tests__ = ( +{ + "#url" : "ytdl:https://www.youtube.com/watch?v=BaW_jenozKc&t=1s&end=9", + "#category": ("", "ytdl", "Youtube"), + "#class" : ytdl.YoutubeDLExtractor, +}, + +) diff --git a/test/results/zerochan.py b/test/results/zerochan.py new file mode 100644 index 00000000..67b9da21 --- /dev/null +++ b/test/results/zerochan.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +from gallery_dl.extractor import zerochan + + +__tests__ = ( +{ + "#url" : "https://www.zerochan.net/Perth+%28Kantai+Collection%29", + "#category": ("booru", "zerochan", "tag"), + "#class" : zerochan.ZerochanTagExtractor, + "#pattern" : r"https://static\.zerochan\.net/.+\.full\.\d+\.(jpg|png)", + "#count" : "> 24", + + "extension" : r"re:jpg|png", + "file_url" : r"re:https://static\.zerochan\.net/.+\.full\.\d+\.(jpg|png)", + "filename" : r"re:(Perth\.\(Kantai\.Collection\)|Kantai\.Collection)\.full\.\d+", + "height" : r"re:^\d+$", + "id" : r"re:^\d+$", + "name" : r"re:(Perth \(Kantai Collection\)|Kantai Collection)", + "search_tags": "Perth (Kantai Collection)", + "size" : r"re:^\d+k$", + "width" : r"re:^\d+$", +}, + +{ + "#url" : "https://www.zerochan.net/2920445", + "#category": ("booru", "zerochan", "image"), + "#class" : zerochan.ZerochanImageExtractor, + "#pattern" : r"https://static\.zerochan\.net/Perth\.%28Kantai\.Collection%29\.full.2920445\.jpg", + + "author" : "YeFan 葉凡", + "date" : "dt:2020-04-24 21:33:44", + "file_url": "https://static.zerochan.net/Perth.%28Kantai.Collection%29.full.2920445.jpg", + "filename": "Perth.(Kantai.Collection).full.2920445", + "height" : 1366, + "id" : 2920445, + "path" : [ + "Kantai Collection", + "Perth (Kantai Collection)", + ], + "size" : 1975296, + "tags" : [ + "Mangaka:YeFan 葉凡", + "Game:Kantai Collection", + "Character:Perth (Kantai Collection)", + "Theme:Blonde Hair", + "Theme:Braids", + "Theme:Coat", + "Theme:Female", + "Theme:Firefighter Outfit", + "Theme:Group", + "Theme:Long Sleeves", + "Theme:Personification", + "Theme:Pins", + "Theme:Ribbon", + "Theme:Shirt", + "Theme:Short Hair", + ], + "uploader": "YukinoTokisaki", + "width" : 1920, +}, + +)