openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #32125
[Merge] lp:~phill-ridout/openlp/pathlib7 into lp:openlp
Phill has proposed merging lp:~phill-ridout/openlp/pathlib7 into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
For more details, see:
https://code.launchpad.net/~phill-ridout/openlp/pathlib7/+merge/331364
pathlib changes to the theme code
lp:~phill-ridout/openlp/pathlib7 (revision 2773)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2214/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/2117/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/2003/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Code_Analysis/1369/
[SUCCESS] https://ci.openlp.io/job/Branch-04b-Test_Coverage/1200/
--
Your team OpenLP Core is requested to review the proposed merge of lp:~phill-ridout/openlp/pathlib7 into lp:openlp.
=== modified file 'openlp/core/lib/json/theme.json'
--- openlp/core/lib/json/theme.json 2013-10-18 18:10:47 +0000
+++ openlp/core/lib/json/theme.json 2017-09-26 17:09:04 +0000
@@ -4,7 +4,7 @@
"color": "#000000",
"direction": "vertical",
"end_color": "#000000",
- "filename": "",
+ "filename": null,
"start_color": "#000000",
"type": "solid"
},
=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py 2017-01-25 21:17:27 +0000
+++ openlp/core/lib/renderer.py 2017-09-26 17:09:04 +0000
@@ -26,6 +26,7 @@
from PyQt5 import QtGui, QtCore, QtWebKitWidgets
from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, RegistryMixin, Settings
+from openlp.core.common.path import path_to_str
from openlp.core.lib import FormattingTags, ImageSource, ItemCapabilities, ScreenList, ServiceItem, expand_tags, \
build_lyrics_format_css, build_lyrics_outline_css, build_chords_css
from openlp.core.common import ThemeLevel
@@ -118,7 +119,7 @@
theme_data, main_rect, footer_rect = self._theme_dimensions[theme_name]
# if No file do not update cache
if theme_data.background_filename:
- self.image_manager.add_image(theme_data.background_filename,
+ self.image_manager.add_image(path_to_str(theme_data.background_filename),
ImageSource.Theme, QtGui.QColor(theme_data.background_border_color))
def pre_render(self, override_theme_data=None):
@@ -207,8 +208,8 @@
service_item.raw_footer = FOOTER
# if No file do not update cache
if theme_data.background_filename:
- self.image_manager.add_image(
- theme_data.background_filename, ImageSource.Theme, QtGui.QColor(theme_data.background_border_color))
+ self.image_manager.add_image(path_to_str(theme_data.background_filename),
+ ImageSource.Theme, QtGui.QColor(theme_data.background_border_color))
theme_data, main, footer = self.pre_render(theme_data)
service_item.theme_data = theme_data
service_item.main = main
=== modified file 'openlp/core/lib/theme.py'
--- openlp/core/lib/theme.py 2017-08-12 17:45:56 +0000
+++ openlp/core/lib/theme.py 2017-09-26 17:09:04 +0000
@@ -22,13 +22,13 @@
"""
Provide the theme XML and handling functions for OpenLP v2 themes.
"""
-import os
+import json
import logging
-import json
from lxml import etree, objectify
from openlp.core.common import AppLocation, de_hump
-
+from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
+from openlp.core.common.path import Path, str_to_path
from openlp.core.lib import str_to_bool, ScreenList, get_text_file_string
log = logging.getLogger(__name__)
@@ -160,9 +160,8 @@
# basic theme object with defaults
json_path = AppLocation.get_directory(AppLocation.AppDir) / 'core' / 'lib' / 'json' / 'theme.json'
jsn = get_text_file_string(json_path)
- jsn = json.loads(jsn)
- self.expand_json(jsn)
- self.background_filename = ''
+ self.load_theme(jsn)
+ self.background_filename = None
def expand_json(self, var, prev=None):
"""
@@ -174,8 +173,6 @@
for key, value in var.items():
if prev:
key = prev + "_" + key
- else:
- key = key
if isinstance(value, dict):
self.expand_json(value, key)
else:
@@ -185,13 +182,13 @@
"""
Add the path name to the image name so the background can be rendered.
- :param path: The path name to be added.
+ :param openlp.core.common.path.Path path: The path name to be added.
+ :rtype: None
"""
if self.background_type == 'image' or self.background_type == 'video':
if self.background_filename and path:
self.theme_name = self.theme_name.strip()
- self.background_filename = self.background_filename.strip()
- self.background_filename = os.path.join(path, self.theme_name, self.background_filename)
+ self.background_filename = path / self.theme_name / self.background_filename
def set_default_header_footer(self):
"""
@@ -206,16 +203,21 @@
self.font_footer_y = current_screen['size'].height() * 9 / 10
self.font_footer_height = current_screen['size'].height() / 10
- def load_theme(self, theme):
+ def load_theme(self, theme, theme_path=None):
"""
Convert the JSON file and expand it.
:param theme: the theme string
+ :param openlp.core.common.path.Path theme_path: The path to the theme
+ :rtype: None
"""
- jsn = json.loads(theme)
+ if theme_path:
+ jsn = json.loads(theme, cls=OpenLPJsonDecoder, base_path=theme_path)
+ else:
+ jsn = json.loads(theme, cls=OpenLPJsonDecoder)
self.expand_json(jsn)
- def export_theme(self):
+ def export_theme(self, theme_path=None):
"""
Loop through the fields and build a dictionary of them
@@ -223,7 +225,9 @@
theme_data = {}
for attr, value in self.__dict__.items():
theme_data["{attr}".format(attr=attr)] = value
- return json.dumps(theme_data)
+ if theme_path:
+ return json.dumps(theme_data, cls=OpenLPJsonEncoder, base_path=theme_path)
+ return json.dumps(theme_data, cls=OpenLPJsonEncoder)
def parse(self, xml):
"""
=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py 2017-09-05 04:28:50 +0000
+++ openlp/core/ui/maindisplay.py 2017-09-26 17:09:04 +0000
@@ -346,7 +346,7 @@
if not hasattr(self, 'service_item'):
return False
self.override['image'] = path
- self.override['theme'] = self.service_item.theme_data.background_filename
+ self.override['theme'] = path_to_str(self.service_item.theme_data.background_filename)
self.image(path)
# Update the preview frame.
if self.is_live:
@@ -454,7 +454,7 @@
Registry().execute('video_background_replaced')
self.override = {}
# We have a different theme.
- elif self.override['theme'] != service_item.theme_data.background_filename:
+ elif self.override['theme'] != path_to_str(service_item.theme_data.background_filename):
Registry().execute('live_theme_changed')
self.override = {}
else:
@@ -466,7 +466,7 @@
if self.service_item.theme_data.background_type == 'image':
if self.service_item.theme_data.background_filename:
self.service_item.bg_image_bytes = self.image_manager.get_image_bytes(
- self.service_item.theme_data.background_filename, ImageSource.Theme)
+ path_to_str(self.service_item.theme_data.background_filename), ImageSource.Theme)
if image_path:
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
created_html = build_html(self.service_item, self.screen, self.is_live, background, image_bytes,
@@ -488,7 +488,7 @@
path = os.path.join(str(AppLocation.get_section_data_path('themes')),
self.service_item.theme_data.theme_name)
service_item.add_from_command(path,
- self.service_item.theme_data.background_filename,
+ path_to_str(self.service_item.theme_data.background_filename),
':/media/slidecontroller_multimedia.png')
self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True)
self._hide_mouse()
=== modified file 'openlp/core/ui/themeform.py'
--- openlp/core/ui/themeform.py 2017-08-25 20:03:25 +0000
+++ openlp/core/ui/themeform.py 2017-09-26 17:09:04 +0000
@@ -28,7 +28,6 @@
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, UiStrings, translate, get_images_filter, is_not_image_file
-from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ThemeLayoutForm
@@ -61,7 +60,7 @@
self.setupUi(self)
self.registerFields()
self.update_theme_allowed = True
- self.temp_background_filename = ''
+ self.temp_background_filename = None
self.theme_layout_form = ThemeLayoutForm(self)
self.background_combo_box.currentIndexChanged.connect(self.on_background_combo_box_current_index_changed)
self.gradient_combo_box.currentIndexChanged.connect(self.on_gradient_combo_box_current_index_changed)
@@ -188,8 +187,7 @@
"""
background_image = BackgroundType.to_string(BackgroundType.Image)
if self.page(self.currentId()) == self.background_page and \
- self.theme.background_type == background_image and \
- is_not_image_file(Path(self.theme.background_filename)):
+ self.theme.background_type == background_image and is_not_image_file(self.theme.background_filename):
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ThemeWizard', 'Background Image Empty'),
translate('OpenLP.ThemeWizard', 'You have not selected a '
'background image. Please select one before continuing.'))
@@ -273,7 +271,7 @@
Run the wizard.
"""
log.debug('Editing theme {name}'.format(name=self.theme.theme_name))
- self.temp_background_filename = ''
+ self.temp_background_filename = None
self.update_theme_allowed = False
self.set_defaults()
self.update_theme_allowed = True
@@ -318,11 +316,11 @@
self.setField('background_type', 1)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Image):
self.image_color_button.color = self.theme.background_border_color
- self.image_path_edit.path = str_to_path(self.theme.background_filename)
+ self.image_path_edit.path = self.theme.background_filename
self.setField('background_type', 2)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
self.video_color_button.color = self.theme.background_border_color
- self.video_path_edit.path = str_to_path(self.theme.background_filename)
+ self.video_path_edit.path = self.theme.background_filename
self.setField('background_type', 4)
elif self.theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
self.setField('background_type', 3)
@@ -402,14 +400,14 @@
self.theme.background_type = BackgroundType.to_string(index)
if self.theme.background_type != BackgroundType.to_string(BackgroundType.Image) and \
self.theme.background_type != BackgroundType.to_string(BackgroundType.Video) and \
- self.temp_background_filename == '':
+ self.temp_background_filename is None:
self.temp_background_filename = self.theme.background_filename
- self.theme.background_filename = ''
+ self.theme.background_filename = None
if (self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or
self.theme.background_type != BackgroundType.to_string(BackgroundType.Video)) and \
- self.temp_background_filename != '':
+ self.temp_background_filename is not None:
self.theme.background_filename = self.temp_background_filename
- self.temp_background_filename = ''
+ self.temp_background_filename = None
self.set_background_page_values()
def on_gradient_combo_box_current_index_changed(self, index):
@@ -450,18 +448,24 @@
"""
self.theme.background_end_color = color
- def on_image_path_edit_path_changed(self, file_path):
- """
- Background Image button pushed.
- """
- self.theme.background_filename = path_to_str(file_path)
+ def on_image_path_edit_path_changed(self, new_path):
+ """
+ Handle the `pathEditChanged` signal from image_path_edit
+
+ :param openlp.core.common.path.Path new_path: Path to the new image
+ :rtype: None
+ """
+ self.theme.background_filename = new_path
self.set_background_page_values()
- def on_video_path_edit_path_changed(self, file_path):
- """
- Background video button pushed.
- """
- self.theme.background_filename = path_to_str(file_path)
+ def on_video_path_edit_path_changed(self, new_path):
+ """
+ Handle the `pathEditChanged` signal from video_path_edit
+
+ :param openlp.core.common.path.Path new_path: Path to the new video
+ :rtype: None
+ """
+ self.theme.background_filename = new_path
self.set_background_page_values()
def on_main_color_changed(self, color):
@@ -537,14 +541,14 @@
translate('OpenLP.ThemeWizard', 'Theme Name Invalid'),
translate('OpenLP.ThemeWizard', 'Invalid theme name. Please enter one.'))
return
- save_from = None
- save_to = None
+ source_path = None
+ destination_path = None
if self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or \
self.theme.background_type == BackgroundType.to_string(BackgroundType.Video):
- filename = os.path.split(str(self.theme.background_filename))[1]
- save_to = os.path.join(self.path, self.theme.theme_name, filename)
- save_from = self.theme.background_filename
+ file_name = self.theme.background_filename.name
+ destination_path = self.path / self.theme.theme_name / file_name
+ source_path = self.theme.background_filename
if not self.edit_mode and not self.theme_manager.check_if_theme_exists(self.theme.theme_name):
return
- self.theme_manager.save_theme(self.theme, save_from, save_to)
+ self.theme_manager.save_theme(self.theme, source_path, destination_path)
return QtWidgets.QDialog.accept(self)
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2017-09-17 19:43:15 +0000
+++ openlp/core/ui/thememanager.py 2017-09-26 17:09:04 +0000
@@ -24,14 +24,14 @@
"""
import os
import zipfile
-import shutil
-
from xml.etree.ElementTree import ElementTree, XML
+
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, OpenLPMixin, RegistryMixin, \
- UiStrings, check_directory_exists, translate, is_win, get_filesystem_encoding, delete_file
-from openlp.core.common.path import Path, path_to_str, str_to_path
+ UiStrings, check_directory_exists, translate, delete_file
+from openlp.core.common.languagemanager import get_locale_key
+from openlp.core.common.path import Path, copyfile, path_to_str, rmtree
from openlp.core.lib import ImageSource, ValidationError, get_text_file_string, build_icon, \
check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.theme import Theme, BackgroundType
@@ -39,7 +39,6 @@
from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.ui.lib import OpenLPToolbar
from openlp.core.ui.lib.filedialog import FileDialog
-from openlp.core.common.languagemanager import get_locale_key
class Ui_ThemeManager(object):
@@ -135,7 +134,7 @@
self.settings_section = 'themes'
# Variables
self.theme_list = []
- self.old_background_image = None
+ self.old_background_image_path = None
def bootstrap_initialise(self):
"""
@@ -145,25 +144,41 @@
self.global_theme = Settings().value(self.settings_section + '/global theme')
self.build_theme_path()
self.load_first_time_themes()
+ self.upgrade_themes()
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
"""
self.theme_form = ThemeForm(self)
- self.theme_form.path = self.path
+ self.theme_form.path = self.theme_path
self.file_rename_form = FileRenameForm()
Registry().register_function('theme_update_global', self.change_global_from_tab)
self.load_themes()
+ def upgrade_themes(self):
+ """
+ Upgrade the xml files to json.
+
+ :rtype: None
+ """
+ xml_file_paths = AppLocation.get_section_data_path('themes').glob('*/*.xml')
+ for xml_file_path in xml_file_paths:
+ theme_data = get_text_file_string(xml_file_path)
+ theme = self._create_theme_from_xml(theme_data, self.theme_path)
+ self._write_theme(theme)
+ xml_file_path.unlink()
+
def build_theme_path(self):
"""
Set up the theme path variables
+
+ :rtype: None
"""
- self.path = str(AppLocation.get_section_data_path(self.settings_section))
- check_directory_exists(Path(self.path))
- self.thumb_path = os.path.join(self.path, 'thumbnails')
- check_directory_exists(Path(self.thumb_path))
+ self.theme_path = AppLocation.get_section_data_path(self.settings_section)
+ check_directory_exists(self.theme_path)
+ self.thumb_path = self.theme_path / 'thumbnails'
+ check_directory_exists(self.thumb_path)
def check_list_state(self, item, field=None):
"""
@@ -298,17 +313,18 @@
"""
Takes a theme and makes a new copy of it as well as saving it.
- :param theme_data: The theme to be used
- :param new_theme_name: The new theme name to save the data to
+ :param Theme theme_data: The theme to be used
+ :param str new_theme_name: The new theme name of the theme
+ :rtype: None
"""
- save_to = None
- save_from = None
+ destination_path = None
+ source_path = None
if theme_data.background_type == 'image' or theme_data.background_type == 'video':
- save_to = os.path.join(self.path, new_theme_name, os.path.split(str(theme_data.background_filename))[1])
- save_from = theme_data.background_filename
+ destination_path = self.theme_path / new_theme_name / theme_data.background_filename.name
+ source_path = theme_data.background_filename
theme_data.theme_name = new_theme_name
- theme_data.extend_image_filename(self.path)
- self.save_theme(theme_data, save_from, save_to)
+ theme_data.extend_image_filename(self.theme_path)
+ self.save_theme(theme_data, source_path, destination_path)
self.load_themes()
def on_edit_theme(self, field=None):
@@ -322,10 +338,10 @@
item = self.theme_list_widget.currentItem()
theme = self.get_theme_data(item.data(QtCore.Qt.UserRole))
if theme.background_type == 'image' or theme.background_type == 'video':
- self.old_background_image = theme.background_filename
+ self.old_background_image_path = theme.background_filename
self.theme_form.theme = theme
self.theme_form.exec(True)
- self.old_background_image = None
+ self.old_background_image_path = None
self.renderer.update_theme(theme.theme_name)
self.load_themes()
@@ -355,77 +371,76 @@
"""
self.theme_list.remove(theme)
thumb = '{name}.png'.format(name=theme)
- delete_file(Path(self.path, thumb))
- delete_file(Path(self.thumb_path, thumb))
+ delete_file(self.theme_path / thumb)
+ delete_file(self.thumb_path / thumb)
try:
- # Windows is always unicode, so no need to encode filenames
- 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:
- shutil.Error = os_error
+ rmtree(self.theme_path / theme)
+ except OSError:
self.log_exception('Error deleting theme {name}'.format(name=theme))
- def on_export_theme(self, field=None):
+ def on_export_theme(self, checked=None):
"""
- Export the theme in a zip file
- :param field:
+ Export the theme to a zip file
+
+ :param bool checked: Sent by the QAction.triggered signal. It's not used in this method.
+ :rtype: None
"""
item = self.theme_list_widget.currentItem()
if item is None:
critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.'))
return
- theme = item.data(QtCore.Qt.UserRole)
+ theme_name = item.data(QtCore.Qt.UserRole)
export_path, filter_used = \
FileDialog.getSaveFileName(self.main_window,
- translate('OpenLP.ThemeManager', 'Save Theme - ({name})').
- format(name=theme),
+ translate('OpenLP.ThemeManager',
+ 'Save Theme - ({name})').format(name=theme_name),
Settings().value(self.settings_section + '/last directory export'),
+ translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'),
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
self.application.set_busy_cursor()
if export_path:
Settings().setValue(self.settings_section + '/last directory export', export_path.parent)
- if self._export_theme(str(export_path), theme):
+ if self._export_theme(export_path.with_suffix('.otz'), theme_name):
QtWidgets.QMessageBox.information(self,
translate('OpenLP.ThemeManager', 'Theme Exported'),
translate('OpenLP.ThemeManager',
'Your theme has been successfully exported.'))
self.application.set_normal_cursor()
- def _export_theme(self, theme_path, theme):
+ def _export_theme(self, theme_path, theme_name):
"""
Create the zipfile with the theme contents.
- :param theme_path: Location where the zip file will be placed
- :param theme: The name of the theme to be exported
+
+ :param openlp.core.common.path.Path theme_path: Location where the zip file will be placed
+ :param str theme_name: The name of the theme to be exported
+ :return: The success of creating the zip file
+ :rtype: bool
"""
- theme_zip = None
try:
- theme_zip = zipfile.ZipFile(theme_path, 'w')
- source = os.path.join(self.path, theme)
- for files in os.walk(source):
- for name in files[2]:
- theme_zip.write(os.path.join(source, name), os.path.join(theme, name))
- theme_zip.close()
+ with zipfile.ZipFile(str(theme_path), 'w') as theme_zip:
+ source_path = self.theme_path / theme_name
+ for file_path in source_path.iterdir():
+ theme_zip.write(str(file_path), os.path.join(theme_name, file_path.name))
return True
except OSError as ose:
self.log_exception('Export Theme Failed')
critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'),
- translate('OpenLP.ThemeManager', 'The theme export failed because this error '
- 'occurred: {err}').format(err=ose.strerror))
- if theme_zip:
- theme_zip.close()
- shutil.rmtree(theme_path, True)
+ translate('OpenLP.ThemeManager',
+ 'The theme_name export failed because this error occurred: {err}')
+ .format(err=ose.strerror))
+ if theme_path.exists():
+ rmtree(theme_path, True)
return False
- def on_import_theme(self, field=None):
+ def on_import_theme(self, checked=None):
"""
Opens a file dialog to select the theme file(s) to import before attempting to extract OpenLP themes from
those files. This process will only load version 2 themes.
- :param field:
+
+ :param bool checked: Sent by the QAction.triggered signal. It's not used in this method.
+ :rtype: None
"""
- file_paths, selected_filter = FileDialog.getOpenFileNames(
+ file_paths, filter_used = FileDialog.getOpenFileNames(
self,
translate('OpenLP.ThemeManager', 'Select Theme Import File'),
Settings().value(self.settings_section + '/last directory import'),
@@ -435,8 +450,8 @@
return
self.application.set_busy_cursor()
for file_path in file_paths:
- self.unzip_theme(path_to_str(file_path), self.path)
- Settings().setValue(self.settings_section + '/last directory import', file_path)
+ self.unzip_theme(file_path, self.theme_path)
+ Settings().setValue(self.settings_section + '/last directory import', file_path.parent)
self.load_themes()
self.application.set_normal_cursor()
@@ -445,17 +460,17 @@
Imports any themes on start up and makes sure there is at least one theme
"""
self.application.set_busy_cursor()
- files = AppLocation.get_files(self.settings_section, '.otz')
- for theme_file in files:
- theme_file = os.path.join(self.path, str(theme_file))
- self.unzip_theme(theme_file, self.path)
- delete_file(Path(theme_file))
- files = AppLocation.get_files(self.settings_section, '.png')
+ theme_paths = AppLocation.get_files(self.settings_section, '.otz')
+ for theme_path in theme_paths:
+ theme_path = self.theme_path / theme_path
+ self.unzip_theme(theme_path, self.theme_path)
+ delete_file(theme_path)
+ theme_paths = AppLocation.get_files(self.settings_section, '.png')
# No themes have been found so create one
- if not files:
+ if not theme_paths:
theme = Theme()
theme.theme_name = UiStrings().Default
- self._write_theme(theme, None, None)
+ self._write_theme(theme)
Settings().setValue(self.settings_section + '/global theme', theme.theme_name)
self.application.set_normal_cursor()
@@ -471,22 +486,21 @@
# Sort the themes by its name considering language specific
files.sort(key=lambda file_name: get_locale_key(str(file_name)))
# now process the file list of png files
- for name in files:
- name = str(name)
+ for file in files:
# check to see file is in theme root directory
- theme = os.path.join(self.path, name)
- if os.path.exists(theme):
- text_name = os.path.splitext(name)[0]
+ theme_path = self.theme_path / file
+ if theme_path.exists():
+ text_name = theme_path.stem
if text_name == self.global_theme:
name = translate('OpenLP.ThemeManager', '{name} (default)').format(name=text_name)
else:
name = text_name
- thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=text_name))
+ thumb = self.thumb_path / '{name}.png'.format(name=text_name)
item_name = QtWidgets.QListWidgetItem(name)
- if validate_thumb(Path(theme), Path(thumb)):
+ if validate_thumb(theme_path, thumb):
icon = build_icon(thumb)
else:
- icon = create_thumb(theme, thumb)
+ icon = create_thumb(str(theme_path), str(thumb))
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole, text_name)
self.theme_list_widget.addItem(item_name)
@@ -507,27 +521,19 @@
def get_theme_data(self, theme_name):
"""
- Returns a theme object from an XML or JSON file
+ Returns a theme object from a JSON file
- :param theme_name: Name of the theme to load from file
- :return: The theme object.
+ :param str theme_name: Name of the theme to load from file
+ :return: The theme object.
+ :rtype: Theme
"""
- self.log_debug('get theme data for theme {name}'.format(name=theme_name))
- theme_file_path = Path(self.path, str(theme_name), '{file_name}.json'.format(file_name=theme_name))
+ theme_name = str(theme_name)
+ theme_file_path = self.theme_path / theme_name / '{file_name}.json'.format(file_name=theme_name)
theme_data = get_text_file_string(theme_file_path)
- jsn = True
- if not theme_data:
- theme_file_path = theme_file_path.with_suffix('.xml')
- theme_data = get_text_file_string(theme_file_path)
- jsn = False
if not theme_data:
self.log_debug('No theme data - using default theme')
return Theme()
- else:
- if jsn:
- return self._create_theme_from_json(theme_data, self.path)
- else:
- return self._create_theme_from_xml(theme_data, self.path)
+ return self._create_theme_from_json(theme_data, self.theme_path)
def over_write_message_box(self, theme_name):
"""
@@ -543,172 +549,148 @@
defaultButton=QtWidgets.QMessageBox.No)
return ret == QtWidgets.QMessageBox.Yes
- def unzip_theme(self, file_name, directory):
+ def unzip_theme(self, file_path, directory_path):
"""
Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
and upgrade if necessary.
- :param file_name:
- :param directory:
+ :param openlp.core.common.path.Path file_path:
+ :param openlp.core.common.path.Path directory_path:
"""
- self.log_debug('Unzipping theme {name}'.format(name=file_name))
- theme_zip = None
- out_file = None
+ self.log_debug('Unzipping theme {name}'.format(name=file_path))
file_xml = None
abort_import = True
json_theme = False
theme_name = ""
try:
- theme_zip = zipfile.ZipFile(file_name)
- json_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.json']
- if len(json_file) != 1:
- # TODO: remove XML handling at some point but would need a auto conversion to run first.
- xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
- if len(xml_file) != 1:
- self.log_error('Theme contains "{val:d}" theme files'.format(val=len(xml_file)))
- raise ValidationError
- xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
- theme_version = xml_tree.get('version', default=None)
- if not theme_version or float(theme_version) < 2.0:
- self.log_error('Theme version is less than 2.0')
- raise ValidationError
- theme_name = xml_tree.find('name').text.strip()
- else:
- new_theme = Theme()
- new_theme.load_theme(theme_zip.read(json_file[0]).decode("utf-8"))
- theme_name = new_theme.theme_name
- json_theme = True
- theme_folder = os.path.join(directory, theme_name)
- theme_exists = os.path.exists(theme_folder)
- if theme_exists and not self.over_write_message_box(theme_name):
- abort_import = True
- return
- else:
- abort_import = False
- for name in theme_zip.namelist():
- out_name = name.replace('/', os.path.sep)
- split_name = out_name.split(os.path.sep)
- if split_name[-1] == '' or len(split_name) == 1:
- # is directory or preview file
- continue
- full_name = os.path.join(directory, out_name)
- check_directory_exists(Path(os.path.dirname(full_name)))
- if os.path.splitext(name)[1].lower() == '.xml' or os.path.splitext(name)[1].lower() == '.json':
- file_xml = str(theme_zip.read(name), 'utf-8')
- out_file = open(full_name, 'w', encoding='utf-8')
- out_file.write(file_xml)
- else:
- out_file = open(full_name, 'wb')
- out_file.write(theme_zip.read(name))
- out_file.close()
+ with zipfile.ZipFile(str(file_path)) as theme_zip:
+ json_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.json']
+ if len(json_file) != 1:
+ # TODO: remove XML handling after the 2.6 release.
+ xml_file = [name for name in theme_zip.namelist() if os.path.splitext(name)[1].lower() == '.xml']
+ if len(xml_file) != 1:
+ self.log_error('Theme contains "{val:d}" theme files'.format(val=len(xml_file)))
+ raise ValidationError
+ xml_tree = ElementTree(element=XML(theme_zip.read(xml_file[0]))).getroot()
+ theme_version = xml_tree.get('version', default=None)
+ if not theme_version or float(theme_version) < 2.0:
+ self.log_error('Theme version is less than 2.0')
+ raise ValidationError
+ theme_name = xml_tree.find('name').text.strip()
+ else:
+ new_theme = Theme()
+ new_theme.load_theme(theme_zip.read(json_file[0]).decode("utf-8"))
+ theme_name = new_theme.theme_name
+ json_theme = True
+ theme_folder = directory_path / theme_name
+ if theme_folder.exists() and not self.over_write_message_box(theme_name):
+ abort_import = True
+ return
+ else:
+ abort_import = False
+ for zipped_file in theme_zip.namelist():
+ zipped_file_rel_path = Path(zipped_file)
+ split_name = zipped_file_rel_path.parts
+ if split_name[-1] == '' or len(split_name) == 1:
+ # is directory or preview file
+ continue
+ full_name = directory_path / zipped_file_rel_path
+ check_directory_exists(full_name.parent)
+ if zipped_file_rel_path.suffix.lower() == '.xml' or zipped_file_rel_path.suffix.lower() == '.json':
+ file_xml = str(theme_zip.read(zipped_file), 'utf-8')
+ with full_name.open('w', encoding='utf-8') as out_file:
+ out_file.write(file_xml)
+ else:
+ with full_name.open('wb') as out_file:
+ out_file.write(theme_zip.read(zipped_file))
except (IOError, zipfile.BadZipfile):
- self.log_exception('Importing theme from zip failed {name}'.format(name=file_name))
+ self.log_exception('Importing theme from zip failed {name}'.format(name=file_path))
raise ValidationError
except ValidationError:
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
finally:
- # Close the files, to be able to continue creating the theme.
- if theme_zip:
- theme_zip.close()
- if out_file:
- out_file.close()
if not abort_import:
# As all files are closed, we can create the Theme.
if file_xml:
if json_theme:
- theme = self._create_theme_from_json(file_xml, self.path)
+ theme = self._create_theme_from_json(file_xml, self.theme_path)
else:
- theme = self._create_theme_from_xml(file_xml, self.path)
+ theme = self._create_theme_from_xml(file_xml, self.theme_path)
self.generate_and_save_image(theme_name, theme)
- # Only show the error message, when IOError was not raised (in
- # this case the error message has already been shown).
- elif theme_zip is not None:
- critical_error_message_box(
- translate('OpenLP.ThemeManager', 'Validation Error'),
- translate('OpenLP.ThemeManager', 'File is not a valid theme.'))
- self.log_error('Theme file does not contain XML data {name}'.format(name=file_name))
def check_if_theme_exists(self, theme_name):
"""
Check if theme already exists and displays error message
- :param theme_name: Name of the Theme to test
+ :param str theme_name: Name of the Theme to test
:return: True or False if theme exists
+ :rtype: bool
"""
- theme_dir = os.path.join(self.path, theme_name)
- if os.path.exists(theme_dir):
+ if (self.theme_path / theme_name).exists():
critical_error_message_box(
translate('OpenLP.ThemeManager', 'Validation Error'),
translate('OpenLP.ThemeManager', 'A theme with this name already exists.'))
return False
return True
- def save_theme(self, theme, image_from, image_to):
+ def save_theme(self, theme, image_source_path, image_destination_path):
"""
Called by theme maintenance Dialog to save the theme and to trigger the reload of the theme list
- :param theme: The theme data object.
- :param image_from: Where the theme image is currently located.
- :param image_to: Where the Theme Image is to be saved to
+ :param Theme theme: The theme data object.
+ :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.
+ :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to
+ :rtype: None
"""
- self._write_theme(theme, image_from, image_to)
+ self._write_theme(theme, image_source_path, image_destination_path)
if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
- self.image_manager.update_image_border(theme.background_filename,
+ self.image_manager.update_image_border(path_to_str(theme.background_filename),
ImageSource.Theme,
QtGui.QColor(theme.background_border_color))
self.image_manager.process_updates()
- def _write_theme(self, theme, image_from, image_to):
+ def _write_theme(self, theme, image_source_path=None, image_destination_path=None):
"""
Writes the theme to the disk and handles the background image if necessary
- :param theme: The theme data object.
- :param image_from: Where the theme image is currently located.
- :param image_to: Where the Theme Image is to be saved to
+ :param Theme theme: The theme data object.
+ :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.
+ :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to
+ :rtype: None
"""
name = theme.theme_name
- theme_pretty = theme.export_theme()
- theme_dir = os.path.join(self.path, name)
- check_directory_exists(Path(theme_dir))
- theme_file = os.path.join(theme_dir, name + '.json')
- if self.old_background_image and image_to != self.old_background_image:
- delete_file(Path(self.old_background_image))
- out_file = None
+ theme_pretty = theme.export_theme(self.theme_path)
+ theme_dir = self.theme_path / name
+ check_directory_exists(theme_dir)
+ theme_path = theme_dir / '{file_name}.json'.format(file_name=name)
try:
- out_file = open(theme_file, 'w', encoding='utf-8')
- out_file.write(theme_pretty)
+ theme_path.write_text(theme_pretty)
except IOError:
self.log_exception('Saving theme to file failed')
- finally:
- if out_file:
- out_file.close()
- if image_from and os.path.abspath(image_from) != os.path.abspath(image_to):
- try:
- # Windows is always unicode, so no need to encode filenames
- if is_win():
- shutil.copyfile(image_from, image_to)
- else:
- encoding = get_filesystem_encoding()
- shutil.copyfile(image_from.encode(encoding), image_to.encode(encoding))
- except IOError as xxx_todo_changeme:
- shutil.Error = xxx_todo_changeme
- self.log_exception('Failed to save theme image')
+ if image_source_path and image_destination_path:
+ if self.old_background_image_path and image_destination_path != self.old_background_image_path:
+ delete_file(self.old_background_image_path)
+ if image_source_path != image_destination_path:
+ try:
+ copyfile(image_source_path, image_destination_path)
+ except IOError:
+ self.log_exception('Failed to save theme image')
self.generate_and_save_image(name, theme)
- def generate_and_save_image(self, name, theme):
+ def generate_and_save_image(self, theme_name, theme):
"""
Generate and save a preview image
- :param name: The name of the theme.
+ :param str theme_name: The name of the theme.
:param theme: The theme data object.
"""
frame = self.generate_image(theme)
- sample_path_name = os.path.join(self.path, name + '.png')
- if os.path.exists(sample_path_name):
- os.unlink(sample_path_name)
- frame.save(sample_path_name, 'png')
- thumb = os.path.join(self.thumb_path, '{name}.png'.format(name=name))
- create_thumb(sample_path_name, thumb, False)
+ sample_path_name = self.theme_path / '{file_name}.png'.format(file_name=theme_name)
+ if sample_path_name.exists():
+ sample_path_name.unlink()
+ frame.save(str(sample_path_name), 'png')
+ thumb_path = self.thumb_path / '{name}.png'.format(name=theme_name)
+ create_thumb(str(sample_path_name), str(thumb_path), False)
def update_preview_images(self):
"""
@@ -730,39 +712,32 @@
"""
return self.renderer.generate_preview(theme_data, force_page)
- def get_preview_image(self, theme):
- """
- Return an image representing the look of the theme
-
- :param theme: The theme to return the image for.
- """
- return os.path.join(self.path, theme + '.png')
-
@staticmethod
def _create_theme_from_xml(theme_xml, image_path):
"""
Return a theme object using information parsed from XML
:param theme_xml: The Theme data object.
- :param image_path: Where the theme image is stored
+ :param openlp.core.common.path.Path image_path: Where the theme image is stored
:return: Theme data.
+ :rtype: Theme
"""
theme = Theme()
theme.parse(theme_xml)
theme.extend_image_filename(image_path)
return theme
- @staticmethod
- def _create_theme_from_json(theme_json, image_path):
+ def _create_theme_from_json(self, theme_json, image_path):
"""
Return a theme object using information parsed from JSON
:param theme_json: The Theme data object.
- :param image_path: Where the theme image is stored
+ :param openlp.core.common.path.Path image_path: Where the theme image is stored
:return: Theme data.
+ :rtype: Theme
"""
theme = Theme()
- theme.load_theme(theme_json)
+ theme.load_theme(theme_json, self.theme_path)
theme.extend_image_filename(image_path)
return theme
=== modified file 'openlp/core/ui/themestab.py'
--- openlp/core/ui/themestab.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/themestab.py 2017-09-26 17:09:04 +0000
@@ -211,8 +211,8 @@
"""
Utility method to update the global theme preview image.
"""
- image = self.theme_manager.get_preview_image(self.global_theme)
- preview = QtGui.QPixmap(str(image))
+ image_path = self.theme_manager.theme_path / '{file_name}.png'.format(file_name=self.global_theme)
+ preview = QtGui.QPixmap(str(image_path))
if not preview.isNull():
preview = preview.scaled(300, 255, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
self.default_list_view.setPixmap(preview)
=== modified file 'openlp/plugins/images/lib/upgrade.py'
--- openlp/plugins/images/lib/upgrade.py 2017-09-23 13:06:42 +0000
+++ openlp/plugins/images/lib/upgrade.py 2017-09-26 17:09:04 +0000
@@ -48,7 +48,6 @@
"""
Version 2 upgrade - Move file path from old db to JSON encoded path to new db. Added during 2.5 dev
"""
- # TODO: Update tests
log.debug('Starting upgrade_2 for file_path to JSON')
old_table = Table('image_filenames', metadata, autoload=True)
if 'file_path' not in [col.name for col in old_table.c.values()]:
=== modified file 'tests/functional/openlp_core_lib/test_theme.py'
--- tests/functional/openlp_core_lib/test_theme.py 2017-05-24 20:04:48 +0000
+++ tests/functional/openlp_core_lib/test_theme.py 2017-09-26 17:09:04 +0000
@@ -22,8 +22,9 @@
"""
Package to test the openlp.core.lib.theme package.
"""
+import os
+from pathlib import Path
from unittest import TestCase
-import os
from openlp.core.lib.theme import Theme
@@ -79,16 +80,16 @@
"""
# GIVEN: A theme object
theme = Theme()
- theme.theme_name = 'MyBeautifulTheme '
- theme.background_filename = ' video.mp4'
+ theme.theme_name = 'MyBeautifulTheme'
+ theme.background_filename = Path('video.mp4')
theme.background_type = 'video'
- path = os.path.expanduser('~')
+ path = Path.home()
# WHEN: Theme.extend_image_filename is run
theme.extend_image_filename(path)
# THEN: The filename of the background should be correct
- expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4')
+ expected_filename = path / 'MyBeautifulTheme' / 'video.mp4'
self.assertEqual(expected_filename, theme.background_filename)
self.assertEqual('MyBeautifulTheme', theme.theme_name)
=== modified file 'tests/functional/openlp_core_ui/test_maindisplay.py'
--- tests/functional/openlp_core_ui/test_maindisplay.py 2017-07-08 13:12:31 +0000
+++ tests/functional/openlp_core_ui/test_maindisplay.py 2017-09-26 17:09:04 +0000
@@ -27,10 +27,10 @@
from PyQt5 import QtCore
-from openlp.core.common import Registry, is_macosx, Settings
+from openlp.core.common import Registry, is_macosx
+from openlp.core.common.path import Path
from openlp.core.lib import ScreenList, PluginManager
from openlp.core.ui import MainDisplay, AudioPlayer
-from openlp.core.ui.media import MediaController
from openlp.core.ui.maindisplay import TRANSPARENT_STYLESHEET, OPAQUE_STYLESHEET
from tests.helpers.testmixin import TestMixin
@@ -184,7 +184,7 @@
self.assertEqual(pyobjc_nsview.window().collectionBehavior(), NSWindowCollectionBehaviorManaged,
'Window collection behavior should be NSWindowCollectionBehaviorManaged')
- @patch(u'openlp.core.ui.maindisplay.Settings')
+ @patch('openlp.core.ui.maindisplay.Settings')
def test_show_display_startup_logo(self, MockedSettings):
# GIVEN: Mocked show_display, setting for logo visibility
display = MagicMock()
@@ -204,7 +204,7 @@
# THEN: setVisible should had been called with "True"
main_display.setVisible.assert_called_once_with(True)
- @patch(u'openlp.core.ui.maindisplay.Settings')
+ @patch('openlp.core.ui.maindisplay.Settings')
def test_show_display_hide_startup_logo(self, MockedSettings):
# GIVEN: Mocked show_display, setting for logo visibility
display = MagicMock()
@@ -224,8 +224,8 @@
# THEN: setVisible should had not been called
main_display.setVisible.assert_not_called()
- @patch(u'openlp.core.ui.maindisplay.Settings')
- @patch(u'openlp.core.ui.maindisplay.build_html')
+ @patch('openlp.core.ui.maindisplay.Settings')
+ @patch('openlp.core.ui.maindisplay.build_html')
def test_build_html_no_video(self, MockedSettings, Mocked_build_html):
# GIVEN: Mocked display
display = MagicMock()
@@ -252,8 +252,8 @@
self.assertEquals(main_display.media_controller.video.call_count, 0,
'Media Controller video should not have been called')
- @patch(u'openlp.core.ui.maindisplay.Settings')
- @patch(u'openlp.core.ui.maindisplay.build_html')
+ @patch('openlp.core.ui.maindisplay.Settings')
+ @patch('openlp.core.ui.maindisplay.build_html')
def test_build_html_video(self, MockedSettings, Mocked_build_html):
# GIVEN: Mocked display
display = MagicMock()
@@ -270,7 +270,7 @@
service_item.theme_data = MagicMock()
service_item.theme_data.background_type = 'video'
service_item.theme_data.theme_name = 'name'
- service_item.theme_data.background_filename = 'background_filename'
+ service_item.theme_data.background_filename = Path('background_filename')
mocked_plugin = MagicMock()
display.plugin_manager = PluginManager()
display.plugin_manager.plugins = [mocked_plugin]
=== modified file 'tests/functional/openlp_core_ui/test_themeform.py'
--- tests/functional/openlp_core_ui/test_themeform.py 2017-08-25 20:03:25 +0000
+++ tests/functional/openlp_core_ui/test_themeform.py 2017-09-26 17:09:04 +0000
@@ -49,5 +49,5 @@
self.instance.on_image_path_edit_path_changed(Path('/', 'new', 'pat.h'))
# THEN: The theme background file should be set and `set_background_page_values` should have been called
- self.assertEqual(self.instance.theme.background_filename, '/new/pat.h')
+ self.assertEqual(self.instance.theme.background_filename, Path('/', 'new', 'pat.h'))
mocked_set_background_page_values.assert_called_once_with()
=== modified file 'tests/functional/openlp_core_ui/test_thememanager.py'
--- tests/functional/openlp_core_ui/test_thememanager.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_ui/test_thememanager.py 2017-09-26 17:09:04 +0000
@@ -30,8 +30,9 @@
from PyQt5 import QtWidgets
+from openlp.core.common import Registry
+from openlp.core.common.path import Path
from openlp.core.ui import ThemeManager
-from openlp.core.common import Registry
from tests.utils.constants import TEST_RESOURCES_PATH
@@ -57,13 +58,13 @@
"""
# GIVEN: A new ThemeManager instance.
theme_manager = ThemeManager()
- theme_manager.path = os.path.join(TEST_RESOURCES_PATH, 'themes')
+ theme_manager.theme_path = Path(TEST_RESOURCES_PATH, 'themes')
with patch('zipfile.ZipFile.__init__') as mocked_zipfile_init, \
patch('zipfile.ZipFile.write') as mocked_zipfile_write:
mocked_zipfile_init.return_value = None
# WHEN: The theme is exported
- theme_manager._export_theme(os.path.join('some', 'path', 'Default.otz'), 'Default')
+ theme_manager._export_theme(Path('some', 'path', 'Default.otz'), 'Default')
# THEN: The zipfile should be created at the given path
mocked_zipfile_init.assert_called_with(os.path.join('some', 'path', 'Default.otz'), 'w')
@@ -86,57 +87,49 @@
"""
Test that we don't try to overwrite a theme background image with itself
"""
- # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile,
+ # GIVEN: A new theme manager instance, with mocked builtins.open, copyfile,
# theme, check_directory_exists and thememanager-attributes.
- with patch('builtins.open') as mocked_open, \
- patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \
+ with patch('openlp.core.ui.thememanager.copyfile') as mocked_copyfile, \
patch('openlp.core.ui.thememanager.check_directory_exists'):
- mocked_open.return_value = MagicMock()
theme_manager = ThemeManager(None)
theme_manager.old_background_image = None
theme_manager.generate_and_save_image = MagicMock()
- theme_manager.path = ''
+ theme_manager.theme_path = MagicMock()
mocked_theme = MagicMock()
mocked_theme.theme_name = 'themename'
mocked_theme.extract_formatted_xml = MagicMock()
mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode()
# WHEN: Calling _write_theme with path to the same image, but the path written slightly different
- file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg')
- # Do replacement from end of string to avoid problems with path start
- file_name2 = file_name1[::-1].replace(os.sep, os.sep + os.sep, 2)[::-1]
- theme_manager._write_theme(mocked_theme, file_name1, file_name2)
+ file_name1 = Path(TEST_RESOURCES_PATH, 'church.jpg')
+ theme_manager._write_theme(mocked_theme, file_name1, file_name1)
# THEN: The mocked_copyfile should not have been called
- self.assertFalse(mocked_copyfile.called, 'shutil.copyfile should not be called')
+ self.assertFalse(mocked_copyfile.called, 'copyfile should not be called')
def test_write_theme_diff_images(self):
"""
Test that we do overwrite a theme background image when a new is submitted
"""
- # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile,
+ # GIVEN: A new theme manager instance, with mocked builtins.open, copyfile,
# theme, check_directory_exists and thememanager-attributes.
- with patch('builtins.open') as mocked_open, \
- patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \
+ with patch('openlp.core.ui.thememanager.copyfile') as mocked_copyfile, \
patch('openlp.core.ui.thememanager.check_directory_exists'):
- mocked_open.return_value = MagicMock()
theme_manager = ThemeManager(None)
theme_manager.old_background_image = None
theme_manager.generate_and_save_image = MagicMock()
- theme_manager.path = ''
+ theme_manager.theme_path = MagicMock()
mocked_theme = MagicMock()
mocked_theme.theme_name = 'themename'
mocked_theme.filename = "filename"
- # mocked_theme.extract_formatted_xml = MagicMock()
- # mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode()
# WHEN: Calling _write_theme with path to different images
- file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg')
- file_name2 = os.path.join(TEST_RESOURCES_PATH, 'church2.jpg')
+ file_name1 = Path(TEST_RESOURCES_PATH, 'church.jpg')
+ file_name2 = Path(TEST_RESOURCES_PATH, 'church2.jpg')
theme_manager._write_theme(mocked_theme, file_name1, file_name2)
# THEN: The mocked_copyfile should not have been called
- self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called')
+ self.assertTrue(mocked_copyfile.called, 'copyfile should be called')
def test_write_theme_special_char_name(self):
"""
@@ -146,7 +139,7 @@
theme_manager = ThemeManager(None)
theme_manager.old_background_image = None
theme_manager.generate_and_save_image = MagicMock()
- theme_manager.path = self.temp_folder
+ theme_manager.theme_path = Path(self.temp_folder)
mocked_theme = MagicMock()
mocked_theme.theme_name = 'theme 愛 name'
mocked_theme.export_theme.return_value = "{}"
@@ -208,17 +201,17 @@
theme_manager = ThemeManager(None)
theme_manager._create_theme_from_xml = MagicMock()
theme_manager.generate_and_save_image = MagicMock()
- theme_manager.path = ''
- folder = mkdtemp()
- theme_file = os.path.join(TEST_RESOURCES_PATH, 'themes', 'Moss_on_tree.otz')
+ theme_manager.theme_path = None
+ folder = Path(mkdtemp())
+ theme_file = Path(TEST_RESOURCES_PATH, 'themes', 'Moss_on_tree.otz')
# WHEN: We try to unzip it
theme_manager.unzip_theme(theme_file, folder)
# THEN: Files should be unpacked
- self.assertTrue(os.path.exists(os.path.join(folder, 'Moss on tree', 'Moss on tree.xml')))
+ self.assertTrue((folder / 'Moss on tree' / 'Moss on tree.xml').exists())
self.assertEqual(mocked_critical_error_message_box.call_count, 0, 'No errors should have happened')
- shutil.rmtree(folder)
+ shutil.rmtree(str(folder))
def test_unzip_theme_invalid_version(self):
"""
=== modified file 'tests/interfaces/openlp_core_ui/test_thememanager.py'
--- tests/interfaces/openlp_core_ui/test_thememanager.py 2017-04-24 05:17:55 +0000
+++ tests/interfaces/openlp_core_ui/test_thememanager.py 2017-09-26 17:09:04 +0000
@@ -26,7 +26,8 @@
from unittest.mock import patch, MagicMock
from openlp.core.common import Registry, Settings
-from openlp.core.ui import ThemeManager, ThemeForm, FileRenameForm
+from openlp.core.common.path import Path
+from openlp.core.ui import ThemeManager
from tests.helpers.testmixin import TestMixin
@@ -91,6 +92,23 @@
assert self.theme_manager.thumb_path.startswith(self.theme_manager.path) is True, \
'The thumb path and the main path should start with the same value'
+ def test_build_theme_path(self):
+ """
+ Test the thememanager build_theme_path - basic test
+ """
+ # GIVEN: A new a call to initialise
+ with patch('openlp.core.common.AppLocation.get_section_data_path', return_value=Path('test/path')):
+ Settings().setValue('themes/global theme', 'my_theme')
+
+ self.theme_manager.theme_form = MagicMock()
+ self.theme_manager.load_first_time_themes = MagicMock()
+
+ # WHEN: the build_theme_path is run
+ self.theme_manager.build_theme_path()
+
+ # THEN: The thumbnail path should be a sub path of the test path
+ self.assertEqual(self.theme_manager.thumb_path, Path('test/path/thumbnails'))
+
def test_click_on_new_theme(self):
"""
Test the on_add_theme event handler is called by the UI
@@ -109,17 +127,16 @@
@patch('openlp.core.ui.themeform.ThemeForm._setup')
@patch('openlp.core.ui.filerenameform.FileRenameForm._setup')
- def test_bootstrap_post(self, mocked_theme_form, mocked_rename_form):
+ def test_bootstrap_post(self, mocked_rename_form, mocked_theme_form):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
- self.theme_manager.path = MagicMock()
+ self.theme_manager.theme_path = MagicMock()
# WHEN:
self.theme_manager.bootstrap_post_set_up()
# THEN:
- self.assertEqual(self.theme_manager.path, self.theme_manager.theme_form.path)
self.assertEqual(1, self.theme_manager.load_themes.call_count, "load_themes should have been called once")
Follow ups