Merge lp:~tomasgroth/openlp/bugfixes18 into lp:openlp

Proposed by Tomas Groth
Status: Merged
Approved by: Raoul Snyman
Approved revision: 2529
Merged at revision: 2526
Proposed branch: lp:~tomasgroth/openlp/bugfixes18
Merge into: lp:openlp
Diff against target: 206 lines (+53/-13)
9 files modified
openlp/core/common/__init__.py (+3/-2)
openlp/core/lib/__init__.py (+1/-1)
openlp/core/ui/maindisplay.py (+2/-2)
openlp/core/ui/media/mediacontroller.py (+2/-0)
openlp/core/ui/thememanager.py (+9/-5)
openlp/plugins/custom/lib/mediaitem.py (+4/-0)
openlp/plugins/songs/lib/openlyricsxml.py (+2/-2)
tests/functional/openlp_core_lib/test_lib.py (+1/-1)
tests/functional/openlp_core_ui/test_thememanager.py (+29/-0)
To merge this branch: bzr merge lp:~tomasgroth/openlp/bugfixes18
Reviewer Review Type Date Requested Status
Raoul Snyman Approve
Tim Bentley Approve
Review via email: mp+255147@code.launchpad.net

Description of the change

Mark a custom slide edited from preview as coming from plugin. Fixes bug 1439671.
Use html.escape instead of the deprecated cgi.escape
Fix support for special characters in theme names. Fixes bug 1438563.
Fix another case of traceback when playing media with no players available/enabled (bug 1422761).

To post a comment you must log in.
Revision history for this message
Tomas Groth (tomasgroth) wrote :

lp:~tomasgroth/openlp/bugfixes18 (revision 2529)
[SUCCESS] https//ci.openlp.io/job/Branch-01-Pull/1003/
[SUCCESS] https//ci.openlp.io/job/Branch-02-Functional-Tests/926/
[SUCCESS] https//ci.openlp.io/job/Branch-03-Interface-Tests/868/
[SUCCESS] https//ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/758/
[SUCCESS] https//ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/356/
[SUCCESS] https//ci.openlp.io/job/Branch-05a-Code_Analysis/490/
[SUCCESS] https//ci.openlp.io/job/Branch-05b-Test_Coverage/361/

Revision history for this message
Tim Bentley (trb143) wrote :

Nice set. Fixed a bug we found but I forgot to raise on our new W7 test machine.

