support 'filter' option for post processors (#1460)

pull/1633/head
Mike Fährmann 3 years ago
parent 4cf40434d7
commit 3cbbefd4ed
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88

@ -2936,11 +2936,17 @@ Example
"name" : "zip",
"compression": "store",
"extension" : "cbz",
"filter" : "extension not in ('zip', 'rar')",
"whitelist" : ["mangadex", "exhentai", "nhentai"]
}
Description
An ``object`` containing a ``"name"`` attribute specifying the
post-processor type, as well as any of its `options <Postprocessor Options_>`__.
It is possible to set a ``"filter"`` expression similar to
`image-filter <extractor.*.image-filter_>`_ to only run a post-processor
condionally.
It is also possible set a ``"whitelist"`` or ``"blacklist"`` to
only enable or disable a post-processor for the specified
extractor categories.

@ -12,6 +12,7 @@ import time
import errno
import logging
import operator
import functools
import collections
from . import extractor, downloader, postprocessor
from . import config, text, util, output, exception
@ -459,6 +460,23 @@ class DownloadJob(Job):
for callback in self.hooks["init"]:
callback(pathfmt)
def register_hooks(self, hooks, options=None):
expr = options.get("filter") if options else None
if expr:
condition = util.compile_expression(expr)
for hook, callback in hooks.items():
self.hooks[hook].append(functools.partial(
self._call_hook, callback, condition))
else:
for hook, callback in hooks.items():
self.hooks[hook].append(callback)
@staticmethod
def _call_hook(callback, condition, pathfmt):
if condition(pathfmt.kwdict):
callback(pathfmt)
def _build_blacklist(self):
wlist = self.extractor.config("whitelist")
if wlist is not None:

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2018-2020 Mike Fährmann
# Copyright 2018-2021 Mike Fährmann
#
# 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
@ -31,9 +31,8 @@ class ClassifyPP(PostProcessor):
for directory, exts in mapping.items()
for ext in exts
}
job.hooks["prepare"].append(self.prepare)
job.hooks["file"].append(self.move)
job.register_hooks(
{"prepare": self.prepare, "file": self.move}, options)
def prepare(self, pathfmt):
ext = pathfmt.extension

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2020 Mike Fährmann
# Copyright 2020-2021 Mike Fährmann
#
# 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
@ -18,11 +18,12 @@ class ComparePP(PostProcessor):
PostProcessor.__init__(self, job)
if options.get("shallow"):
self._compare = self._compare_size
job.hooks["file"].append(
job.register_hooks({"file": (
self.enumerate
if options.get("action") == "enumerate" else
self.compare
)
)}, options)
def compare(self, pathfmt):
try:

@ -41,8 +41,7 @@ class ExecPP(PostProcessor):
events = ("after",)
elif isinstance(events, str):
events = events.split(",")
for event in events:
job.hooks[event].append(execute)
job.register_hooks({event: execute for event in events}, options)
def exec_list(self, pathfmt, status=None):
if status:

@ -57,8 +57,7 @@ class MetadataPP(PostProcessor):
events = ("file",)
elif isinstance(events, str):
events = events.split(",")
for event in events:
job.hooks[event].append(self.run)
job.register_hooks({event: self.run for event in events}, options)
def run(self, pathfmt):
directory = self._directory(pathfmt)

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2019-2020 Mike Fährmann
# Copyright 2019-2021 Mike Fährmann
#
# 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
@ -17,7 +17,7 @@ class MtimePP(PostProcessor):
def __init__(self, job, options):
PostProcessor.__init__(self, job)
self.key = options.get("key", "date")
job.hooks["file"].append(self.run)
job.register_hooks({"file": self.run}, options)
def run(self, pathfmt):
mtime = pathfmt.kwdict.get(self.key)

@ -55,8 +55,8 @@ class UgoiraPP(PostProcessor):
else:
self.prevent_odd = False
job.hooks["prepare"].append(self.prepare)
job.hooks["file"].append(self.convert)
job.register_hooks(
{"prepare": self.prepare, "file": self.convert}, options)
def prepare(self, pathfmt):
self._frames = None

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright 2018-2020 Mike Fährmann
# Copyright 2018-2021 Mike Fährmann
#
# 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
@ -38,9 +38,11 @@ class ZipPP(PostProcessor):
self.args = (self.path[:-1] + ext, "a",
self.COMPRESSION_ALGORITHMS[algorithm], True)
job.hooks["file"].append(
self.write_safe if options.get("mode") == "safe" else self.write)
job.hooks["finalize"].append(self.finalize)
job.register_hooks({
"file":
self.write_safe if options.get("mode") == "safe" else self.write,
"finalize": self.finalize,
}, options)
def write(self, pathfmt, zfile=None):
# 'NameToInfo' is not officially documented, but it's available

@ -37,6 +37,10 @@ class FakeJob():
self.get_logger = logging.getLogger
self.hooks = collections.defaultdict(list)
def register_hooks(self, hooks, options):
for hook, callback in hooks.items():
self.hooks[hook].append(callback)
class TestPostprocessorModule(unittest.TestCase):

Loading…
Cancel
Save