diff options
Diffstat (limited to 'gallery_dl/postprocessor')
| -rw-r--r-- | gallery_dl/postprocessor/classify.py | 5 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/common.py | 20 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/compare.py | 19 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/exec.py | 72 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/metadata.py | 64 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/mtime.py | 1 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/ugoira.py | 5 | ||||
| -rw-r--r-- | gallery_dl/postprocessor/zip.py | 13 |
8 files changed, 106 insertions, 93 deletions
diff --git a/gallery_dl/postprocessor/classify.py b/gallery_dl/postprocessor/classify.py index 0106903..eda092d 100644 --- a/gallery_dl/postprocessor/classify.py +++ b/gallery_dl/postprocessor/classify.py @@ -32,13 +32,16 @@ class ClassifyPP(PostProcessor): for ext in exts } + job.hooks["prepare"].append(self.prepare) + job.hooks["file"].append(self.move) + def prepare(self, pathfmt): ext = pathfmt.extension if ext in self.mapping: # set initial paths to enable download skips self._build_paths(pathfmt, self.mapping[ext]) - def run(self, pathfmt): + def move(self, pathfmt): ext = pathfmt.extension if ext in self.mapping: # rebuild paths in case the filename extension changed diff --git a/gallery_dl/postprocessor/common.py b/gallery_dl/postprocessor/common.py index 64f978e..ef211e6 100644 --- a/gallery_dl/postprocessor/common.py +++ b/gallery_dl/postprocessor/common.py @@ -16,25 +16,5 @@ class PostProcessor(): name = self.__class__.__name__[:-2].lower() self.log = job.get_logger("postprocessor." + name) - @staticmethod - def prepare(pathfmt): - """Update file paths, etc.""" - - @staticmethod - def run(pathfmt): - """Execute the postprocessor for a file""" - - @staticmethod - def run_metadata(pathfmt): - """Execute the postprocessor for a file""" - - @staticmethod - def run_after(pathfmt): - """Execute postprocessor after moving a file to its target location""" - - @staticmethod - def run_final(pathfmt, status): - """Postprocessor finalization after all files have been downloaded""" - def __repr__(self): return self.__class__.__name__ diff --git a/gallery_dl/postprocessor/compare.py b/gallery_dl/postprocessor/compare.py index 0d11844..ca416c9 100644 --- a/gallery_dl/postprocessor/compare.py +++ b/gallery_dl/postprocessor/compare.py @@ -16,22 +16,25 @@ class ComparePP(PostProcessor): def __init__(self, job, options): PostProcessor.__init__(self, job) - if options.get("action") == "enumerate": - self.run = self._run_enumerate if options.get("shallow"): - self.compare = self._compare_size + self._compare = self._compare_size + job.hooks["file"].append( + self.enumerate + if options.get("action") == "enumerate" else + self.compare + ) - def run(self, pathfmt): + def compare(self, pathfmt): try: - if self.compare(pathfmt.realpath, pathfmt.temppath): + if self._compare(pathfmt.realpath, pathfmt.temppath): pathfmt.delete = True except OSError: pass - def _run_enumerate(self, pathfmt): + def enumerate(self, pathfmt): num = 1 try: - while not self.compare(pathfmt.realpath, pathfmt.temppath): + while not self._compare(pathfmt.realpath, pathfmt.temppath): pathfmt.prefix = str(num) + "." pathfmt.set_extension(pathfmt.extension, False) num += 1 @@ -39,7 +42,7 @@ class ComparePP(PostProcessor): except OSError: pass - def compare(self, f1, f2): + def _compare(self, f1, f2): return self._compare_size(f1, f2) and self._compare_content(f1, f2) @staticmethod diff --git a/gallery_dl/postprocessor/exec.py b/gallery_dl/postprocessor/exec.py index cbe51ae..205f42e 100644 --- a/gallery_dl/postprocessor/exec.py +++ b/gallery_dl/postprocessor/exec.py @@ -24,54 +24,58 @@ class ExecPP(PostProcessor): def __init__(self, job, options): PostProcessor.__init__(self, job) - args = options["command"] - final = options.get("final", False) + if options.get("async", False): + self._exec = self._exec_async + + args = options["command"] if isinstance(args, str): - if final: - self._format = self._format_args_directory - else: - self._format = self._format_args_path if "{}" not in args: args += " {}" self.args = args - self.shell = True + execute = self.exec_string else: - self._format = self._format_args_list self.args = [util.Formatter(arg) for arg in args] - self.shell = False - - if final: - self.run_after = PostProcessor.run_after - else: - self.run_final = PostProcessor.run_final - - if options.get("async", False): - self._exec = self._exec_async + execute = self.exec_list + + events = options.get("event") + if events is None: + events = ("after",) + if options.get("final"): + self.log.warning("'final' is deprecated, " + "use '\"event\": \"finalize\"' instead") + events = ("finalize",) + elif isinstance(events, str): + events = events.split(",") + for event in events: + job.hooks[event].append(execute) + + def exec_list(self, pathfmt, status=None): + if status: + return - def run_after(self, pathfmt): - self._exec(self._format(pathfmt)) - - def run_final(self, pathfmt, status): - if status == 0: - self._exec(self._format(pathfmt)) - - def _format_args_path(self, pathfmt): - return self.args.replace("{}", quote(pathfmt.realpath)) - - def _format_args_directory(self, pathfmt): - return self.args.replace("{}", quote(pathfmt.realdirectory)) - - def _format_args_list(self, pathfmt): kwdict = pathfmt.kwdict kwdict["_directory"] = pathfmt.realdirectory kwdict["_filename"] = pathfmt.filename kwdict["_path"] = pathfmt.realpath - return [arg.format_map(kwdict) for arg in self.args] - def _exec(self, args): + args = [arg.format_map(kwdict) for arg in self.args] + self._exec(args, False) + + def exec_string(self, pathfmt, status=None): + if status: + return + + if status is None and pathfmt.realpath: + args = self.args.replace("{}", quote(pathfmt.realpath)) + else: + args = self.args.replace("{}", quote(pathfmt.realdirectory)) + + self._exec(args, True) + + def _exec(self, args, shell): self.log.debug("Running '%s'", args) - retcode = subprocess.Popen(args, shell=self.shell).wait() + retcode = subprocess.Popen(args, shell=shell).wait() if retcode: self.log.warning( "Executing '%s' returned with non-zero exit status (%d)", diff --git a/gallery_dl/postprocessor/metadata.py b/gallery_dl/postprocessor/metadata.py index f88dde7..27f9c03 100644 --- a/gallery_dl/postprocessor/metadata.py +++ b/gallery_dl/postprocessor/metadata.py @@ -6,7 +6,7 @@ # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. -"""Write metadata to JSON files""" +"""Write metadata to external files""" from .common import PostProcessor from .. import util @@ -24,7 +24,7 @@ class MetadataPP(PostProcessor): cfmt = options.get("content-format") or options.get("format") if isinstance(cfmt, list): cfmt = "\n".join(cfmt) + "\n" - self.contentfmt = util.Formatter(cfmt).format_map + self._content_fmt = util.Formatter(cfmt).format_map ext = "txt" elif mode == "tags": self.write = self._write_tags @@ -39,47 +39,68 @@ class MetadataPP(PostProcessor): if directory: self._directory = self._directory_custom sep = os.sep + (os.altsep or "") - self.metadir = directory.rstrip(sep) + os.sep + self._metadir = directory.rstrip(sep) + os.sep + filename = options.get("filename") extfmt = options.get("extension-format") - if extfmt: + if filename: self._filename = self._filename_custom - self.extfmt = util.Formatter(extfmt).format_map + self._filename_fmt = util.Formatter(filename).format_map + elif extfmt: + self._filename = self._filename_extfmt + self._extension_fmt = util.Formatter(extfmt).format_map else: self.extension = options.get("extension", ext) - if options.get("bypost"): - self.run_metadata, self.run = self.run, self.run_metadata + events = options.get("event") + if events is None: + events = ("file",) + if options.get("bypost"): + self.log.warning("'bypost' is deprecated, use '\"event\": " + "\"post\"' and 'filename' instead") + events = ("metadata",) + elif isinstance(events, str): + events = events.split(",") + for event in events: + job.hooks[event].append(self.run) def run(self, pathfmt): - path = self._directory(pathfmt) + self._filename(pathfmt) - with open(path, "w", encoding="utf-8") as file: - self.write(file, pathfmt.kwdict) + directory = self._directory(pathfmt) + path = directory + self._filename(pathfmt) + + try: + with open(path, "w", encoding="utf-8") as fp: + self.write(fp, pathfmt.kwdict) + except FileNotFoundError: + os.makedirs(directory, exist_ok=True) + with open(path, "w", encoding="utf-8") as fp: + self.write(fp, pathfmt.kwdict) def _directory(self, pathfmt): return pathfmt.realdirectory def _directory_custom(self, pathfmt): - directory = os.path.join(pathfmt.realdirectory, self.metadir) - os.makedirs(directory, exist_ok=True) - return directory + return os.path.join(pathfmt.realdirectory, self._metadir) def _filename(self, pathfmt): - return pathfmt.filename + "." + self.extension + return (pathfmt.filename or "metadata") + "." + self.extension def _filename_custom(self, pathfmt): + return self._filename_fmt(pathfmt.kwdict) + + def _filename_extfmt(self, pathfmt): kwdict = pathfmt.kwdict ext = kwdict["extension"] kwdict["extension"] = pathfmt.extension - kwdict["extension"] = pathfmt.prefix + self.extfmt(kwdict) + kwdict["extension"] = pathfmt.prefix + self._extension_fmt(kwdict) filename = pathfmt.build_filename() kwdict["extension"] = ext return filename - def _write_custom(self, file, kwdict): - file.write(self.contentfmt(kwdict)) + def _write_custom(self, fp, kwdict): + fp.write(self._content_fmt(kwdict)) - def _write_tags(self, file, kwdict): + def _write_tags(self, fp, kwdict): tags = kwdict.get("tags") or kwdict.get("tag_string") if not tags: @@ -91,11 +112,10 @@ class MetadataPP(PostProcessor): taglist = tags.split(" ") tags = taglist - file.write("\n".join(tags)) - file.write("\n") + fp.write("\n".join(tags) + "\n") - def _write_json(self, file, kwdict): - util.dump_json(util.filter_dict(kwdict), file, self.ascii, self.indent) + def _write_json(self, fp, kwdict): + util.dump_json(util.filter_dict(kwdict), fp, self.ascii, self.indent) __postprocessor__ = MetadataPP diff --git a/gallery_dl/postprocessor/mtime.py b/gallery_dl/postprocessor/mtime.py index b8a4988..e4c28ea 100644 --- a/gallery_dl/postprocessor/mtime.py +++ b/gallery_dl/postprocessor/mtime.py @@ -17,6 +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) def run(self, pathfmt): mtime = pathfmt.kwdict.get(self.key) diff --git a/gallery_dl/postprocessor/ugoira.py b/gallery_dl/postprocessor/ugoira.py index 1afba86..14eaa8d 100644 --- a/gallery_dl/postprocessor/ugoira.py +++ b/gallery_dl/postprocessor/ugoira.py @@ -49,6 +49,9 @@ class UgoiraPP(PostProcessor): else: self.prevent_odd = False + job.hooks["prepare"].append(self.prepare) + job.hooks["file"].append(self.convert) + def prepare(self, pathfmt): self._frames = None @@ -65,7 +68,7 @@ class UgoiraPP(PostProcessor): if self.delete: pathfmt.set_extension(self.extension) - def run(self, pathfmt): + def convert(self, pathfmt): if not self._frames: return diff --git a/gallery_dl/postprocessor/zip.py b/gallery_dl/postprocessor/zip.py index a6e5bc3..e820280 100644 --- a/gallery_dl/postprocessor/zip.py +++ b/gallery_dl/postprocessor/zip.py @@ -38,12 +38,11 @@ class ZipPP(PostProcessor): self.args = (self.path[:-1] + ext, "a", self.COMPRESSION_ALGORITHMS[algorithm], True) - if options.get("mode") == "safe": - self.run = self._write_safe - else: - self.run = self._write + job.hooks["file"].append( + self.write_safe if options.get("mode") == "safe" else self.write) + job.hooks["finalize"].append(self.finalize) - def _write(self, pathfmt, zfile=None): + def write(self, pathfmt, zfile=None): # 'NameToInfo' is not officially documented, but it's available # for all supported Python versions and using it directly is a lot # faster than calling getinfo() @@ -55,11 +54,11 @@ class ZipPP(PostProcessor): zfile.write(pathfmt.temppath, pathfmt.filename) pathfmt.delete = self.delete - def _write_safe(self, pathfmt): + def write_safe(self, pathfmt): with zipfile.ZipFile(*self.args) as zfile: self._write(pathfmt, zfile) - def run_final(self, pathfmt, status): + def finalize(self, pathfmt, status): if self.zfile: self.zfile.close() |
