diff --git a/gallery_dl/exception.py b/gallery_dl/exception.py index 3e86177c..c3c28e79 100644 --- a/gallery_dl/exception.py +++ b/gallery_dl/exception.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright 2015-2018 Mike Fährmann +# Copyright 2015-2019 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,63 +17,90 @@ Exception | +-- AuthorizationError | +-- NotFoundError | +-- HttpError - +-- DownloadError - | +-- DownloadComplete - | +-- DownloadRetry - +-- NoExtractorError +-- FormatError + | +-- FilenameFormatError + | +-- DirectoryFormatError +-- FilterError + +-- NoExtractorError +-- StopExtraction """ class GalleryDLException(Exception): """Base class for GalleryDL exceptions""" + default = None + msgfmt = None + code = 1 + + def __init__(self, message=None): + if not message: + message = self.default + elif isinstance(message, Exception): + message = "{}: {}".format(message.__class__.__name__, message) + if self.msgfmt: + message = self.msgfmt.format(message) + Exception.__init__(self, message) class ExtractionError(GalleryDLException): """Base class for exceptions during information extraction""" +class HttpError(ExtractionError): + """HTTP request during data extraction failed""" + default = "HTTP request failed" + code = 4 + + +class NotFoundError(ExtractionError): + """Requested resource (gallery/image) could not be found""" + msgfmt = "Requested {} could not be found" + default = "resource (gallery/image)" + code = 8 + + class AuthenticationError(ExtractionError): - """Invalid or missing login information""" + """Invalid or missing login credentials""" + default = "Invalid or missing login credentials" + code = 16 class AuthorizationError(ExtractionError): """Insufficient privileges to access a resource""" - - -class NotFoundError(ExtractionError): - """Requested resource (gallery/image) does not exist""" - - -class HttpError(ExtractionError): - """HTTP request during extraction failed""" - - -class DownloadError(GalleryDLException): - """Base class for exceptions during file downloads""" - - -class DownloadRetry(DownloadError): - """Download attempt failed and should be retried""" - - -class DownloadComplete(DownloadError): - """Output file of attempted download is already complete""" - - -class NoExtractorError(GalleryDLException): - """No extractor can handle the given URL""" + default = "Insufficient privileges to access a resource" + code = 16 class FormatError(GalleryDLException): - """Error while building output path""" + """Error while building output paths""" + code = 32 + + +class FilenameFormatError(FormatError): + """Error while building output filenames""" + msgfmt = "Applying filename format string failed ({})" + + +class DirectoryFormatError(FormatError): + """Error while building output directory paths""" + msgfmt = "Applying directory format string failed ({})" class FilterError(GalleryDLException): """Error while evaluating a filter expression""" + msgfmt = "Evaluating filter expression failed ({})" + code = 32 + + +class NoExtractorError(GalleryDLException): + """No extractor can handle the given URL""" + code = 64 class StopExtraction(GalleryDLException): - """Extraction should stop""" + """Stop data extraction""" + + def __init__(self, message=None): + GalleryDLException.__init__(self) + self.message = message + self.code = 1 if message else 0 diff --git a/gallery_dl/job.py b/gallery_dl/job.py index b8eef639..bb94ebe3 100644 --- a/gallery_dl/job.py +++ b/gallery_dl/job.py @@ -46,34 +46,18 @@ class Job(): log = self.extractor.log for msg in self.extractor: self.dispatch(msg) - except exception.AuthenticationError as exc: - msg = str(exc) or "Please provide a valid username/password pair." - log.error("Authentication failed: %s", msg) - except exception.AuthorizationError: - log.error("You do not have permission to access the resource " - "at '%s'", self.extractor.url) - except exception.NotFoundError as exc: - res = str(exc) or "resource (gallery/image/user)" - log.error("The %s at '%s' does not exist", res, self.extractor.url) - except exception.HttpError as exc: - err = exc.args[0] - if isinstance(err, Exception): - err = "{}: {}".format(err.__class__.__name__, err) - log.error("HTTP request failed: %s", err) - except exception.FormatError as exc: - err, obj = exc.args - log.error("Applying %s format string failed: %s: %s", - obj, err.__class__.__name__, err) - except exception.FilterError as exc: - err = exc.args[0] - log.error("Evaluating filter expression failed: %s: %s", - err.__class__.__name__, err) - except exception.StopExtraction: - pass + except exception.StopExtraction as exc: + if exc.message: + log.error("%s", exc.message) + return exc.code + except exception.GalleryDLException as exc: + log.error("%s: %s", exc.__class__.__name__, exc) + return exc.code except OSError as exc: log.error("Unable to download data: %s: %s", exc.__class__.__name__, exc) log.debug("", exc_info=True) + return 128 except Exception as exc: log.error(("An unexpected error occurred: %s - %s. " "Please run gallery-dl again with the --verbose flag, " @@ -81,6 +65,9 @@ class Job(): "https://github.com/mikf/gallery-dl/issues ."), exc.__class__.__name__, exc) log.debug("", exc_info=True) + return 1 + else: + return 0 finally: self.handle_finalize() @@ -504,6 +491,7 @@ class DataJob(Job): # dump to 'file' util.dump_json(self.data, self.file, self.ascii, 2) + return 0 def handle_url(self, url, kwdict): self.data.append((Message.Url, url, self._filter(kwdict))) diff --git a/gallery_dl/util.py b/gallery_dl/util.py index d87184de..dfea1d87 100644 --- a/gallery_dl/util.py +++ b/gallery_dl/util.py @@ -528,7 +528,7 @@ class PathFormat(): self.filename_formatter = Formatter( filename_fmt, kwdefault).format_map except Exception as exc: - raise exception.FormatError(exc, "filename") + raise exception.FilenameFormatError(exc) try: self.directory_formatters = [ @@ -536,7 +536,7 @@ class PathFormat(): for dirfmt in directory_fmt ] except Exception as exc: - raise exception.FormatError(exc, "directory") + raise exception.DirectoryFormatError(exc) self.directory = self.realdirectory = "" self.filename = "" @@ -616,7 +616,7 @@ class PathFormat(): if segment: append(self.clean_segment(segment)) except Exception as exc: - raise exception.FormatError(exc, "directory") + raise exception.DirectoryFormatError(exc) # Join path segements sep = os.sep @@ -673,7 +673,7 @@ class PathFormat(): self.filename = filename = self.clean_path(self.clean_segment( self.filename_formatter(self.kwdict))) except Exception as exc: - raise exception.FormatError(exc, "filename") + raise exception.FilenameFormatError(exc) # Combine directory and filename to full paths self.path = self.directory + filename