From e4b10af41a94aa67e37f25903748e38f940e4b51 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 23 Jun 2014 12:15:10 +0200 Subject: [PATCH] Move filename checking to utils.misc --- qutebrowser/browser/downloads.py | 35 +++--------------------------- qutebrowser/utils/misc.py | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py index 5c7ef010c..8a4680b55 100644 --- a/qutebrowser/browser/downloads.py +++ b/qutebrowser/browser/downloads.py @@ -24,7 +24,6 @@ import os.path from functools import partial from collections import deque -import rfc6266 from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QCoreApplication, QTimer) from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply @@ -36,7 +35,8 @@ from qutebrowser.utils.log import downloads as logger from qutebrowser.utils.log import fix_rfc2622 from qutebrowser.utils.usertypes import PromptMode, Question, Timer from qutebrowser.utils.misc import (interpolate_color, format_seconds, - format_size, qt_ensure_valid) + format_size, parse_content_disposition) +from qutebrowser.utils.qt import qt_ensure_valid from qutebrowser.commands.exceptions import CommandError @@ -332,35 +332,6 @@ class DownloadManager(QObject): def __repr__(self): return '<{}>'.format(self.__class__.__name__) - def _get_filename(self, reply): - """Get a suitable filename to download a file to. - - Args: - reply: The QNetworkReply to get a filename for. - """ - # First check if the Content-Disposition header has a filename - # attribute. - if reply.hasRawHeader('Content-Disposition'): - # We use the unsafe variant of the filename as we sanitize it via - # os.path.basename later. - try: - content_disposition = rfc6266.parse_headers( - bytes(reply.rawHeader('Content-Disposition'))) - filename = content_disposition.filename_unsafe - except UnicodeDecodeError as e: - logger.warning("Error while getting filename: {}: {}".format( - e.__class__.__name__, e)) - filename = None - else: - filename = None - # Then try to get filename from url - if not filename: - filename = reply.url().path() - # If that fails as well, use a fallback - if not filename: - filename = 'qutebrowser-download' - return os.path.basename(filename) - def get(self, url): """Start a download with a link URL. @@ -390,7 +361,7 @@ class DownloadManager(QObject): Args: reply: The QNetworkReply to download. """ - suggested_filename = self._get_filename(reply) + _inline, suggested_filename = parse_content_disposition(reply) download_location = config.get('storage', 'download-directory') suggested_filepath = os.path.join(download_location, suggested_filename) diff --git a/qutebrowser/utils/misc.py b/qutebrowser/utils/misc.py index 30c613a7d..7f328f1fb 100644 --- a/qutebrowser/utils/misc.py +++ b/qutebrowser/utils/misc.py @@ -28,11 +28,13 @@ import urllib.request from urllib.parse import urljoin, urlencode from functools import reduce +import rfc6266 from PyQt5.QtCore import QCoreApplication, QStandardPaths from PyQt5.QtGui import QColor from pkg_resources import resource_string import qutebrowser +import qutebrowser.utils.log as log from qutebrowser.utils.qt import qt_version_check, qt_ensure_valid @@ -305,3 +307,38 @@ def format_size(size, base=1024, suffix=''): return '{:.02f}{}{}'.format(size, p, suffix) size /= base return '{:.02f}{}{}'.format(size, prefixes[-1], suffix) + + +def parse_content_disposition(reply): + """Parse a content_disposition header. + + Args: + reply: The QNetworkReply to get a filename for. + + Return: + A (is_inline, filename) tuple. + """ + is_inline = True + filename = None + # First check if the Content-Disposition header has a filename + # attribute. + if reply.hasRawHeader('Content-Disposition'): + # We use the unsafe variant of the filename as we sanitize it via + # os.path.basename later. + try: + content_disposition = rfc6266.parse_headers( + bytes(reply.rawHeader('Content-Disposition'))) + filename = content_disposition.filename_unsafe + except UnicodeDecodeError as e: + log.misc.warning("Error while getting filename: {}: {}".format( + e.__class__.__name__, e)) + filename = None + else: + is_inline = content_disposition.is_inline + # Then try to get filename from url + if not filename: + filename = reply.url().path() + # If that fails as well, use a fallback + if not filename: + filename = 'qutebrowser-download' + return is_inline, os.path.basename(filename)