diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py index b9aaeea8c..5161b3309 100644 --- a/qutebrowser/browser/qtnetworkdownloads.py +++ b/qutebrowser/browser/qtnetworkdownloads.py @@ -438,12 +438,9 @@ class DownloadManager(downloads.AbstractDownloadManager): The created DownloadItem. """ if not suggested_filename: - if isinstance(target, usertypes.FileDownloadTarget): - suggested_filename = os.path.basename(target.filename) - elif (isinstance(target, usertypes.FileObjDownloadTarget) and - getattr(target.fileobj, 'name', None)): - suggested_filename = target.fileobj.name - else: + try: + suggested_filename = target.suggested_filename() + except usertypes.NoFilenameError: _, suggested_filename = http.parse_content_disposition(reply) log.downloads.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index 4e67a2eac..052db5720 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -23,6 +23,7 @@ Module attributes: _UNSET: Used as default argument in the constructor so default can be None. """ +import os.path import operator import collections.abc import enum as pyenum @@ -268,6 +269,11 @@ JsWorld = enum('JsWorld', ['main', 'application', 'user', 'jseval']) MessageLevel = enum('MessageLevel', ['error', 'warning', 'info']) +class NoFilenameError(Exception): + + """Raised when we can't find out a filename in DownloadTarget.""" + + # Where a download should be saved class DownloadTarget: @@ -276,6 +282,10 @@ class DownloadTarget: def __init__(self): raise NotImplementedError + def suggested_filename(self): + """Get the suggested filename for this download target.""" + raise NotImplementedError + class FileDownloadTarget(DownloadTarget): @@ -289,6 +299,9 @@ class FileDownloadTarget(DownloadTarget): # pylint: disable=super-init-not-called self.filename = filename + def suggested_filename(self): + return os.path.basename(self.filename) + class FileObjDownloadTarget(DownloadTarget): @@ -302,6 +315,12 @@ class FileObjDownloadTarget(DownloadTarget): # pylint: disable=super-init-not-called self.fileobj = fileobj + def suggested_filename(self): + try: + return self.fileobj.name + except AttributeError: + raise NoFilenameError + class OpenFileDownloadTarget(DownloadTarget): @@ -317,6 +336,9 @@ class OpenFileDownloadTarget(DownloadTarget): # pylint: disable=super-init-not-called self.cmdline = cmdline + def suggested_filename(self): + raise NoFilenameError + class Question(QObject):