summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Bruhin <git@the-compiler.org>2015-01-03 17:50:59 +0100
committerFlorian Bruhin <git@the-compiler.org>2015-01-09 07:15:44 +0100
commit8f33fcfc52cf598d0aa11a347992c87010d3e37a (patch)
treeb4c321d0493584b9789897cccb02905cb9ad36b3
parent91b0a33ab0e14aacc96527b976bfdc29de425bb1 (diff)
downloadqutebrowser-8f33fcfc52cf598d0aa11a347992c87010d3e37a.tar.gz
qutebrowser-8f33fcfc52cf598d0aa11a347992c87010d3e37a.zip
Replace unencodable chars in download filenames.
Fixes #427.
-rw-r--r--qutebrowser/browser/downloads.py13
-rw-r--r--qutebrowser/test/utils/test_utils.py20
-rw-r--r--qutebrowser/utils/utils.py8
3 files changed, 40 insertions, 1 deletions
diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py
index d7b5f7c35..f9aaa022e 100644
--- a/qutebrowser/browser/downloads.py
+++ b/qutebrowser/browser/downloads.py
@@ -21,6 +21,7 @@
import io
import os
+import sys
import os.path
import shutil
import functools
@@ -385,6 +386,10 @@ class DownloadItem(QObject):
"existing: {}, fileobj {}".format(
filename, self._filename, self.fileobj))
filename = os.path.expanduser(filename)
+ # Remove chars which can't be encoded in the filename encoding.
+ # 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.
@@ -639,7 +644,10 @@ class DownloadManager(QAbstractListModel):
return self.fetch_request(request, filename, fileobj, page,
auto_remove)
q = self._prepare_question()
- q.default = urlutils.filename_from_url(request.url())
+ 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(
@@ -719,6 +727,9 @@ 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.answered.connect(download.set_filename)
q.cancelled.connect(download.cancel)
diff --git a/qutebrowser/test/utils/test_utils.py b/qutebrowser/test/utils/test_utils.py
index 027e0d516..a0db50b51 100644
--- a/qutebrowser/test/utils/test_utils.py
+++ b/qutebrowser/test/utils/test_utils.py
@@ -383,5 +383,25 @@ class RaisesTests(unittest.TestCase):
utils.raises(ValueError, self.do_raise)
+class ForceEncodingTests(unittest.TestCase):
+
+ """Test force_encoding."""
+
+ def test_fitting_ascii(self):
+ """Test with a text fitting into ascii."""
+ text = 'hello world'
+ self.assertEqual(utils.force_encoding(text, 'ascii'), text)
+
+ def test_fitting_utf8(self):
+ """Test with a text fitting into utf-8."""
+ text = 'hellö wörld'
+ self.assertEqual(utils.force_encoding(text, 'utf-8'), text)
+
+ def test_not_fitting_ascii(self):
+ """Test with a text not fitting into ascii."""
+ text = 'hellö wörld'
+ self.assertEqual(utils.force_encoding(text, 'ascii'), 'hell? w?rld')
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py
index 567c84e9c..3d264a335 100644
--- a/qutebrowser/utils/utils.py
+++ b/qutebrowser/utils/utils.py
@@ -542,3 +542,11 @@ def raises(exc, func, *args):
return True
else:
return False
+
+
+def force_encoding(text, encoding):
+ """Make sure a given text is encodable with the given encoding.
+
+ This replaces all chars not encodable with question marks.
+ """
+ return text.encode(encoding, errors='replace').decode(encoding)