extend '-A / --abort' & '"skip": "abort"' functionality (#7891)

implement ascending by more than 1 level or
up to an extractor with a specific subcategory
This commit is contained in:
Mike Fährmann
2025-07-30 00:01:49 +02:00
parent 64de6605ce
commit 2eb5e52055
5 changed files with 70 additions and 23 deletions

View File

@@ -48,7 +48,7 @@ def main():
if filename == "/O":
filename = "{filename}.{extension}"
elif filename.startswith("\\f"):
filename = "\f" + filename[2:]
filename = f"\f{filename[2:]}"
config.set((), "filename", filename)
if args.directory is not None:
config.set((), "base-directory", args.directory)
@@ -56,9 +56,9 @@ def main():
if args.postprocessors:
config.set((), "postprocessors", args.postprocessors)
if args.abort:
config.set((), "skip", "abort:" + str(args.abort))
config.set((), "skip", f"abort:{args.abort}")
if args.terminate:
config.set((), "skip", "terminate:" + str(args.terminate))
config.set((), "skip", f"terminate:{args.terminate}")
if args.cookies_from_browser:
browser, _, profile = args.cookies_from_browser.partition(":")
browser, _, keyring = browser.partition("+")

View File

@@ -160,6 +160,22 @@ class ControlException(GalleryDLException):
class StopExtraction(ControlException):
"""Stop data extraction"""
def __init__(self, target=None):
ControlException.__init__(self)
if target is None:
self.target = None
self.depth = 1
elif isinstance(target, int):
self.target = None
self.depth = target
elif target.isdecimal():
self.target = None
self.depth = int(target)
else:
self.target = target
self.depth = 128
class AbortExtraction(ExtractionError, ControlException):
"""Abort data extraction due to an error"""

View File

@@ -151,7 +151,10 @@ class Job():
try:
for msg in extractor:
self.dispatch(msg)
except exception.StopExtraction:
except exception.StopExtraction as exc:
if exc.depth > 1 and exc.target != extractor.__class__.subcategory:
exc.depth -= 1
raise
pass
except exception.AbortExtraction as exc:
log.error(exc.message)
@@ -509,7 +512,7 @@ class DownloadJob(Job):
if not self._skipftr or self._skipftr(pathfmt.kwdict):
self._skipcnt += 1
if self._skipcnt >= self._skipmax:
raise self._skipexc()
raise self._skipexc
def download(self, url):
"""Download 'url'"""
@@ -603,7 +606,8 @@ class DownloadJob(Job):
elif isinstance(skip, str):
skip, _, smax = skip.partition(":")
if skip == "abort":
self._skipexc = exception.StopExtraction
smax, _, sarg = smax.partition(":")
self._skipexc = exception.StopExtraction(sarg or None)
elif skip == "terminate":
self._skipexc = exception.TerminateExtraction
elif skip == "exit":

View File

@@ -664,14 +664,18 @@ def build_parser():
selection = parser.add_argument_group("Selection Options")
selection.add_argument(
"-A", "--abort",
dest="abort", metavar="N", type=int,
help=("Stop current extractor run "
"after N consecutive file downloads were skipped"),
dest="abort", metavar="N[:TARGET]",
help=("Stop current extractor(s) "
"after N consecutive file downloads were skipped. "
"Specify a TARGET to set how many levels to ascend or "
"to which subcategory to jump to. "
"Examples: '-A 3', '-A 3:2', '-A 3:manga'"),
)
selection.add_argument(
"-T", "--terminate",
dest="terminate", metavar="N", type=int,
help=("Stop current and parent extractor runs "
help=("Stop current & parent extractors "
"and proceed with the next input URL "
"after N consecutive file downloads were skipped"),
)
selection.add_argument(