review: Approve
Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/common/__init__.py'
--- openlp/core/common/__init__.py 2015-02-04 16:43:04 +0000
+++ openlp/core/common/__init__.py 2015-04-02 21:03:11 +0000
@@ -66,8 +66,9 @@
66 try:66 try:
67 if not os.path.exists(directory):67 if not os.path.exists(directory):
68 os.makedirs(directory)68 os.makedirs(directory)
69 except IOError:69 except IOError as e:
70 pass70 if not do_not_log:
71 log.exception('failed to check if directory exists or create directory')
7172
7273
73def get_frozen_path(frozen_option, non_frozen_option):74def get_frozen_path(frozen_option, non_frozen_option):
7475
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2015-02-13 21:47:06 +0000
+++ openlp/core/lib/__init__.py 2015-04-02 21:03:11 +0000
@@ -90,7 +90,7 @@
90 file_handle = None90 file_handle = None
91 content = None91 content = None
92 try:92 try:
93 file_handle = open(text_file, 'r')93 file_handle = open(text_file, 'r', encoding='utf-8')
94 if not file_handle.read(3) == '\xEF\xBB\xBF':94 if not file_handle.read(3) == '\xEF\xBB\xBF':
95 # no BOM was found95 # no BOM was found
96 file_handle.seek(0)96 file_handle.seek(0)
9797
=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py 2015-01-29 20:58:14 +0000
+++ openlp/core/ui/maindisplay.py 2015-04-02 21:03:11 +0000
@@ -29,7 +29,7 @@
2929
30"""30"""
3131
32import cgi32import html
33import logging33import logging
3434
35from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL35from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
@@ -273,7 +273,7 @@
273 """273 """
274 # First we convert <>& marks to html variants, then apply274 # First we convert <>& marks to html variants, then apply
275 # formattingtags, finally we double all backslashes for JavaScript.275 # formattingtags, finally we double all backslashes for JavaScript.
276 text_prepared = expand_tags(cgi.escape(text)).replace('\\', '\\\\').replace('\"', '\\\"')276 text_prepared = expand_tags(html.escape(text)).replace('\\', '\\\\').replace('\"', '\\\"')
277 if self.height() != self.screen['size'].height() or not self.isVisible():277 if self.height() != self.screen['size'].height() or not self.isVisible():
278 shrink = True278 shrink = True
279 js = 'show_alert("%s", "%s")' % (text_prepared, 'top')279 js = 'show_alert("%s", "%s")' % (text_prepared, 'top')
280280
=== modified file 'openlp/core/ui/media/mediacontroller.py'
--- openlp/core/ui/media/mediacontroller.py 2015-03-16 21:32:56 +0000
+++ openlp/core/ui/media/mediacontroller.py 2015-04-02 21:03:11 +0000
@@ -523,6 +523,8 @@
523 if controller.media_info.file_info.isFile():523 if controller.media_info.file_info.isFile():
524 suffix = '*.%s' % controller.media_info.file_info.suffix().lower()524 suffix = '*.%s' % controller.media_info.file_info.suffix().lower()
525 for title in used_players:525 for title in used_players:
526 if not title:
527 continue
526 player = self.media_players[title]528 player = self.media_players[title]
527 if suffix in player.video_extensions_list:529 if suffix in player.video_extensions_list:
528 if not controller.media_info.is_background or controller.media_info.is_background and \530 if not controller.media_info.is_background or controller.media_info.is_background and \
529531
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2015-02-28 07:04:41 +0000
+++ openlp/core/ui/thememanager.py 2015-04-02 21:03:11 +0000
@@ -354,8 +354,12 @@
354 delete_file(os.path.join(self.path, thumb))354 delete_file(os.path.join(self.path, thumb))
355 delete_file(os.path.join(self.thumb_path, thumb))355 delete_file(os.path.join(self.thumb_path, thumb))
356 try:356 try:
357 encoding = get_filesystem_encoding()357 # Windows is always unicode, so no need to encode filenames
358 shutil.rmtree(os.path.join(self.path, theme).encode(encoding))358 if is_win():
359 shutil.rmtree(os.path.join(self.path, theme))
360 else:
361 encoding = get_filesystem_encoding()
362 shutil.rmtree(os.path.join(self.path, theme).encode(encoding))
359 except OSError as os_error:363 except OSError as os_error:
360 shutil.Error = os_error364 shutil.Error = os_error
361 self.log_exception('Error deleting theme %s' % theme)365 self.log_exception('Error deleting theme %s' % theme)
@@ -567,7 +571,7 @@
567 check_directory_exists(os.path.dirname(full_name))571 check_directory_exists(os.path.dirname(full_name))
568 if os.path.splitext(name)[1].lower() == '.xml':572 if os.path.splitext(name)[1].lower() == '.xml':
569 file_xml = str(theme_zip.read(name), 'utf-8')573 file_xml = str(theme_zip.read(name), 'utf-8')
570 out_file = open(full_name, 'w')574 out_file = open(full_name, 'w', encoding='utf-8')
571 out_file.write(file_xml)575 out_file.write(file_xml)
572 else:576 else:
573 out_file = open(full_name, 'wb')577 out_file = open(full_name, 'wb')
@@ -645,8 +649,8 @@
645 delete_file(self.old_background_image)649 delete_file(self.old_background_image)
646 out_file = None650 out_file = None
647 try:651 try:
648 out_file = open(theme_file, 'w')652 out_file = open(theme_file, 'w', encoding='utf-8')
649 out_file.write(theme_pretty_xml.decode('UTF-8'))653 out_file.write(theme_pretty_xml.decode('utf-8'))
650 except IOError:654 except IOError:
651 self.log_exception('Saving theme to file failed')655 self.log_exception('Saving theme to file failed')
652 finally:656 finally:
653657
=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py 2015-01-18 13:39:21 +0000
+++ openlp/plugins/custom/lib/mediaitem.py 2015-04-02 21:03:11 +0000
@@ -158,6 +158,10 @@
158 self.remote_triggered = None158 self.remote_triggered = None
159 self.remote_custom = 1159 self.remote_custom = 1
160 if item:160 if item:
161 if preview:
162 # A custom slide can only be edited if it comes from plugin,
163 # so we set it again for the new item.
164 item.from_plugin = True
161 return item165 return item
162 return None166 return None
163167
164168
=== modified file 'openlp/plugins/songs/lib/openlyricsxml.py'
--- openlp/plugins/songs/lib/openlyricsxml.py 2015-01-21 20:35:36 +0000
+++ openlp/plugins/songs/lib/openlyricsxml.py 2015-04-02 21:03:11 +0000
@@ -55,7 +55,7 @@
55 </lyrics>55 </lyrics>
56 </song>56 </song>
57"""57"""
58import cgi58import html
59import logging59import logging
60import re60import re
6161
@@ -318,7 +318,7 @@
318 if 'lang' in verse[0]:318 if 'lang' in verse[0]:
319 verse_element.set('lang', verse[0]['lang'])319 verse_element.set('lang', verse[0]['lang'])
320 # Create a list with all "optional" verses.320 # Create a list with all "optional" verses.
321 optional_verses = cgi.escape(verse[1])321 optional_verses = html.escape(verse[1])
322 optional_verses = optional_verses.split('\n[---]\n')322 optional_verses = optional_verses.split('\n[---]\n')
323 start_tags = ''323 start_tags = ''
324 end_tags = ''324 end_tags = ''
325325
=== modified file 'tests/functional/openlp_core_lib/test_lib.py'
--- tests/functional/openlp_core_lib/test_lib.py 2015-01-18 13:39:21 +0000
+++ tests/functional/openlp_core_lib/test_lib.py 2015-04-02 21:03:11 +0000
@@ -176,7 +176,7 @@
176176
177 # THEN: None should be returned177 # THEN: None should be returned
178 mocked_isfile.assert_called_with(filename)178 mocked_isfile.assert_called_with(filename)
179 mocked_open.assert_called_with(filename, 'r')179 mocked_open.assert_called_with(filename, 'r', encoding='utf-8')
180 self.assertIsNone(result, 'None should be returned if the file cannot be opened')180 self.assertIsNone(result, 'None should be returned if the file cannot be opened')
181181
182 def get_text_file_string_decode_error_test(self):182 def get_text_file_string_decode_error_test(self):
183183
=== modified file 'tests/functional/openlp_core_ui/test_thememanager.py'
--- tests/functional/openlp_core_ui/test_thememanager.py 2015-02-19 18:57:05 +0000
+++ tests/functional/openlp_core_ui/test_thememanager.py 2015-04-02 21:03:11 +0000
@@ -29,6 +29,7 @@
29from tempfile import mkdtemp29from tempfile import mkdtemp
3030
31from PyQt4 import QtGui31from PyQt4 import QtGui
32from tempfile import mkdtemp
3233
33from openlp.core.ui import ThemeManager34from openlp.core.ui import ThemeManager
34from openlp.core.common import Registry35from openlp.core.common import Registry
@@ -44,6 +45,13 @@
44 Set up the tests45 Set up the tests
45 """46 """
46 Registry.create()47 Registry.create()
48 self.temp_folder = mkdtemp()
49
50 def tearDown(self):
51 """
52 Clean up
53 """
54 shutil.rmtree(self.temp_folder)
4755
48 def export_theme_test(self):56 def export_theme_test(self):
49 """57 """
@@ -131,6 +139,27 @@
131 # THEN: The mocked_copyfile should not have been called139 # THEN: The mocked_copyfile should not have been called
132 self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called')140 self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called')
133141
142 def write_theme_special_char_name_test(self):
143 """
144 Test that we can save themes with special characters in the name
145 """
146 # GIVEN: A new theme manager instance, with mocked theme and thememanager-attributes.
147 theme_manager = ThemeManager(None)
148 theme_manager.old_background_image = None
149 theme_manager.generate_and_save_image = MagicMock()
150 theme_manager.path = self.temp_folder
151 mocked_theme = MagicMock()
152 mocked_theme.theme_name = 'theme 愛 name'
153 mocked_theme.extract_formatted_xml = MagicMock()
154 mocked_theme.extract_formatted_xml.return_value = 'fake theme 愛 XML'.encode()
155
156 # WHEN: Calling _write_theme with a theme with a name with special characters in it
157 theme_manager._write_theme(mocked_theme, None, None)
158
159 # THEN: It should have been created
160 self.assertTrue(os.path.exists(os.path.join(self.temp_folder, 'theme 愛 name', 'theme 愛 name.xml')),
161 'Theme with special characters should have been created!')
162
134 def over_write_message_box_yes_test(self):163 def over_write_message_box_yes_test(self):
135 """164 """
136 Test that theme_manager.over_write_message_box returns True when the user clicks yes.165 Test that theme_manager.over_write_message_box returns True when the user clicks yes.