From c7801d4cc0e9729b0d741384373c47671203ee2a Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Fri, 14 Apr 2017 09:31:30 -0400 Subject: [PATCH] Attempted fix for #2515 (convert on Windows) On Python 3, this tries to pass through the Unicode filename representation for paths to the Windows API. --- beetsplug/convert.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/beetsplug/convert.py b/beetsplug/convert.py index 8af9a62a1..ec4d7c62e 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -24,6 +24,7 @@ import tempfile import shlex import six from string import Template +import platform from beets import ui, util, plugins, config from beets.plugins import BeetsPlugin @@ -183,12 +184,22 @@ class ConvertPlugin(BeetsPlugin): if not quiet and not pretend: self._log.info(u'Encoding {0}', util.displayable_path(source)) - # Substitute $source and $dest in the argument list. + # On Python 3, we need to construct the command to invoke as a + # Unicode string. On Unix, this is a little unfortunate---the OS is + # expecting bytes---so we use surrogate escaping and decode with the + # argument encoding, which is the same encoding that will then be + # *reversed* to recover the same bytes before invoking the OS. On + # Windows, we want to preserve the Unicode filename "as is." if not six.PY2: command = command.decode(util.arg_encoding(), 'surrogateescape') - source = source.decode(util.arg_encoding(), 'surrogateescape') - dest = dest.decode(util.arg_encoding(), 'surrogateescape') + if platform.system() == 'Windows': + source = source.decode(util._fsencoding()) + dest = dest.decode(util._fsencoding()) + else: + source = source.decode(util.arg_encoding(), 'surrogateescape') + dest = dest.decode(util.arg_encoding(), 'surrogateescape') + # Substitute $source and $dest in the argument list. args = shlex.split(command) encode_cmd = [] for i, arg in enumerate(args):