Fix support for special characters in theme names. Fixes bug 1438563.

Fixes: https://launchpad.net/bugs/1438563
This commit is contained in:
Tomas Groth 2015-04-02 10:04:56 +01:00
parent 25f6fe0a59
commit 335c804e8f
4 changed files with 40 additions and 7 deletions

View File

@ -90,7 +90,7 @@ def get_text_file_string(text_file):
file_handle = None file_handle = None
content = None content = None
try: try:
file_handle = open(text_file, 'r') file_handle = open(text_file, 'r', encoding='utf-8')
if not file_handle.read(3) == '\xEF\xBB\xBF': if not file_handle.read(3) == '\xEF\xBB\xBF':
# no BOM was found # no BOM was found
file_handle.seek(0) file_handle.seek(0)

View File

@ -354,8 +354,12 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager, R
delete_file(os.path.join(self.path, thumb)) delete_file(os.path.join(self.path, thumb))
delete_file(os.path.join(self.thumb_path, thumb)) delete_file(os.path.join(self.thumb_path, thumb))
try: try:
encoding = get_filesystem_encoding() # Windows is always unicode, so no need to encode filenames
shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) if is_win():
shutil.rmtree(os.path.join(self.path, theme))
else:
encoding = get_filesystem_encoding()
shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
except OSError as os_error: except OSError as os_error:
shutil.Error = os_error shutil.Error = os_error
self.log_exception('Error deleting theme %s' % theme) self.log_exception('Error deleting theme %s' % theme)
@ -567,7 +571,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager, R
check_directory_exists(os.path.dirname(full_name)) check_directory_exists(os.path.dirname(full_name))
if os.path.splitext(name)[1].lower() == '.xml': if os.path.splitext(name)[1].lower() == '.xml':
file_xml = str(theme_zip.read(name), 'utf-8') file_xml = str(theme_zip.read(name), 'utf-8')
out_file = open(full_name, 'w') out_file = open(full_name, 'w', encoding='utf-8')
out_file.write(file_xml) out_file.write(file_xml)
else: else:
out_file = open(full_name, 'wb') out_file = open(full_name, 'wb')
@ -645,8 +649,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager, R
delete_file(self.old_background_image) delete_file(self.old_background_image)
out_file = None out_file = None
try: try:
out_file = open(theme_file, 'w') out_file = open(theme_file, 'w', encoding='utf-8')
out_file.write(theme_pretty_xml.decode('UTF-8')) out_file.write(theme_pretty_xml.decode('utf-8'))
except IOError: except IOError:
self.log_exception('Saving theme to file failed') self.log_exception('Saving theme to file failed')
finally: finally:

View File

@ -176,7 +176,7 @@ class TestLib(TestCase):
# THEN: None should be returned # THEN: None should be returned
mocked_isfile.assert_called_with(filename) mocked_isfile.assert_called_with(filename)
mocked_open.assert_called_with(filename, 'r') mocked_open.assert_called_with(filename, 'r', encoding='utf-8')
self.assertIsNone(result, 'None should be returned if the file cannot be opened') self.assertIsNone(result, 'None should be returned if the file cannot be opened')
def get_text_file_string_decode_error_test(self): def get_text_file_string_decode_error_test(self):

View File

@ -29,6 +29,7 @@ from unittest import TestCase
from tempfile import mkdtemp from tempfile import mkdtemp
from PyQt4 import QtGui from PyQt4 import QtGui
from tempfile import mkdtemp
from openlp.core.ui import ThemeManager from openlp.core.ui import ThemeManager
from openlp.core.common import Registry from openlp.core.common import Registry
@ -44,6 +45,13 @@ class TestThemeManager(TestCase):
Set up the tests Set up the tests
""" """
Registry.create() Registry.create()
self.temp_folder = mkdtemp()
def tearDown(self):
"""
Clean up
"""
shutil.rmtree(self.temp_folder)
def export_theme_test(self): def export_theme_test(self):
""" """
@ -131,6 +139,27 @@ class TestThemeManager(TestCase):
# THEN: The mocked_copyfile should not have been called # THEN: The mocked_copyfile should not have been called
self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called') self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called')
def write_theme_special_char_name_test(self):
"""
Test that we can save themes with special characters in the name
"""
# GIVEN: A new theme manager instance, with mocked theme and thememanager-attributes.
theme_manager = ThemeManager(None)
theme_manager.old_background_image = None
theme_manager.generate_and_save_image = MagicMock()
theme_manager.path = self.temp_folder
mocked_theme = MagicMock()
mocked_theme.theme_name = 'theme 愛 name'
mocked_theme.extract_formatted_xml = MagicMock()
mocked_theme.extract_formatted_xml.return_value = 'fake theme 愛 XML'.encode()
# WHEN: Calling _write_theme with a theme with a name with special characters in it
theme_manager._write_theme(mocked_theme, None, None)
# THEN: It should have been created
self.assertTrue(os.path.exists(os.path.join(self.temp_folder, 'theme 愛 name', 'theme 愛 name.xml')),
'Theme with special characters should have been created!')
def over_write_message_box_yes_test(self): def over_write_message_box_yes_test(self):
""" """
Test that theme_manager.over_write_message_box returns True when the user clicks yes. Test that theme_manager.over_write_message_box returns True when the user clicks yes.