diff --git a/gallery_dl/__init__.py b/gallery_dl/__init__.py index c79d6276..f9065189 100644 --- a/gallery_dl/__init__.py +++ b/gallery_dl/__init__.py @@ -11,7 +11,7 @@ import logging from . import version, config, option, output, extractor, job, util, exception __author__ = "Mike Fährmann" -__copyright__ = "Copyright 2014-2023 Mike Fährmann" +__copyright__ = "Copyright 2014-2025 Mike Fährmann" __license__ = "GPLv2" __maintainer__ = "Mike Fährmann" __email__ = "mike_faehrmann@web.de" @@ -78,8 +78,7 @@ def main(): output.configure_standard_streams() # signals - signals = config.get((), "signals-ignore") - if signals: + if signals := config.get((), "signals-ignore"): import signal if isinstance(signals, str): signals = signals.split(",") @@ -90,6 +89,19 @@ def main(): else: signal.signal(signal_num, signal.SIG_IGN) + if signals := config.get((), "signals-actions"): + import signal + for signal_name, action in signals.items(): + signal_num = getattr(signal, signal_name, None) + if signal_num is None: + log.warning("signal '%s' is not defined", signal_name) + else: + def handler(signal_num, frame): + signal_name = signal.Signals(signal_num).name + output.stderr_write(f"{signal_name} received\n") + util.FLAGS.__dict__[action.upper()] = "stop" + signal.signal(signal_num, handler) + # enable ANSI escape sequences on Windows if util.WINDOWS and config.get(("output",), "ansi", output.COLORS): from ctypes import windll, wintypes, byref diff --git a/gallery_dl/job.py b/gallery_dl/job.py index 28ee4a6e..6df633f0 100644 --- a/gallery_dl/job.py +++ b/gallery_dl/job.py @@ -28,6 +28,7 @@ from . import ( ) from .extractor.message import Message stdout_write = output.stdout_write +FLAGS = util.FLAGS class Job(): @@ -200,6 +201,8 @@ class Job(): if self.pred_url(url, kwdict): self.update_kwdict(kwdict) self.handle_url(url, kwdict) + if FLAGS.FILE is not None: + FLAGS.FILE = FLAGS.process(FLAGS.FILE) elif msg[0] == Message.Directory: self.update_kwdict(msg[1]) @@ -212,6 +215,8 @@ class Job(): if self.pred_queue(url, kwdict): self.update_kwdict(kwdict) self.handle_queue(url, kwdict) + if FLAGS.CHILD is not None: + FLAGS.CHILD = FLAGS.process(FLAGS.CHILD) def handle_url(self, url, kwdict): """Handle Message.Url""" @@ -390,6 +395,8 @@ class DownloadJob(Job): if "post-after" in self.hooks: for callback in self.hooks["post-after"]: callback(self.pathfmt) + if FLAGS.POST is not None: + FLAGS.POST = FLAGS.process(FLAGS.POST) self.pathfmt.set_directory(kwdict) if "post" in self.hooks: for callback in self.hooks["post"]: diff --git a/gallery_dl/util.py b/gallery_dl/util.py index 0a1c4f87..4bad023b 100644 --- a/gallery_dl/util.py +++ b/gallery_dl/util.py @@ -722,6 +722,17 @@ class CustomNone(): __repr__ = __str__ +class Flags(): + + def __init__(self): + self.FILE = self.POST = self.CHILD = self.DOWNLOAD = None + + def process(self, flag): + if flag == "terminate": + raise exception.TerminateExtraction() + raise exception.StopExtraction() + + # v137.0 release of Firefox on 2025-04-01 has ordinal 739342 # 735506 == 739342 - 137 * 28 # v135.0 release of Chrome on 2025-04-01 has ordinal 739342 @@ -737,6 +748,7 @@ re = text.re re_compile = text.re_compile NONE = CustomNone() +FLAGS = Flags() EPOCH = datetime.datetime(1970, 1, 1) SECOND = datetime.timedelta(0, 1) WINDOWS = (os.name == "nt")