From 7aaa4fd6c5b88a4ba0fa3ad66775390af3736020 Mon Sep 17 00:00:00 2001 From: Til Boerner Date: Sun, 4 Feb 2018 22:18:46 +0100 Subject: [PATCH] Fix: Make remaining latin1 workarounds conditional This fixes #701 and fixes #710. --- CHANGES | 1 + cherrymusicserver/__init__.py | 9 ++--- cherrymusicserver/httphandler.py | 2 +- cherrymusicserver/test/test_httphandler.py | 40 +++++++++++++++------- 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index fa866ab7..13dce653 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Changelog 0.41.2 (2018-02-04) - FIXED: '--setup' now works for CherryPy 12 and upwards (thanks to TangoSierraAlfaVI) + - FIXED: UnicodeError when transcoding non-ASCII URLs - IMPROVEMENT: Added Bandcamp album cover fetching (thanks to its-wednesday) 0.41.1 (2017-10-10) diff --git a/cherrymusicserver/__init__.py b/cherrymusicserver/__init__.py index 4dbc4713..74183279 100644 --- a/cherrymusicserver/__init__.py +++ b/cherrymusicserver/__init__.py @@ -466,10 +466,11 @@ def start_server(self, httphandler): basedirpath = codecs.encode(basedirpath, 'utf-8') scriptname = codecs.encode(config['server.rootpath'], 'utf-8') else: - # fix cherrypy unicode issue (only for Python3) - # see patch to cherrypy.lib.static.serve_file way above and - # https://bitbucket.org/cherrypy/cherrypy/issue/1148/wrong-encoding-for-urls-containing-utf-8 - basedirpath = codecs.decode(codecs.encode(basedirpath, 'utf-8'), 'latin-1') + if needs_serve_file_utf8_fix: + # fix cherrypy unicode issue (only for Python3) + # see patch to cherrypy.lib.static.serve_file way above and + # https://bitbucket.org/cherrypy/cherrypy/issue/1148/wrong-encoding-for-urls-containing-utf-8 + basedirpath = codecs.decode(codecs.encode(basedirpath, 'utf-8'), 'latin-1') scriptname = config['server.rootpath'] cherrypy.tree.mount( httphandler, scriptname, diff --git a/cherrymusicserver/httphandler.py b/cherrymusicserver/httphandler.py index e9564e93..791e3d86 100644 --- a/cherrymusicserver/httphandler.py +++ b/cherrymusicserver/httphandler.py @@ -253,7 +253,7 @@ def trans(self, newformat, *path, **params): path = os.path.sep.join(path) if sys.version_info < (3, 0): # workaround for #327 (cherrypy issue) path = path.decode('utf-8') # make it work with non-ascii - else: + elif cherry.needs_serve_file_utf8_fix: path = codecs.decode(codecs.encode(path, 'latin1'), 'utf-8') fullpath = os.path.join(cherry.config['media.basedir'], path) diff --git a/cherrymusicserver/test/test_httphandler.py b/cherrymusicserver/test/test_httphandler.py index 4a2964ef..366d8e49 100644 --- a/cherrymusicserver/test/test_httphandler.py +++ b/cherrymusicserver/test/test_httphandler.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# -*- coding: utf-8 -*- # # CherryMusic - a standalone music server # Copyright (c) 2012 - 2014 Tom Wallroth & Tilman Boerner @@ -44,7 +45,6 @@ from cherrymusicserver import service from cherrymusicserver.cherrymodel import CherryModel, MusicEntry -from cherrymusicserver import log class MockAction(Exception): pass @@ -321,19 +321,35 @@ def test_api_userchangepassword(self): session is used to authenticate the http request.""" self.assertRaises(AttributeError, self.http.api, 'userchangepassword') - def test_trans(self): - import os - config = {'media.basedir': 'BASEDIR', 'media.transcode': True} - with mock_auth(): - with patch('cherrymusicserver.httphandler.cherry.config', config): - with patch('cherrymusicserver.httphandler.cherrypy'): - with patch('cherrymusicserver.httphandler.audiotranscode.AudioTranscode') as transcoder: - transcoder.return_value = transcoder - expectPath = os.path.join(config['media.basedir'], 'path') - httphandler.HTTPHandler(config).trans('newformat', 'path', bitrate=111) +def test_trans(): + import sys + if sys.version_info < (3, 0): + test_paths = ['path', ('p\xc3\xb6th', u'pöth')] + else: + if cherry.needs_serve_file_utf8_fix: + test_paths = ['path', + ('pöth'.encode('utf-8').decode('latin-1'), 'pöth')] + else: + test_paths = ['path', 'pöth'] + for path in test_paths: + yield check_trans, path + + +def check_trans(path): + import os + path, expectPath = (path, path) if isinstance(path, str) else path + config = {'media.basedir': 'BASEDIR', 'media.transcode': True} + with mock_auth(): + with patch('cherrymusicserver.httphandler.cherry.config', config): + with patch('cherrymusicserver.httphandler.cherrypy'): + with patch('cherrymusicserver.httphandler.audiotranscode.AudioTranscode') as transcoder: + transcoder.return_value = transcoder + expectPath = os.path.join(config['media.basedir'], expectPath) + + httphandler.HTTPHandler(config).trans('newformat', path, bitrate=111) - transcoder.transcode_stream.assert_called_with(expectPath, 'newformat', bitrate=111, starttime=0) + transcoder.transcode_stream.assert_called_with(expectPath, 'newformat', bitrate=111, starttime=0) if __name__ == "__main__":