From 82deaeed2e5c9031336eebb825fdcac7fa9f5f8c Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Thu, 19 Feb 2015 10:51:06 +0100 Subject: [PATCH 01/10] Downloads now shows path in question. --- qutebrowser/browser/downloads.py | 51 +++++++++++++------------------- qutebrowser/browser/webpage.py | 8 +++-- 2 files changed, 25 insertions(+), 34 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index b5fe94bda..543b39cbc 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -38,7 +38,6 @@ from qutebrowser.config import config from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import (message, usertypes, log, utils, urlutils, objreg, standarddir, qtutils) -from qutebrowser.browser import http from qutebrowser.browser.network import networkmanager @@ -374,6 +373,13 @@ class DownloadItem(QObject): log.downloads.exception("Failed to remove partial file") @pyqtSlot() + def download_dir(self): + """Get the download directory to use.""" + download_dir = config.get('storage', 'download-directory') + if download_dir is None: + download_dir = standarddir.get(QStandardPaths.DownloadLocation) + return download_dir + os.sep + def retry(self): """Retry a failed download.""" self.cancel() @@ -415,10 +421,7 @@ class DownloadItem(QObject): else: # We only got a filename (without directory) from the user, so we # save it under that filename in the default directory. - download_dir = config.get('storage', 'download-directory') - if download_dir is None: - download_dir = standarddir.download() - self._filename = os.path.join(download_dir, filename) + self._filename = os.path.join(self.download_dir(), filename) self.basename = filename log.downloads.debug("Setting filename to {}".format(filename)) if os.path.isfile(self._filename): @@ -604,8 +607,7 @@ class DownloadManager(QAbstractListModel): ui -> remove-finished-downloads is set to false. Return: - If the download could start immediately, (fileobj/filename given), - the created DownloadItem. + If the url is valid, the created DownloadItem. If not, None. """ @@ -630,10 +632,7 @@ class DownloadManager(QAbstractListModel): ui -> remove-finished-downloads is set to false. Return: - If the download could start immediately, (fileobj/filename given), - the created DownloadItem. - - If not, None. + The created DownloadItem. """ if fileobj is not None and filename is not None: raise TypeError("Only one of fileobj/filename may be given!") @@ -644,21 +643,14 @@ class DownloadManager(QAbstractListModel): if fileobj is not None or filename is not None: return self.fetch_request(request, page, fileobj, filename, auto_remove) - q = self._prepare_question() - filename = urlutils.filename_from_url(request.url()) + suggested_filename = urlutils.filename_from_url(request.url()) encoding = sys.getfilesystemencoding() - filename = utils.force_encoding(filename, encoding) - q.default = filename - message_bridge = objreg.get('message-bridge', scope='window', - window=self._win_id) - q.answered.connect( - lambda fn: self.fetch_request(request, filename=fn, page=page, - auto_remove=auto_remove)) - message_bridge.ask(q, blocking=False) - return None + suggested_filename = utils.force_encoding(suggested_filename, encoding) + return self.fetch_request(request, page, fileobj, filename, + auto_remove, suggested_filename) def fetch_request(self, request, page=None, fileobj=None, filename=None, - auto_remove=False): + auto_remove=False, suggested_filename=None): """Download a QNetworkRequest to disk. Args: @@ -677,10 +669,12 @@ class DownloadManager(QAbstractListModel): else: nam = page.networkAccessManager() reply = nam.get(request) - return self.fetch(reply, fileobj, filename, auto_remove) + return self.fetch(reply, fileobj, filename, auto_remove, + suggested_filename) @pyqtSlot('QNetworkReply') - def fetch(self, reply, fileobj=None, filename=None, auto_remove=False): + def fetch(self, reply, fileobj=None, filename=None, auto_remove=False, + suggested_filename=None): """Download a QNetworkReply to disk. Args: @@ -699,8 +693,6 @@ class DownloadManager(QAbstractListModel): suggested_filename = os.path.basename(filename) elif fileobj is not None and getattr(fileobj, 'name', None): suggested_filename = fileobj.name - else: - _inline, suggested_filename = http.parse_content_disposition(reply) log.downloads.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) download = DownloadItem(reply, self._win_id, self) @@ -729,10 +721,7 @@ class DownloadManager(QAbstractListModel): download.autoclose = False else: q = self._prepare_question() - encoding = sys.getfilesystemencoding() - suggested_filename = utils.force_encoding(suggested_filename, - encoding) - q.default = suggested_filename + q.default = download.download_dir() q.answered.connect(download.set_filename) q.cancelled.connect(download.cancel) download.cancelled.connect(q.abort) diff --git a/qutebrowser/browser/webpage.py b/qutebrowser/browser/webpage.py index cd77a1090..230d5b48b 100644 --- a/qutebrowser/browser/webpage.py +++ b/qutebrowser/browser/webpage.py @@ -280,12 +280,13 @@ class BrowserPage(QWebPage): At some point we might want to implement the MIME Sniffing standard here: http://mimesniff.spec.whatwg.org/ """ - inline, _suggested_filename = http.parse_content_disposition(reply) + inline, suggested_filename = http.parse_content_disposition(reply) download_manager = objreg.get('download-manager', scope='window', window=self._win_id) if not inline: # Content-Disposition: attachment -> force download - download_manager.fetch(reply) + download_manager.fetch(reply, + suggested_filename=suggested_filename) return mimetype, _rest = http.parse_content_type(reply) if mimetype == 'image/jpg': @@ -300,7 +301,8 @@ class BrowserPage(QWebPage): self.display_content, reply, 'image/jpeg')) else: # Unknown mimetype, so download anyways. - download_manager.fetch(reply) + download_manager.fetch(reply, + suggested_filename=suggested_filename) @pyqtSlot() def on_load_started(self): From 8e0c1cff7bfcc9c24510fc202d9c56e2775349d1 Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Fri, 20 Feb 2015 21:00:47 +0100 Subject: [PATCH 02/10] Made download suggestion configurable. Fix #505 --- qutebrowser/browser/downloads.py | 21 +++++++++++++++++++-- qutebrowser/config/configdata.py | 4 ++++ qutebrowser/config/configtypes.py | 9 +++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 543b39cbc..6bca9974d 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -284,6 +284,13 @@ class DownloadItem(QObject): window=self._win_id) message_bridge.ask(q, blocking=False) + def _download_dir(self): + """Get the download directory to use.""" + download_dir = config.get('storage', 'download-directory') + if download_dir is None: + download_dir = standarddir.get(QStandardPaths.DownloadLocation) + return download_dir + os.sep + def _die(self, msg): """Abort the download and emit an error.""" assert not self.successful @@ -364,6 +371,16 @@ class DownloadItem(QObject): self.data_changed.emit() @pyqtSlot() + def path_suggestion(self): + """Get the suggestion of file path""" + suggestion = config.get('completion', 'download-path-suggestion') + if suggestion == 'path': + return self._download_dir() + elif suggestion == 'filename': + return self.basename + else: + return os.path.join(self._download_dir(), self.basename) + def delete(self): """Delete the downloaded file""" try: @@ -421,7 +438,7 @@ class DownloadItem(QObject): else: # We only got a filename (without directory) from the user, so we # save it under that filename in the default directory. - self._filename = os.path.join(self.download_dir(), filename) + self._filename = os.path.join(self._download_dir(), filename) self.basename = filename log.downloads.debug("Setting filename to {}".format(filename)) if os.path.isfile(self._filename): @@ -721,7 +738,7 @@ class DownloadManager(QAbstractListModel): download.autoclose = False else: q = self._prepare_question() - q.default = download.download_dir() + q.default = download.path_suggestion() q.answered.connect(download.set_filename) q.cancelled.connect(download.cancel) download.cancelled.connect(q.abort) diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 059e49b0e..d0902009a 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -305,6 +305,10 @@ DATA = collections.OrderedDict([ )), ('completion', sect.KeyValue( + ('download-path-suggestion', + SettingValue(typ.DownloadPath(), 'path'), + "What to show in the suggestion for the download question."), + ('show', SettingValue(typ.Bool(), 'true'), "Whether to show the autocompletion window."), diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index 5a6a524e7..a2838af84 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1416,6 +1416,15 @@ class NewInstanceOpenTarget(BaseType): ('window', "Open in a new window.")) +class DownloadPath(BaseType): + + """How to format the question when downloading.""" + + valid_values = ValidValues(('path', "Show only the download path."), + ('filename', "Show only download filename."), + ('both', "Show download path and filename.")) + + class UserAgent(BaseType): """The user agent to use.""" From 68774a2c757ae2ef12ea532abb594d66097cc490 Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Tue, 3 Mar 2015 18:48:27 +0100 Subject: [PATCH 03/10] Style fixes. --- qutebrowser/browser/downloads.py | 8 +++++--- qutebrowser/config/configdata.py | 4 ++-- qutebrowser/config/configtypes.py | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 6bca9974d..1ad307b7a 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -289,7 +289,7 @@ class DownloadItem(QObject): download_dir = config.get('storage', 'download-directory') if download_dir is None: download_dir = standarddir.get(QStandardPaths.DownloadLocation) - return download_dir + os.sep + return download_dir def _die(self, msg): """Abort the download and emit an error.""" @@ -375,11 +375,13 @@ class DownloadItem(QObject): """Get the suggestion of file path""" suggestion = config.get('completion', 'download-path-suggestion') if suggestion == 'path': - return self._download_dir() + return self._download_dir() + os.sep elif suggestion == 'filename': return self.basename - else: + elif suggestion == 'both': return os.path.join(self._download_dir(), self.basename) + else: + raise ValueError("Invalid suggestion value {}!".format(suggestion)) def delete(self): """Delete the downloaded file""" diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index d0902009a..e87e49476 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -306,8 +306,8 @@ DATA = collections.OrderedDict([ ('completion', sect.KeyValue( ('download-path-suggestion', - SettingValue(typ.DownloadPath(), 'path'), - "What to show in the suggestion for the download question."), + SettingValue(typ.DownloadPathSuggestion(), 'path'), + "What to display in the download filename input."), ('show', SettingValue(typ.Bool(), 'true'), diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py index a2838af84..f72622369 100644 --- a/qutebrowser/config/configtypes.py +++ b/qutebrowser/config/configtypes.py @@ -1416,7 +1416,7 @@ class NewInstanceOpenTarget(BaseType): ('window', "Open in a new window.")) -class DownloadPath(BaseType): +class DownloadPathSuggestion(BaseType): """How to format the question when downloading.""" From 49c666a4a8296dd49c609978c48338f894e933cf Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Tue, 3 Mar 2015 23:36:12 +0100 Subject: [PATCH 04/10] get_request is now correct. --- qutebrowser/browser/downloads.py | 69 +++++++++++++++++--------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 1ad307b7a..8184f45f1 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -48,6 +48,27 @@ ModelRole = usertypes.enum('ModelRole', ['item'], start=Qt.UserRole, RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager']) +def download_dir(): + """Get the download directory to use.""" + directory = config.get('storage', 'download-directory') + if directory is None: + directory = standarddir.download() + return directory + + +def path_suggestion(filename): + """Get the suggested file path""" + suggestion = config.get('completion', 'download-path-suggestion') + if suggestion == 'path': + return download_dir() + os.sep + elif suggestion == 'filename': + return filename + elif suggestion == 'both': + return os.path.join(download_dir(), filename) + else: + raise ValueError("Invalid suggestion value {}!".format(suggestion)) + + class DownloadItemStats(QObject): """Statistics (bytes done, total bytes, time, etc.) about a download. @@ -284,13 +305,6 @@ class DownloadItem(QObject): window=self._win_id) message_bridge.ask(q, blocking=False) - def _download_dir(self): - """Get the download directory to use.""" - download_dir = config.get('storage', 'download-directory') - if download_dir is None: - download_dir = standarddir.get(QStandardPaths.DownloadLocation) - return download_dir - def _die(self, msg): """Abort the download and emit an error.""" assert not self.successful @@ -370,19 +384,6 @@ class DownloadItem(QObject): self.finished.emit() self.data_changed.emit() - @pyqtSlot() - def path_suggestion(self): - """Get the suggestion of file path""" - suggestion = config.get('completion', 'download-path-suggestion') - if suggestion == 'path': - return self._download_dir() + os.sep - elif suggestion == 'filename': - return self.basename - elif suggestion == 'both': - return os.path.join(self._download_dir(), self.basename) - else: - raise ValueError("Invalid suggestion value {}!".format(suggestion)) - def delete(self): """Delete the downloaded file""" try: @@ -391,14 +392,6 @@ class DownloadItem(QObject): except OSError: log.downloads.exception("Failed to remove partial file") - @pyqtSlot() - def download_dir(self): - """Get the download directory to use.""" - download_dir = config.get('storage', 'download-directory') - if download_dir is None: - download_dir = standarddir.get(QStandardPaths.DownloadLocation) - return download_dir + os.sep - def retry(self): """Retry a failed download.""" self.cancel() @@ -440,7 +433,7 @@ class DownloadItem(QObject): else: # We only got a filename (without directory) from the user, so we # save it under that filename in the default directory. - self._filename = os.path.join(self._download_dir(), filename) + self._filename = os.path.join(download_dir(), filename) self.basename = filename log.downloads.debug("Setting filename to {}".format(filename)) if os.path.isfile(self._filename): @@ -651,7 +644,10 @@ class DownloadManager(QAbstractListModel): ui -> remove-finished-downloads is set to false. Return: - The created DownloadItem. + If the download could start immediately, (fileobj/filename given), + the created DownloadItem. + + If not, None. """ if fileobj is not None and filename is not None: raise TypeError("Only one of fileobj/filename may be given!") @@ -665,8 +661,15 @@ class DownloadManager(QAbstractListModel): suggested_filename = urlutils.filename_from_url(request.url()) encoding = sys.getfilesystemencoding() suggested_filename = utils.force_encoding(suggested_filename, encoding) - return self.fetch_request(request, page, fileobj, filename, - auto_remove, suggested_filename) + q = self._prepare_question() + q.default = path_suggestion(suggested_filename) + message_bridge = objreg.get('message-bridge', scope='window', + window=self._win_id) + q.answered.connect( + lambda fn: self.fetch_request(request, page, filename=fn, + auto_remove=auto_remove)) + message_bridge.ask(q, blocking=False) + return None def fetch_request(self, request, page=None, fileobj=None, filename=None, auto_remove=False, suggested_filename=None): @@ -740,7 +743,7 @@ class DownloadManager(QAbstractListModel): download.autoclose = False else: q = self._prepare_question() - q.default = download.path_suggestion() + q.default = path_suggestion(suggested_filename) q.answered.connect(download.set_filename) q.cancelled.connect(download.cancel) download.cancelled.connect(q.abort) From 4e7e97232e1f5d3120b1a1532802062f166afe24 Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Wed, 4 Mar 2015 12:24:26 +0100 Subject: [PATCH 05/10] Downloads using get_request specifying only path now works. --- qutebrowser/browser/downloads.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 8184f45f1..bd34b956c 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -658,16 +658,17 @@ class DownloadManager(QAbstractListModel): if fileobj is not None or filename is not None: return self.fetch_request(request, page, fileobj, filename, auto_remove) - suggested_filename = urlutils.filename_from_url(request.url()) + suggested_fn = urlutils.filename_from_url(request.url()) encoding = sys.getfilesystemencoding() - suggested_filename = utils.force_encoding(suggested_filename, encoding) + suggested_fn = utils.force_encoding(suggested_fn, encoding) q = self._prepare_question() - q.default = path_suggestion(suggested_filename) + q.default = path_suggestion(suggested_fn) message_bridge = objreg.get('message-bridge', scope='window', window=self._win_id) q.answered.connect( lambda fn: self.fetch_request(request, page, filename=fn, - auto_remove=auto_remove)) + auto_remove=auto_remove, + suggested_filename=suggested_fn)) message_bridge.ask(q, blocking=False) return None @@ -711,10 +712,11 @@ class DownloadManager(QAbstractListModel): """ if fileobj is not None and filename is not None: raise TypeError("Only one of fileobj/filename may be given!") - if filename is not None: - suggested_filename = os.path.basename(filename) - elif fileobj is not None and getattr(fileobj, 'name', None): - suggested_filename = fileobj.name + if not suggested_filename: + if filename is not None: + suggested_filename = os.path.basename(filename) + elif fileobj is not None and getattr(fileobj, 'name', None): + suggested_filename = fileobj.name log.downloads.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) download = DownloadItem(reply, self._win_id, self) From 7d48845afacecb7c115e0f6c68860ce0f959724e Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Wed, 4 Mar 2015 23:05:23 +0100 Subject: [PATCH 06/10] Made static functions private. --- qutebrowser/browser/downloads.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index bd34b956c..e089237c5 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -48,7 +48,7 @@ ModelRole = usertypes.enum('ModelRole', ['item'], start=Qt.UserRole, RetryInfo = collections.namedtuple('RetryInfo', ['request', 'manager']) -def download_dir(): +def _download_dir(): """Get the download directory to use.""" directory = config.get('storage', 'download-directory') if directory is None: @@ -56,15 +56,19 @@ def download_dir(): return directory -def path_suggestion(filename): - """Get the suggested file path""" +def _path_suggestion(filename): + """Get the suggested file path + + Args: + filename: The filename to use if included in the suggestion. + """ suggestion = config.get('completion', 'download-path-suggestion') if suggestion == 'path': - return download_dir() + os.sep + return _download_dir() + os.sep elif suggestion == 'filename': return filename elif suggestion == 'both': - return os.path.join(download_dir(), filename) + return os.path.join(_download_dir(), filename) else: raise ValueError("Invalid suggestion value {}!".format(suggestion)) @@ -392,6 +396,7 @@ class DownloadItem(QObject): except OSError: log.downloads.exception("Failed to remove partial file") + @pyqtSlot() def retry(self): """Retry a failed download.""" self.cancel() @@ -433,7 +438,7 @@ class DownloadItem(QObject): else: # We only got a filename (without directory) from the user, so we # save it under that filename in the default directory. - self._filename = os.path.join(download_dir(), filename) + self._filename = os.path.join(_download_dir(), filename) self.basename = filename log.downloads.debug("Setting filename to {}".format(filename)) if os.path.isfile(self._filename): @@ -619,7 +624,8 @@ class DownloadManager(QAbstractListModel): ui -> remove-finished-downloads is set to false. Return: - If the url is valid, the created DownloadItem. + If the download could start immediately, (fileobj/filename given), + the created DownloadItem. If not, None. """ @@ -662,7 +668,7 @@ class DownloadManager(QAbstractListModel): encoding = sys.getfilesystemencoding() suggested_fn = utils.force_encoding(suggested_fn, encoding) q = self._prepare_question() - q.default = path_suggestion(suggested_fn) + q.default = _path_suggestion(suggested_fn) message_bridge = objreg.get('message-bridge', scope='window', window=self._win_id) q.answered.connect( @@ -745,7 +751,7 @@ class DownloadManager(QAbstractListModel): download.autoclose = False else: q = self._prepare_question() - q.default = path_suggestion(suggested_filename) + q.default = _path_suggestion(suggested_filename) q.answered.connect(download.set_filename) q.cancelled.connect(download.cancel) download.cancelled.connect(q.abort) From 9cfa34c00968b75e0397059940c38578d9320c06 Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Thu, 5 Mar 2015 20:17:48 +0100 Subject: [PATCH 07/10] Readded suggested_filename fallback. --- qutebrowser/browser/downloads.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index e089237c5..25f36c9d6 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -38,6 +38,7 @@ from qutebrowser.config import config from qutebrowser.commands import cmdexc, cmdutils from qutebrowser.utils import (message, usertypes, log, utils, urlutils, objreg, standarddir, qtutils) +from qutebrowser.browser import http from qutebrowser.browser.network import networkmanager @@ -723,6 +724,8 @@ class DownloadManager(QAbstractListModel): suggested_filename = os.path.basename(filename) elif fileobj is not None and getattr(fileobj, 'name', None): suggested_filename = fileobj.name + else: + _, suggested_filename = http.parse_content_disposition(reply) log.downloads.debug("fetch: {} -> {}".format(reply.url(), suggested_filename)) download = DownloadItem(reply, self._win_id, self) From d449a60078b0844b6e201b8446e7acb4f6dc5209 Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Thu, 5 Mar 2015 20:33:02 +0100 Subject: [PATCH 08/10] Fixed bug using download dirs with trailing slash. --- qutebrowser/browser/downloads.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 25f36c9d6..3d6b3af5a 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -65,7 +65,8 @@ def _path_suggestion(filename): """ suggestion = config.get('completion', 'download-path-suggestion') if suggestion == 'path': - return _download_dir() + os.sep + # add trailing '/' if not present + return os.path.join(_download_dir(), '') elif suggestion == 'filename': return filename elif suggestion == 'both': From 0fb74da4ff5418b5be4ca0518e2edfccea55d62b Mon Sep 17 00:00:00 2001 From: Joel Torstensson Date: Thu, 5 Mar 2015 23:44:12 +0100 Subject: [PATCH 09/10] Can now handle relative paths. --- qutebrowser/browser/downloads.py | 43 ++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 3d6b3af5a..d4a79ee59 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -428,20 +428,12 @@ class DownloadItem(QObject): # See https://github.com/The-Compiler/qutebrowser/issues/427 encoding = sys.getfilesystemencoding() filename = utils.force_encoding(filename, encoding) - if os.path.isabs(filename) and os.path.isdir(filename): - # We got an absolute directory from the user, so we save it under - # the default filename in that directory. - self._filename = os.path.join(filename, self.basename) - elif os.path.isabs(filename): - # We got an absolute filename from the user, so we save it under - # that filename. - self._filename = filename - self.basename = os.path.basename(self._filename) - else: - # We only got a filename (without directory) from the user, so we - # save it under that filename in the default directory. - self._filename = os.path.join(_download_dir(), filename) - self.basename = filename + if not self._create_full_filename(filename): + # We only got a filename (without directory) or a relative path + # from the user, so we append that to the default directory and + # try again. + self._create_full_filename(os.path.join(_download_dir(), filename)) + log.downloads.debug("Setting filename to {}".format(filename)) if os.path.isfile(self._filename): # The file already exists, so ask the user if it should be @@ -450,6 +442,25 @@ class DownloadItem(QObject): else: self._create_fileobj() + def _create_full_filename(self, filename): + """Tries to create the full filename. + + Return: + True if the full filename was created, False otherwise. + """ + if os.path.isabs(filename) and os.path.isdir(filename): + # We got an absolute directory from the user, so we save it under + # the default filename in that directory. + self._filename = os.path.join(filename, self.basename) + return True + elif os.path.isabs(filename): + # We got an absolute filename from the user, so we save it under + # that filename. + self._filename = filename + self.basename = os.path.basename(self._filename) + return True + return False + def set_fileobj(self, fileobj): """"Set the file object to write the download to. @@ -663,10 +674,10 @@ class DownloadManager(QAbstractListModel): # https://bugreports.qt-project.org/browse/QTBUG-42757 request.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.AlwaysNetwork) + suggested_fn = urlutils.filename_from_url(request.url()) if fileobj is not None or filename is not None: return self.fetch_request(request, page, fileobj, filename, - auto_remove) - suggested_fn = urlutils.filename_from_url(request.url()) + auto_remove, suggested_fn) encoding = sys.getfilesystemencoding() suggested_fn = utils.force_encoding(suggested_fn, encoding) q = self._prepare_question() From 8ee8d28f037457d0fb71849cccc6f15268923b9c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 6 Mar 2015 16:57:58 +0100 Subject: [PATCH 10/10] Regenerate docs. --- README.asciidoc | 2 +- doc/help/settings.asciidoc | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.asciidoc b/README.asciidoc index bb0f5b106..3df054a88 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -130,8 +130,8 @@ Contributors, sorted by the number of commits in descending order: // QUTE_AUTHORS_START * Florian Bruhin -* Claude * Joel Torstensson +* Claude * ZDarian * Peter Vilim * John ShaggyTwoDope Jenkins diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 2149a4de4..5f038e64b 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -59,6 +59,7 @@ [options="header",width="75%",cols="25%,75%"] |============== |Setting|Description +|<>|What to display in the download filename input. |<>|Whether to show the autocompletion window. |<>|The height of the completion, in px or as percentage of the window. |<>|How many commands to save in the history. @@ -601,6 +602,18 @@ Default: +pass:[true]+ == completion Options related to completion and command history. +[[completion-download-path-suggestion]] +=== download-path-suggestion +What to display in the download filename input. + +Valid values: + + * +path+: Show only the download path. + * +filename+: Show only download filename. + * +both+: Show download path and filename. + +Default: +pass:[path]+ + [[completion-show]] === show Whether to show the autocompletion window.