Modify setting upgrade code to provide versioned updates. Upgrade settings to use JSON encoded Path objects

This commit is contained in:
Philip Ridout 2017-08-26 16:06:11 +01:00
parent f8a68c23d0
commit 8f9cb4a090
30 changed files with 251 additions and 219 deletions

View File

@ -405,7 +405,7 @@ def main(args=None):
# Set our data path # Set our data path
log.info('Data path: {name}'.format(name=data_path)) log.info('Data path: {name}'.format(name=data_path))
# Point to our data path # Point to our data path
portable_settings.setValue('advanced/data path', str(data_path)) portable_settings.setValue('advanced/data path', data_path)
portable_settings.setValue('advanced/is portable', True) portable_settings.setValue('advanced/is portable', True)
portable_settings.sync() portable_settings.sync()
else: else:
@ -422,8 +422,8 @@ def main(args=None):
if application.is_data_path_missing(): if application.is_data_path_missing():
application.shared_memory.detach() application.shared_memory.detach()
sys.exit() sys.exit()
# Remove/convert obsolete settings. # Upgrade settings.
Settings().remove_obsolete_settings() Settings().upgrade_settings()
# First time checks in settings # First time checks in settings
if not Settings().value('core/has run wizard'): if not Settings().value('core/has run wizard'):
if not FirstTimeLanguageForm().exec(): if not FirstTimeLanguageForm().exec():

View File

@ -79,8 +79,7 @@ def controller_text(request):
item['title'] = str(frame['display_title']) item['title'] = str(frame['display_title'])
if current_item.is_capable(ItemCapabilities.HasNotes): if current_item.is_capable(ItemCapabilities.HasNotes):
item['slide_notes'] = str(frame['notes']) item['slide_notes'] = str(frame['notes'])
if current_item.is_capable(ItemCapabilities.HasThumbnails) and \ if current_item.is_capable(ItemCapabilities.HasThumbnails) and Settings().value('api/thumbnails'):
Settings().value('api/thumbnails'):
# If the file is under our app directory tree send the portion after the match # If the file is under our app directory tree send the portion after the match
data_path = str(AppLocation.get_data_path()) data_path = str(AppLocation.get_data_path())
if frame['image'][0:len(data_path)] == data_path: if frame['image'][0:len(data_path)] == data_path:

View File

@ -86,7 +86,7 @@ class AppLocation(object):
""" """
# Check if we have a different data location. # Check if we have a different data location.
if Settings().contains('advanced/data path'): if Settings().contains('advanced/data path'):
path = Path(Settings().value('advanced/data path')) path = Settings().value('advanced/data path')
else: else:
path = AppLocation.get_directory(AppLocation.DataDir) path = AppLocation.get_directory(AppLocation.DataDir)
check_directory_exists(path) check_directory_exists(path)
@ -118,7 +118,7 @@ class AppLocation(object):
""" """
Return the path a particular module stores its data under. Return the path a particular module stores its data under.
:type section: str :param str section:
:rtype: openlp.core.common.path.Path :rtype: openlp.core.common.path.Path
""" """
path = AppLocation.get_data_path() / section path = AppLocation.get_data_path() / section

View File

@ -24,15 +24,18 @@ This class contains the core default settings.
""" """
import datetime import datetime
import logging import logging
import json
import os import os
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
from openlp.core.common import ThemeLevel, SlideLimits, UiStrings, is_win, is_linux from openlp.core.common import SlideLimits, ThemeLevel, UiStrings, is_linux, is_win
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
from openlp.core.common.path import Path, path_to_str, str_to_path
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
__version__ = 2
# Fix for bug #1014422. # Fix for bug #1014422.
X11_BYPASS_DEFAULT = True X11_BYPASS_DEFAULT = True
@ -44,21 +47,6 @@ if is_linux():
X11_BYPASS_DEFAULT = False X11_BYPASS_DEFAULT = False
def recent_files_conv(value):
"""
If the value is not a list convert it to a list
:param value: Value to convert
:return: value as a List
"""
if isinstance(value, list):
return value
elif isinstance(value, str):
return [value]
elif isinstance(value, bytes):
return [value.decode()]
return []
def media_players_conv(string): def media_players_conv(string):
""" """
If phonon is in the setting string replace it with system If phonon is in the setting string replace it with system
@ -73,14 +61,24 @@ def media_players_conv(string):
return string return string
def file_names_conv(file_names):
"""
Convert a list of file names in to a list of file paths.
:param list[str] file_names: The list of file names to convert.
:return: The list converted to file paths
:rtype: openlp.core.common.path.Path
"""
return [str_to_path(file_name) for file_name in file_names]
class Settings(QtCore.QSettings): class Settings(QtCore.QSettings):
""" """
Class to wrap QSettings. Class to wrap QSettings.
* Exposes all the methods of QSettings. * Exposes all the methods of QSettings.
* Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to * Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to ``IniFormat``, and the path to the Ini
``IniFormat``, and the path to the Ini file is set using ``set_filename``, file is set using ``set_filename``, then the Settings constructor (without any arguments) will create a Settings
then the Settings constructor (without any arguments) will create a Settings
object for accessing settings stored in that Ini file. object for accessing settings stored in that Ini file.
``__default_settings__`` ``__default_settings__``
@ -91,7 +89,7 @@ class Settings(QtCore.QSettings):
('general/enable slide loop', 'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]) ('general/enable slide loop', 'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)])
The first entry is the *old key*; it will be removed. The first entry is the *old key*; if it is different from the *new key* it will be removed.
The second entry is the *new key*; we will add it to the config. If this is just an empty string, we just remove The second entry is the *new key*; we will add it to the config. If this is just an empty string, we just remove
the old key. The last entry is a list containing two-pair tuples. If the list is empty, no conversion is made. the old key. The last entry is a list containing two-pair tuples. If the list is empty, no conversion is made.
@ -105,11 +103,12 @@ class Settings(QtCore.QSettings):
So, if the type of the old value is bool, then there must be two rules. So, if the type of the old value is bool, then there must be two rules.
""" """
__default_settings__ = { __default_settings__ = {
'settings/version': 0,
'advanced/add page break': False, 'advanced/add page break': False,
'advanced/alternate rows': not is_win(), 'advanced/alternate rows': not is_win(),
'advanced/autoscrolling': {'dist': 1, 'pos': 0}, 'advanced/autoscrolling': {'dist': 1, 'pos': 0},
'advanced/current media plugin': -1, 'advanced/current media plugin': -1,
'advanced/data path': '', 'advanced/data path': None,
# 7 stands for now, 0 to 6 is Monday to Sunday. # 7 stands for now, 0 to 6 is Monday to Sunday.
'advanced/default service day': 7, 'advanced/default service day': 7,
'advanced/default service enabled': True, 'advanced/default service enabled': True,
@ -143,7 +142,7 @@ class Settings(QtCore.QSettings):
'api/authentication enabled': False, 'api/authentication enabled': False,
'api/ip address': '0.0.0.0', 'api/ip address': '0.0.0.0',
'api/thumbnails': True, 'api/thumbnails': True,
'crashreport/last directory': '', 'crashreport/last directory': None,
'formattingTags/html_tags': '', 'formattingTags/html_tags': '',
'core/audio repeat list': False, 'core/audio repeat list': False,
'core/auto open': False, 'core/auto open': False,
@ -162,7 +161,7 @@ class Settings(QtCore.QSettings):
'core/screen blank': False, 'core/screen blank': False,
'core/show splash': True, 'core/show splash': True,
'core/logo background color': '#ffffff', 'core/logo background color': '#ffffff',
'core/logo file': ':/graphics/openlp-splash-screen.png', 'core/logo file': Path(':/graphics/openlp-splash-screen.png'),
'core/logo hide on startup': False, 'core/logo hide on startup': False,
'core/songselect password': '', 'core/songselect password': '',
'core/songselect username': '', 'core/songselect username': '',
@ -177,17 +176,17 @@ class Settings(QtCore.QSettings):
'media/players': 'system,webkit', 'media/players': 'system,webkit',
'media/override player': QtCore.Qt.Unchecked, 'media/override player': QtCore.Qt.Unchecked,
'players/background color': '#000000', 'players/background color': '#000000',
'servicemanager/last directory': '', 'servicemanager/last directory': None,
'servicemanager/last file': '', 'servicemanager/last file': None,
'servicemanager/service theme': '', 'servicemanager/service theme': None,
'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"), 'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
'SettingsImport/Make_Changes': 'At_Own_RISK', 'SettingsImport/Make_Changes': 'At_Own_RISK',
'SettingsImport/type': 'OpenLP_settings_export', 'SettingsImport/type': 'OpenLP_settings_export',
'SettingsImport/version': '', 'SettingsImport/version': '',
'themes/global theme': '', 'themes/global theme': '',
'themes/last directory': '', 'themes/last directory': None,
'themes/last directory export': '', 'themes/last directory export': None,
'themes/last directory import': '', 'themes/last directory import': None,
'themes/theme level': ThemeLevel.Song, 'themes/theme level': ThemeLevel.Song,
'themes/wrap footer': False, 'themes/wrap footer': False,
'user interface/live panel': True, 'user interface/live panel': True,
@ -208,22 +207,20 @@ class Settings(QtCore.QSettings):
'projector/db database': '', 'projector/db database': '',
'projector/enable': True, 'projector/enable': True,
'projector/connect on start': False, 'projector/connect on start': False,
'projector/last directory import': '', 'projector/last directory import': None,
'projector/last directory export': '', 'projector/last directory export': None,
'projector/poll time': 20, # PJLink timeout is 30 seconds 'projector/poll time': 20, # PJLink timeout is 30 seconds
'projector/socket timeout': 5, # 5 second socket timeout 'projector/socket timeout': 5, # 5 second socket timeout
'projector/source dialog type': 0 # Source select dialog box type 'projector/source dialog type': 0 # Source select dialog box type
} }
__file_path__ = '' __file_path__ = ''
__obsolete_settings__ = [ __setting_upgrade_1__ = [
# Changed during 2.2.x development. # Changed during 2.2.x development.
# ('advanced/stylesheet fix', '', []),
# ('general/recent files', 'core/recent files', [(recent_files_conv, None)]),
('songs/search as type', 'advanced/search as type', []), ('songs/search as type', 'advanced/search as type', []),
('media/players', 'media/players_temp', [(media_players_conv, None)]), # Convert phonon to system ('media/players', 'media/players_temp', [(media_players_conv, None)]), # Convert phonon to system
('media/players_temp', 'media/players', []), # Move temp setting from above to correct setting ('media/players_temp', 'media/players', []), # Move temp setting from above to correct setting
('advanced/default color', 'core/logo background color', []), # Default image renamed + moved to general > 2.4. ('advanced/default color', 'core/logo background color', []), # Default image renamed + moved to general > 2.4.
('advanced/default image', '/core/logo file', []), # Default image renamed + moved to general after 2.4. ('advanced/default image', 'core/logo file', []), # Default image renamed + moved to general after 2.4.
('remotes/https enabled', '', []), ('remotes/https enabled', '', []),
('remotes/https port', '', []), ('remotes/https port', '', []),
('remotes/twelve hour', 'api/twelve hour', []), ('remotes/twelve hour', 'api/twelve hour', []),
@ -234,7 +231,6 @@ class Settings(QtCore.QSettings):
('remotes/authentication enabled', 'api/authentication enabled', []), ('remotes/authentication enabled', 'api/authentication enabled', []),
('remotes/ip address', 'api/ip address', []), ('remotes/ip address', 'api/ip address', []),
('remotes/thumbnails', 'api/thumbnails', []), ('remotes/thumbnails', 'api/thumbnails', []),
('advanced/default image', 'core/logo file', []), # Default image renamed + moved to general after 2.4.
('shortcuts/escapeItem', 'shortcuts/desktopScreenEnable', []), # Escape item was removed in 2.6. ('shortcuts/escapeItem', 'shortcuts/desktopScreenEnable', []), # Escape item was removed in 2.6.
('shortcuts/offlineHelpItem', 'shortcuts/userManualItem', []), # Online and Offline help were combined in 2.6. ('shortcuts/offlineHelpItem', 'shortcuts/userManualItem', []), # Online and Offline help were combined in 2.6.
('shortcuts/onlineHelpItem', 'shortcuts/userManualItem', []), # Online and Offline help were combined in 2.6. ('shortcuts/onlineHelpItem', 'shortcuts/userManualItem', []), # Online and Offline help were combined in 2.6.
@ -243,7 +239,28 @@ class Settings(QtCore.QSettings):
# Last search type was renamed to last used search type in 2.6 since Bible search value type changed in 2.6. # Last search type was renamed to last used search type in 2.6 since Bible search value type changed in 2.6.
('songs/last search type', 'songs/last used search type', []), ('songs/last search type', 'songs/last used search type', []),
('bibles/last search type', '', []), ('bibles/last search type', '', []),
('custom/last search type', 'custom/last used search type', []) ('custom/last search type', 'custom/last used search type', [])]
__setting_upgrade_2__ = [
# The following changes are being made for the conversion to using Path objects made in 2.6 development
('advanced/data path', 'advanced/data path', [(str_to_path, None)]),
('crashreport/last directory', 'crashreport/last directory', [(str_to_path, None)]),
('servicemanager/last directory', 'servicemanager/last directory', [(str_to_path, None)]),
('servicemanager/last file', 'servicemanager/last file', [(str_to_path, None)]),
('themes/last directory', 'themes/last directory', [(str_to_path, None)]),
('themes/last directory export', 'themes/last directory export', [(str_to_path, None)]),
('themes/last directory import', 'themes/last directory import', [(str_to_path, None)]),
('projector/last directory import', 'projector/last directory import', [(str_to_path, None)]),
('projector/last directory export', 'projector/last directory export', [(str_to_path, None)]),
('bibles/last directory import', 'bibles/last directory import', [(str_to_path, None)]),
('presentations/pdf_program', 'presentations/pdf_program', [(str_to_path, None)]),
('songs/last directory import', 'songs/last directory import', [(str_to_path, None)]),
('songs/last directory export', 'songs/last directory export', [(str_to_path, None)]),
('songusage/last directory export', 'songusage/last directory export', [(str_to_path, None)]),
('core/recent files', 'core/recent files', [(file_names_conv, None)]),
('media/media files', 'media/media files', [(file_names_conv, None)]),
('presentations/presentations files', 'presentations/presentations files', [(file_names_conv, None)]),
('core/logo file', 'core/logo file', [(str_to_path, None)])
] ]
@staticmethod @staticmethod
@ -256,13 +273,16 @@ class Settings(QtCore.QSettings):
Settings.__default_settings__.update(default_values) Settings.__default_settings__.update(default_values)
@staticmethod @staticmethod
def set_filename(ini_file): def set_filename(ini_path):
""" """
Sets the complete path to an Ini file to be used by Settings objects. Sets the complete path to an Ini file to be used by Settings objects.
Does not affect existing Settings objects. Does not affect existing Settings objects.
:param openlp.core.common.path.Path ini_path: ini file path
:rtype: None
""" """
Settings.__file_path__ = ini_file Settings.__file_path__ = str(ini_path)
@staticmethod @staticmethod
def set_up_default_values(): def set_up_default_values():
@ -431,14 +451,22 @@ class Settings(QtCore.QSettings):
key = self.group() + '/' + key key = self.group() + '/' + key
return Settings.__default_settings__[key] return Settings.__default_settings__[key]
def remove_obsolete_settings(self): def upgrade_settings(self):
""" """
This method is only called to clean up the config. It removes old settings and it renames settings. See This method is only called to clean up the config. It removes old settings and it renames settings. See
``__obsolete_settings__`` for more details. ``__obsolete_settings__`` for more details.
""" """
for old_key, new_key, rules in Settings.__obsolete_settings__: current_version = self.value('settings/version')
# Once removed we don't have to do this again. if __version__ == current_version:
if self.contains(old_key): return
for version in range(current_version, __version__):
version += 1
upgrade_list = getattr(self, '__setting_upgrade_{version}__'.format(version=version))
for old_key, new_key, rules in upgrade_list:
# Once removed we don't have to do this again. - Can be removed once fully switched to the versioning
# system.
if not self.contains(old_key):
continue
if new_key: if new_key:
# Get the value of the old_key. # Get the value of the old_key.
old_value = super(Settings, self).value(old_key) old_value = super(Settings, self).value(old_key)
@ -457,14 +485,17 @@ class Settings(QtCore.QSettings):
old_value = new old_value = new
break break
self.setValue(new_key, old_value) self.setValue(new_key, old_value)
self.remove(old_key) if new_key != old_key:
self.remove(old_key)
self.setValue('settings/version', version)
def value(self, key): def value(self, key):
""" """
Returns the value for the given ``key``. The returned ``value`` is of the same type as the default value in the Returns the value for the given ``key``. The returned ``value`` is of the same type as the default value in the
*Settings.__default_settings__* dict. *Settings.__default_settings__* dict.
:param key: The key to return the value from. :param str key: The key to return the value from.
:return: The value stored by the setting.
""" """
# if group() is not empty the group has not been specified together with the key. # if group() is not empty the group has not been specified together with the key.
if self.group(): if self.group():
@ -474,6 +505,18 @@ class Settings(QtCore.QSettings):
setting = super(Settings, self).value(key, default_value) setting = super(Settings, self).value(key, default_value)
return self._convert_value(setting, default_value) return self._convert_value(setting, default_value)
def setValue(self, key, value):
"""
Reimplement the setValue method to handle Path objects.
:param str key: The key of the setting to save
:param value: The value to save
:rtype: None
"""
if isinstance(value, Path) or (isinstance(value, list) and value and isinstance(value[0], Path)):
value = json.dumps(value, cls=OpenLPJsonEncoder)
super().setValue(key, value)
def _convert_value(self, setting, default_value): def _convert_value(self, setting, default_value):
""" """
This converts the given ``setting`` to the type of the given ``default_value``. This converts the given ``setting`` to the type of the given ``default_value``.
@ -491,8 +534,11 @@ class Settings(QtCore.QSettings):
if isinstance(default_value, str): if isinstance(default_value, str):
return '' return ''
# An empty list saved to the settings results in a None type being returned. # An empty list saved to the settings results in a None type being returned.
else: elif isinstance(default_value, list):
return [] return []
elif isinstance(setting, str):
if '__Path__' in setting:
return json.loads(setting, cls=OpenLPJsonDecoder)
# Convert the setting to the correct type. # Convert the setting to the correct type.
if isinstance(default_value, bool): if isinstance(default_value, bool):
if isinstance(setting, bool): if isinstance(setting, bool):

View File

@ -29,7 +29,7 @@ import re
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate
from openlp.core.common.path import path_to_str, str_to_path from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import ServiceItem, StringContent, ServiceItemContext from openlp.core.lib import ServiceItem, StringContent, ServiceItemContext
from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import create_widget_action, critical_error_message_box from openlp.core.lib.ui import create_widget_action, critical_error_message_box
@ -313,7 +313,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
""" """
file_paths, selected_filter = FileDialog.getOpenFileNames( file_paths, selected_filter = FileDialog.getOpenFileNames(
self, self.on_new_prompt, self, self.on_new_prompt,
str_to_path(Settings().value(self.settings_section + '/last directory')), Settings().value(self.settings_section + '/last directory'),
self.on_new_file_masks) self.on_new_file_masks)
log.info('New files(s) {file_paths}'.format(file_paths=file_paths)) log.info('New files(s) {file_paths}'.format(file_paths=file_paths))
if file_paths: if file_paths:
@ -377,9 +377,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
self.list_view.clear() self.list_view.clear()
self.load_list(full_list, target_group) self.load_list(full_list, target_group)
last_dir = os.path.split(files[0])[0] last_dir = os.path.split(files[0])[0]
Settings().setValue(self.settings_section + '/last directory', last_dir) Settings().setValue(self.settings_section + '/last directory', Path(last_dir))
Settings().setValue('{section}/{section} files'.format(section=self.settings_section), Settings().setValue('{section}/{section} files'.format(section=self.settings_section), self.get_file_list())
self.get_file_list())
if duplicates_found: if duplicates_found:
critical_error_message_box(UiStrings().Duplicate, critical_error_message_box(UiStrings().Duplicate,
translate('OpenLP.MediaManagerItem', translate('OpenLP.MediaManagerItem',
@ -400,13 +399,15 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
def get_file_list(self): def get_file_list(self):
""" """
Return the current list of files Return the current list of files
:rtype: list[openlp.core.common.path.Path]
""" """
file_list = [] file_paths = []
for index in range(self.list_view.count()): for index in range(self.list_view.count()):
list_item = self.list_view.item(index) list_item = self.list_view.item(index)
filename = list_item.data(QtCore.Qt.UserRole) filename = list_item.data(QtCore.Qt.UserRole)
file_list.append(filename) file_paths.append(str_to_path(filename))
return file_list return file_paths
def load_list(self, load_list, target_group): def load_list(self, load_list, target_group):
""" """

View File

@ -150,7 +150,7 @@ class Plugin(QtCore.QObject, RegistryProperties):
self.status = PluginStatus.Inactive self.status = PluginStatus.Inactive
# Add the default status to the default settings. # Add the default status to the default settings.
default_settings[name + '/status'] = PluginStatus.Inactive default_settings[name + '/status'] = PluginStatus.Inactive
default_settings[name + '/last directory'] = '' default_settings[name + '/last directory'] = None
# Append a setting for files in the mediamanager (note not all plugins # Append a setting for files in the mediamanager (note not all plugins
# which have a mediamanager need this). # which have a mediamanager need this).
if media_item_class is not None: if media_item_class is not None:

View File

@ -70,9 +70,9 @@ try:
except ImportError: except ImportError:
VLC_VERSION = '-' VLC_VERSION = '-'
from openlp.core.common import Settings, UiStrings, translate from openlp.core.common import RegistryProperties, Settings, UiStrings, is_linux, translate
from openlp.core.common.versionchecker import get_application_version from openlp.core.common.versionchecker import get_application_version
from openlp.core.common import RegistryProperties, is_linux from openlp.core.ui.lib.filedialog import FileDialog
from .exceptiondialog import Ui_ExceptionDialog from .exceptiondialog import Ui_ExceptionDialog
@ -139,17 +139,17 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
""" """
Saving exception log and system information to a file. Saving exception log and system information to a file.
""" """
filename = QtWidgets.QFileDialog.getSaveFileName( file_path, filter_used = FileDialog.getSaveFileName(
self, self,
translate('OpenLP.ExceptionForm', 'Save Crash Report'), translate('OpenLP.ExceptionForm', 'Save Crash Report'),
Settings().value(self.settings_section + '/last directory'), Settings().value(self.settings_section + '/last directory'),
translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)'))[0] translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)'))
if filename: if file_path:
filename = str(filename).replace('/', os.path.sep) Settings().setValue(self.settings_section + '/last directory', file_path.parent)
Settings().setValue(self.settings_section + '/last directory', os.path.dirname(filename))
opts = self._create_report() opts = self._create_report()
report_text = self.report_text.format(version=opts['version'], description=opts['description'], report_text = self.report_text.format(version=opts['version'], description=opts['description'],
traceback=opts['traceback'], libs=opts['libs'], system=opts['system']) traceback=opts['traceback'], libs=opts['libs'], system=opts['system'])
filename = str(file_path)
try: try:
report_file = open(filename, 'w') report_file = open(filename, 'w')
try: try:
@ -212,17 +212,16 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
def on_attach_file_button_clicked(self): def on_attach_file_button_clicked(self):
""" """
Attache files to the bug report e-mail. Attach files to the bug report e-mail.
""" """
files, filter_used = QtWidgets.QFileDialog.getOpenFileName(self, file_path, filter_used = \
translate('ImagePlugin.ExceptionDialog', FileDialog.getOpenFileName(self,
'Select Attachment'), translate('ImagePlugin.ExceptionDialog', 'Select Attachment'),
Settings().value(self.settings_section + Settings().value(self.settings_section + '/last directory'),
'/last directory'), '{text} (*)'.format(text=UiStrings().AllFiles))
'{text} (*)'.format(text=UiStrings().AllFiles)) log.info('New file {file}'.format(file=file_path))
log.info('New files(s) {files}'.format(files=str(files))) if file_path:
if files: self.file_attachment = str(file_path)
self.file_attachment = str(files)
def __button_state(self, state): def __button_state(self, state):
""" """

View File

@ -293,7 +293,7 @@ class GeneralTab(SettingsTab):
self.auto_open_check_box.setChecked(settings.value('auto open')) self.auto_open_check_box.setChecked(settings.value('auto open'))
self.show_splash_check_box.setChecked(settings.value('show splash')) self.show_splash_check_box.setChecked(settings.value('show splash'))
self.logo_background_color = settings.value('logo background color') self.logo_background_color = settings.value('logo background color')
self.logo_file_path_edit.path = str_to_path(settings.value('logo file')) self.logo_file_path_edit.path = settings.value('logo file')
self.logo_hide_on_startup_check_box.setChecked(settings.value('logo hide on startup')) self.logo_hide_on_startup_check_box.setChecked(settings.value('logo hide on startup'))
self.logo_color_button.color = self.logo_background_color self.logo_color_button.color = self.logo_background_color
self.check_for_updates_check_box.setChecked(settings.value('update check')) self.check_for_updates_check_box.setChecked(settings.value('update check'))
@ -327,7 +327,7 @@ class GeneralTab(SettingsTab):
settings.setValue('auto open', self.auto_open_check_box.isChecked()) settings.setValue('auto open', self.auto_open_check_box.isChecked())
settings.setValue('show splash', self.show_splash_check_box.isChecked()) settings.setValue('show splash', self.show_splash_check_box.isChecked())
settings.setValue('logo background color', self.logo_background_color) settings.setValue('logo background color', self.logo_background_color)
settings.setValue('logo file', path_to_str(self.logo_file_path_edit.path)) settings.setValue('logo file', self.logo_file_path_edit.path)
settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked()) settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked())
settings.setValue('update check', self.check_for_updates_check_box.isChecked()) settings.setValue('update check', self.check_for_updates_check_box.isChecked())
settings.setValue('save prompt', self.save_check_service_check_box.isChecked()) settings.setValue('save prompt', self.save_check_service_check_box.isChecked())

View File

@ -30,6 +30,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate, is_macosx from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate, is_macosx
from openlp.core.lib import build_icon from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page from openlp.core.lib.ui import add_welcome_page
from openlp.core.ui.lib.filedialog import FileDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -278,37 +279,38 @@ class OpenLPWizard(QtWidgets.QWizard, RegistryProperties):
def get_file_name(self, title, editbox, setting_name, filters=''): def get_file_name(self, title, editbox, setting_name, filters=''):
""" """
Opens a QFileDialog and saves the filename to the given editbox. Opens a FileDialog and saves the filename to the given editbox.
:param title: The title of the dialog (unicode). :param str title: The title of the dialog.
:param editbox: An editbox (QLineEdit). :param QtWidgets.QLineEdit editbox: An QLineEdit.
:param setting_name: The place where to save the last opened directory. :param str setting_name: The place where to save the last opened directory.
:param filters: The file extension filters. It should contain the file description :param str filters: The file extension filters. It should contain the file description
as well as the file extension. For example:: as well as the file extension. For example::
'OpenLP 2 Databases (*.sqlite)' 'OpenLP 2 Databases (*.sqlite)'
:rtype: None
""" """
if filters: if filters:
filters += ';;' filters += ';;'
filters += '%s (*)' % UiStrings().AllFiles filters += '%s (*)' % UiStrings().AllFiles
filename, filter_used = QtWidgets.QFileDialog.getOpenFileName( file_path, filter_used = FileDialog.getOpenFileName(
self, title, os.path.dirname(Settings().value(self.plugin.settings_section + '/' + setting_name)), self, title, Settings().value(self.plugin.settings_section + '/' + setting_name), filters)
filters) if file_path:
if filename: editbox.setText(str(file_path))
editbox.setText(filename) Settings().setValue(self.plugin.settings_section + '/' + setting_name, file_path.parent)
Settings().setValue(self.plugin.settings_section + '/' + setting_name, filename)
def get_folder(self, title, editbox, setting_name): def get_folder(self, title, editbox, setting_name):
""" """
Opens a QFileDialog and saves the selected folder to the given editbox. Opens a FileDialog and saves the selected folder to the given editbox.
:param title: The title of the dialog (unicode). :param str title: The title of the dialog.
:param editbox: An editbox (QLineEdit). :param QtWidgets.QLineEdit editbox: An QLineEditbox.
:param setting_name: The place where to save the last opened directory. :param str setting_name: The place where to save the last opened directory.
:rtype: None
""" """
folder = QtWidgets.QFileDialog.getExistingDirectory( folder_path = FileDialog.getExistingDirectory(
self, title, Settings().value(self.plugin.settings_section + '/' + setting_name), self, title, Settings().value(self.plugin.settings_section + '/' + setting_name),
QtWidgets.QFileDialog.ShowDirsOnly) QtWidgets.QFileDialog.ShowDirsOnly)
if folder: if folder_path:
editbox.setText(folder) editbox.setText(str(folder_path))
Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder) Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder_path)

View File

@ -37,6 +37,7 @@ from PyQt5 import QtCore, QtWidgets, QtWebKit, QtWebKitWidgets, QtGui, QtMultime
from openlp.core.common import AppLocation, Registry, RegistryProperties, OpenLPMixin, Settings, translate,\ from openlp.core.common import AppLocation, Registry, RegistryProperties, OpenLPMixin, Settings, translate,\
is_macosx, is_win is_macosx, is_win
from openlp.core.common.path import path_to_str
from openlp.core.lib import ServiceItem, ImageSource, ScreenList, build_html, expand_tags, image_to_byte from openlp.core.lib import ServiceItem, ImageSource, ScreenList, build_html, expand_tags, image_to_byte
from openlp.core.lib.theme import BackgroundType from openlp.core.lib.theme import BackgroundType
from openlp.core.ui import HideMode, AlertLocation, DisplayControllerType from openlp.core.ui import HideMode, AlertLocation, DisplayControllerType
@ -259,7 +260,7 @@ class MainDisplay(OpenLPMixin, Display, RegistryProperties):
background_color.setNamedColor(Settings().value('core/logo background color')) background_color.setNamedColor(Settings().value('core/logo background color'))
if not background_color.isValid(): if not background_color.isValid():
background_color = QtCore.Qt.white background_color = QtCore.Qt.white
image_file = Settings().value('core/logo file') image_file = path_to_str(Settings().value('core/logo file'))
splash_image = QtGui.QImage(image_file) splash_image = QtGui.QImage(image_file)
self.initial_fame = QtGui.QImage( self.initial_fame = QtGui.QImage(
self.screen['size'].width(), self.screen['size'].width(),

View File

@ -39,7 +39,7 @@ from openlp.core.api.http import server
from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \ from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, translate, is_win, is_macosx, add_actions check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.common.versionchecker import get_application_version from openlp.core.common.versionchecker import get_application_version
from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon
from openlp.core.lib.ui import create_action from openlp.core.lib.ui import create_action
@ -879,8 +879,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
# Convert image files # Convert image files
log.info('hook upgrade_plugin_settings') log.info('hook upgrade_plugin_settings')
self.plugin_manager.hook_upgrade_plugin_settings(import_settings) self.plugin_manager.hook_upgrade_plugin_settings(import_settings)
# Remove/rename old settings to prepare the import. # Upgrade settings to prepare the import.
import_settings.remove_obsolete_settings() import_settings.upgrade_settings()
# Lets do a basic sanity check. If it contains this string we can assume it was created by OpenLP and so we'll # Lets do a basic sanity check. If it contains this string we can assume it was created by OpenLP and so we'll
# load what we can from it, and just silently ignore anything we don't recognise. # load what we can from it, and just silently ignore anything we don't recognise.
if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export': if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export':
@ -1277,7 +1277,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
settings.remove('custom slide') settings.remove('custom slide')
settings.remove('service') settings.remove('service')
settings.beginGroup(self.general_settings_section) settings.beginGroup(self.general_settings_section)
self.recent_files = settings.value('recent files') self.recent_files = [path_to_str(file_path) for file_path in settings.value('recent files')]
settings.endGroup() settings.endGroup()
settings.beginGroup(self.ui_settings_section) settings.beginGroup(self.ui_settings_section)
self.move(settings.value('main window position')) self.move(settings.value('main window position'))
@ -1301,7 +1301,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
log.debug('Saving QSettings') log.debug('Saving QSettings')
settings = Settings() settings = Settings()
settings.beginGroup(self.general_settings_section) settings.beginGroup(self.general_settings_section)
settings.setValue('recent files', self.recent_files) settings.setValue('recent files', [str_to_path(file) for file in self.recent_files])
settings.endGroup() settings.endGroup()
settings.beginGroup(self.ui_settings_section) settings.beginGroup(self.ui_settings_section)
settings.setValue('main window position', self.pos()) settings.setValue('main window position', self.pos())
@ -1443,7 +1443,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
log.info('No data copy requested') log.info('No data copy requested')
# Change the location of data directory in config file. # Change the location of data directory in config file.
settings = QtCore.QSettings() settings = QtCore.QSettings()
settings.setValue('advanced/data path', self.new_data_path) settings.setValue('advanced/data path', Path(self.new_data_path))
# Check if the new data path is our default. # Check if the new data path is our default.
if self.new_data_path == str(AppLocation.get_directory(AppLocation.DataDir)): if self.new_data_path == str(AppLocation.get_directory(AppLocation.DataDir)):
settings.remove('advanced/data path') settings.remove('advanced/data path')

View File

@ -35,12 +35,13 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, ThemeLevel, OpenLPMixin, \ from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, ThemeLevel, OpenLPMixin, \
RegistryMixin, check_directory_exists, UiStrings, translate, split_filename, delete_file RegistryMixin, check_directory_exists, UiStrings, translate, split_filename, delete_file
from openlp.core.common.actions import ActionList, CategoryOrder from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path from openlp.core.common.languagemanager import format_time
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
from openlp.core.ui.lib import OpenLPToolbar from openlp.core.ui.lib import OpenLPToolbar
from openlp.core.common.languagemanager import format_time from openlp.core.ui.lib.filedialog import FileDialog
class ServiceManagerList(QtWidgets.QTreeWidget): class ServiceManagerList(QtWidgets.QTreeWidget):
@ -373,7 +374,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
""" """
self._file_name = str(file_name) self._file_name = str(file_name)
self.main_window.set_service_modified(self.is_modified(), self.short_file_name()) self.main_window.set_service_modified(self.is_modified(), self.short_file_name())
Settings().setValue('servicemanager/last file', file_name) Settings().setValue('servicemanager/last file', Path(file_name))
self._save_lite = self._file_name.endswith('.oszl') self._save_lite = self._file_name.endswith('.oszl')
def file_name(self): def file_name(self):
@ -435,18 +436,17 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
elif result == QtWidgets.QMessageBox.Save: elif result == QtWidgets.QMessageBox.Save:
self.decide_save_method() self.decide_save_method()
if not load_file: if not load_file:
file_name, filter_used = QtWidgets.QFileDialog.getOpenFileName( file_path, filter_used = FileDialog.getOpenFileName(
self.main_window, self.main_window,
translate('OpenLP.ServiceManager', 'Open File'), translate('OpenLP.ServiceManager', 'Open File'),
Settings().value(self.main_window.service_manager_settings_section + '/last directory'), Settings().value(self.main_window.service_manager_settings_section + '/last directory'),
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)')) translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
if not file_name: if not file_path:
return False return False
else: else:
file_name = load_file file_path = str_to_path(load_file)
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
split_filename(file_name)[0]) self.load_file(str(file_path))
self.load_file(file_name)
def save_modified_service(self): def save_modified_service(self):
""" """
@ -477,7 +477,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
self.set_file_name('') self.set_file_name('')
self.service_id += 1 self.service_id += 1
self.set_modified(False) self.set_modified(False)
Settings().setValue('servicemanager/last file', '') Settings().setValue('servicemanager/last file', None)
self.plugin_manager.new_service_created() self.plugin_manager.new_service_created()
def create_basic_service(self): def create_basic_service(self):
@ -513,7 +513,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
base_name = os.path.splitext(file_name)[0] base_name = os.path.splitext(file_name)[0]
service_file_name = '{name}.osj'.format(name=base_name) service_file_name = '{name}.osj'.format(name=base_name)
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name)) self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path) Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', Path(path))
service = self.create_basic_service() service = self.create_basic_service()
write_list = [] write_list = []
missing_list = [] missing_list = []
@ -634,7 +634,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
base_name = os.path.splitext(file_name)[0] base_name = os.path.splitext(file_name)[0]
service_file_name = '{name}.osj'.format(name=base_name) service_file_name = '{name}.osj'.format(name=base_name)
self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name)) self.log_debug('ServiceManager.save_file - {name}'.format(name=path_file_name))
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path) Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', Path(path))
service = self.create_basic_service() service = self.create_basic_service()
self.application.set_busy_cursor() self.application.set_busy_cursor()
# Number of items + 1 to zip it # Number of items + 1 to zip it
@ -695,7 +695,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
default_file_name = format_time(default_pattern, local_time) default_file_name = format_time(default_pattern, local_time)
else: else:
default_file_name = '' default_file_name = ''
directory = Settings().value(self.main_window.service_manager_settings_section + '/last directory') directory = path_to_str(Settings().value(self.main_window.service_manager_settings_section + '/last directory'))
path = os.path.join(directory, default_file_name) path = os.path.join(directory, default_file_name)
# SaveAs from osz to oszl is not valid as the files will be deleted on exit which is not sensible or usable in # SaveAs from osz to oszl is not valid as the files will be deleted on exit which is not sensible or usable in
# the long term. # the long term.
@ -778,7 +778,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
delete_file(Path(p_file)) delete_file(Path(p_file))
self.main_window.add_recent_file(file_name) self.main_window.add_recent_file(file_name)
self.set_modified(False) self.set_modified(False)
Settings().setValue('servicemanager/last file', file_name) Settings().setValue('servicemanager/last file', Path(file_name))
else: else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
self.log_error('File contains no service data') self.log_error('File contains no service data')
@ -843,7 +843,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
Load the last service item from the service manager when the service was last closed. Can be blank if there was Load the last service item from the service manager when the service was last closed. Can be blank if there was
no service present. no service present.
""" """
file_name = Settings().value('servicemanager/last file') file_name = str_to_path(Settings().value('servicemanager/last file'))
if file_name: if file_name:
self.load_file(file_name) self.load_file(file_name)

View File

@ -378,16 +378,16 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.')) critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.'))
return return
theme = item.data(QtCore.Qt.UserRole) theme = item.data(QtCore.Qt.UserRole)
path, filter_used = \ export_path, filter_used = \
QtWidgets.QFileDialog.getSaveFileName(self.main_window, FileDialog.getSaveFileName(self.main_window,
translate('OpenLP.ThemeManager', 'Save Theme - ({name})'). translate('OpenLP.ThemeManager', 'Save Theme - ({name})').
format(name=theme), format(name=theme),
Settings().value(self.settings_section + '/last directory export'), 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() self.application.set_busy_cursor()
if path: if export_path:
Settings().setValue(self.settings_section + '/last directory export', path) Settings().setValue(self.settings_section + '/last directory export', export_path.parent)
if self._export_theme(path, theme): if self._export_theme(str(export_path, theme)):
QtWidgets.QMessageBox.information(self, QtWidgets.QMessageBox.information(self,
translate('OpenLP.ThemeManager', 'Theme Exported'), translate('OpenLP.ThemeManager', 'Theme Exported'),
translate('OpenLP.ThemeManager', translate('OpenLP.ThemeManager',
@ -428,16 +428,15 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
file_paths, selected_filter = FileDialog.getOpenFileNames( file_paths, selected_filter = FileDialog.getOpenFileNames(
self, self,
translate('OpenLP.ThemeManager', 'Select Theme Import File'), translate('OpenLP.ThemeManager', 'Select Theme Import File'),
str_to_path(Settings().value(self.settings_section + '/last directory import')), Settings().value(self.settings_section + '/last directory import'),
translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)')) translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
self.log_info('New Themes {file_paths}'.format(file_paths=file_paths)) self.log_info('New Themes {file_paths}'.format(file_paths=file_paths))
if not file_paths: if not file_paths:
return return
self.application.set_busy_cursor() self.application.set_busy_cursor()
for file_path in file_paths: for file_path in file_paths:
file_name = path_to_str(file_path) self.unzip_theme(path_to_str(file_path), self.path)
Settings().setValue(self.settings_section + '/last directory import', str(file_name)) Settings().setValue(self.settings_section + '/last directory import', file_path)
self.unzip_theme(file_name, self.path)
self.load_themes() self.load_themes()
self.application.set_normal_cursor() self.application.set_normal_cursor()

View File

@ -59,7 +59,7 @@ __default_settings__ = {
'bibles/range separator': '', 'bibles/range separator': '',
'bibles/list separator': '', 'bibles/list separator': '',
'bibles/end separator': '', 'bibles/end separator': '',
'bibles/last directory import': '', 'bibles/last directory import': None,
'bibles/hide combined quick error': False, 'bibles/hide combined quick error': False,
'bibles/is search while typing enabled': True 'bibles/is search while typing enabled': True
} }

View File

@ -390,7 +390,7 @@ class ImageMediaItem(MediaManagerItem):
self.application.set_normal_cursor() self.application.set_normal_cursor()
self.load_list(files, target_group) self.load_list(files, target_group)
last_dir = os.path.split(files[0])[0] last_dir = os.path.split(files[0])[0]
Settings().setValue(self.settings_section + '/last directory', last_dir) Settings().setValue(self.settings_section + '/last directory', Path(last_dir))
def load_list(self, images, target_group=None, initial_load=False): def load_list(self, images, target_group=None, initial_load=False):
""" """

View File

@ -27,7 +27,7 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, UiStrings,\ from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, UiStrings,\
translate translate
from openlp.core.common.path import Path from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \ from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \
build_icon, check_item_selected build_icon, check_item_selected
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box
@ -303,7 +303,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
self.list_view.clear() self.list_view.clear()
self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails') self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails')
check_directory_exists(Path(self.service_path)) check_directory_exists(Path(self.service_path))
self.load_list(Settings().value(self.settings_section + '/media files')) self.load_list([path_to_str(file) for file in Settings().value(self.settings_section + '/media files')])
self.rebuild_players() self.rebuild_players()
def rebuild_players(self): def rebuild_players(self):
@ -401,14 +401,14 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:param media_type: Type to get, defaults to audio. :param media_type: Type to get, defaults to audio.
:return: The media list :return: The media list
""" """
media = Settings().value(self.settings_section + '/media files') media_file_paths = Settings().value(self.settings_section + '/media files')
media.sort(key=lambda filename: get_locale_key(os.path.split(str(filename))[1])) media_file_paths.sort(key=lambda file_path: get_locale_key(file_path.name))
if media_type == MediaType.Audio: if media_type == MediaType.Audio:
extension = self.media_controller.audio_extensions_list extension = self.media_controller.audio_extensions_list
else: else:
extension = self.media_controller.video_extensions_list extension = self.media_controller.video_extensions_list
extension = [x[1:] for x in extension] extension = [x[1:] for x in extension]
media = [x for x in media if os.path.splitext(x)[1] in extension] media = [x for x in media_file_paths if x.suffix in extension]
return media return media
def search(self, string, show_error): def search(self, string, show_error):
@ -419,13 +419,12 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:param show_error: Should the error be shown (True) :param show_error: Should the error be shown (True)
:return: The search result. :return: The search result.
""" """
files = Settings().value(self.settings_section + '/media files')
results = [] results = []
string = string.lower() string = string.lower()
for file in files: for file_path in Settings().value(self.settings_section + '/media files'):
filename = os.path.split(str(file))[1] file_name = file_path.name
if filename.lower().find(string) > -1: if file_name.lower().find(string) > -1:
results.append([file, filename]) results.append([str(file_path), file_name])
return results return results
def on_load_optical(self): def on_load_optical(self):
@ -446,13 +445,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
:param optical: The clip to add. :param optical: The clip to add.
""" """
full_list = self.get_file_list() file_paths = self.get_file_list()
# If the clip already is in the media list it isn't added and an error message is displayed. # If the clip already is in the media list it isn't added and an error message is displayed.
if optical in full_list: if optical in file_paths:
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Mediaclip already saved'), critical_error_message_box(translate('MediaPlugin.MediaItem', 'Mediaclip already saved'),
translate('MediaPlugin.MediaItem', 'This mediaclip has already been saved')) translate('MediaPlugin.MediaItem', 'This mediaclip has already been saved'))
return return
# Append the optical string to the media list # Append the optical string to the media list
full_list.append(optical) file_paths.append(optical)
self.load_list([optical]) self.load_list([optical])
Settings().setValue(self.settings_section + '/media files', self.get_file_list()) Settings().setValue(self.settings_section + '/media files', file_paths)

View File

@ -26,10 +26,11 @@ import os
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, Settings, UiStrings, translate from openlp.core.common import Registry, Settings, UiStrings, translate
from openlp.core.common.languagemanager import get_locale_key
from openlp.core.common.path import path_to_str
from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext,\ from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemContext,\
build_icon, check_item_selected, create_thumb, validate_thumb build_icon, check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
@ -126,8 +127,8 @@ class PresentationMediaItem(MediaManagerItem):
Populate the media manager tab Populate the media manager tab
""" """
self.list_view.setIconSize(QtCore.QSize(88, 50)) self.list_view.setIconSize(QtCore.QSize(88, 50))
files = Settings().value(self.settings_section + '/presentations files') file_paths = Settings().value(self.settings_section + '/presentations files')
self.load_list(files, initial_load=True) self.load_list([path_to_str(file) for file in file_paths], initial_load=True)
self.populate_display_types() self.populate_display_types()
def populate_display_types(self): def populate_display_types(self):
@ -157,7 +158,7 @@ class PresentationMediaItem(MediaManagerItem):
existing files, and when the user adds new files via the media manager. existing files, and when the user adds new files via the media manager.
""" """
current_list = self.get_file_list() current_list = self.get_file_list()
titles = [os.path.split(file)[1] for file in current_list] titles = [file_path.name for file_path in current_list]
self.application.set_busy_cursor() self.application.set_busy_cursor()
if not initial_load: if not initial_load:
self.main_window.display_progress_bar(len(files)) self.main_window.display_progress_bar(len(files))
@ -410,11 +411,11 @@ class PresentationMediaItem(MediaManagerItem):
:param show_error: not used :param show_error: not used
:return: :return:
""" """
files = Settings().value(self.settings_section + '/presentations files') file_paths = Settings().value(self.settings_section + '/presentations files')
results = [] results = []
string = string.lower() string = string.lower()
for file in files: for file_path in file_paths:
filename = os.path.split(str(file))[1] file_name = file_path.name
if filename.lower().find(string) > -1: if file_name.lower().find(string) > -1:
results.append([file, filename]) results.append([path_to_str(file_path), file_name])
return results return results

View File

@ -28,7 +28,7 @@ from subprocess import check_output, CalledProcessError
from openlp.core.common import AppLocation, check_binary_exists from openlp.core.common import AppLocation, check_binary_exists
from openlp.core.common import Settings, is_win from openlp.core.common import Settings, is_win
from openlp.core.common.path import Path from openlp.core.common.path import Path, path_to_str
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
@ -113,7 +113,7 @@ class PdfController(PresentationController):
self.also_supports = [] self.also_supports = []
# Use the user defined program if given # Use the user defined program if given
if Settings().value('presentations/enable_pdf_program'): if Settings().value('presentations/enable_pdf_program'):
pdf_program = Settings().value('presentations/pdf_program') pdf_program = path_to_str(Settings().value('presentations/pdf_program'))
program_type = self.process_check_binary(pdf_program) program_type = self.process_check_binary(pdf_program)
if program_type == 'gs': if program_type == 'gs':
self.gsbin = pdf_program self.gsbin = pdf_program

View File

@ -155,9 +155,7 @@ class PresentationTab(SettingsTab):
enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program') enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program')
self.pdf_program_check_box.setChecked(enable_pdf_program) self.pdf_program_check_box.setChecked(enable_pdf_program)
self.program_path_edit.setEnabled(enable_pdf_program) self.program_path_edit.setEnabled(enable_pdf_program)
pdf_program = Settings().value(self.settings_section + '/pdf_program') self.program_path_edit.path = Settings().value(self.settings_section + '/pdf_program')
if pdf_program:
self.program_path_edit.path = str_to_path(pdf_program)
def save(self): def save(self):
""" """
@ -193,13 +191,13 @@ class PresentationTab(SettingsTab):
Settings().setValue(setting_key, self.ppt_window_check_box.checkState()) Settings().setValue(setting_key, self.ppt_window_check_box.checkState())
changed = True changed = True
# Save pdf-settings # Save pdf-settings
pdf_program = path_to_str(self.program_path_edit.path) pdf_program_path = self.program_path_edit.path
enable_pdf_program = self.pdf_program_check_box.checkState() enable_pdf_program = self.pdf_program_check_box.checkState()
# If the given program is blank disable using the program # If the given program is blank disable using the program
if pdf_program == '': if not pdf_program_path:
enable_pdf_program = 0 enable_pdf_program = 0
if pdf_program != Settings().value(self.settings_section + '/pdf_program'): if pdf_program_path != Settings().value(self.settings_section + '/pdf_program'):
Settings().setValue(self.settings_section + '/pdf_program', pdf_program) Settings().setValue(self.settings_section + '/pdf_program', pdf_program_path)
changed = True changed = True
if enable_pdf_program != Settings().value(self.settings_section + '/enable_pdf_program'): if enable_pdf_program != Settings().value(self.settings_section + '/enable_pdf_program'):
Settings().setValue(self.settings_section + '/enable_pdf_program', enable_pdf_program) Settings().setValue(self.settings_section + '/enable_pdf_program', enable_pdf_program)

View File

@ -39,7 +39,7 @@ log = logging.getLogger(__name__)
__default_settings__ = {'presentations/override app': QtCore.Qt.Unchecked, __default_settings__ = {'presentations/override app': QtCore.Qt.Unchecked,
'presentations/enable_pdf_program': QtCore.Qt.Unchecked, 'presentations/enable_pdf_program': QtCore.Qt.Unchecked,
'presentations/pdf_program': '', 'presentations/pdf_program': None,
'presentations/Impress': QtCore.Qt.Checked, 'presentations/Impress': QtCore.Qt.Checked,
'presentations/Powerpoint': QtCore.Qt.Checked, 'presentations/Powerpoint': QtCore.Qt.Checked,
'presentations/Powerpoint Viewer': QtCore.Qt.Checked, 'presentations/Powerpoint Viewer': QtCore.Qt.Checked,

View File

@ -239,13 +239,11 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
filters += ';;' filters += ';;'
filters += '{text} (*)'.format(text=UiStrings().AllFiles) filters += '{text} (*)'.format(text=UiStrings().AllFiles)
file_paths, selected_filter = FileDialog.getOpenFileNames( file_paths, selected_filter = FileDialog.getOpenFileNames(
self, title, self, title, Settings().value(self.plugin.settings_section + '/last directory import'), filters)
str_to_path(Settings().value(self.plugin.settings_section + '/last directory import')), filters)
if file_paths: if file_paths:
file_names = [path_to_str(file_path) for file_path in file_paths] file_names = [path_to_str(file_path) for file_path in file_paths]
listbox.addItems(file_names) listbox.addItems(file_names)
Settings().setValue(self.plugin.settings_section + '/last directory import', Settings().setValue(self.plugin.settings_section + '/last directory import', file_paths[0].parent)
os.path.split(str(file_names[0]))[0])
def get_list_of_files(self, list_box): def get_list_of_files(self, list_box):
""" """
@ -363,14 +361,15 @@ class SongImportForm(OpenLPWizard, RegistryProperties):
def on_error_save_to_button_clicked(self): def on_error_save_to_button_clicked(self):
""" """
Save the error report to a file. Save the error report to a file.
:rtype: None
""" """
filename, filter_used = QtWidgets.QFileDialog.getSaveFileName( file_path, filter_used = FileDialog.getSaveFileName(
self, Settings().value(self.plugin.settings_section + '/last directory import')) self, Settings().value(self.plugin.settings_section + '/last directory import'))
if not filename: if not file_path:
return return
report_file = codecs.open(filename, 'w', 'utf-8') with file_path.open('w', encoding='utf-8') as report_file:
report_file.write(self.error_report_text_edit.toPlainText()) report_file.write(self.error_report_text_edit.toPlainText())
report_file.close()
def add_file_select_item(self): def add_file_select_item(self):
""" """

View File

@ -66,8 +66,8 @@ __default_settings__ = {
'songs/display songbook': False, 'songs/display songbook': False,
'songs/display written by': True, 'songs/display written by': True,
'songs/display copyright symbol': False, 'songs/display copyright symbol': False,
'songs/last directory import': '', 'songs/last directory import': None,
'songs/last directory export': '', 'songs/last directory export': None,
'songs/songselect username': '', 'songs/songselect username': '',
'songs/songselect password': '', 'songs/songselect password': '',
'songs/songselect searches': '', 'songs/songselect searches': '',

View File

@ -56,14 +56,16 @@ class SongUsageDetailForm(QtWidgets.QDialog, Ui_SongUsageDetailDialog, RegistryP
""" """
self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date')) self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/from date'))
self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date')) self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settings_section + '/to date'))
self.report_path_edit.path = str_to_path( self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export')
Settings().value(self.plugin.settings_section + '/last directory export'))
def on_report_path_edit_path_changed(self, file_path): def on_report_path_edit_path_changed(self, file_path):
""" """
Triggered when the Directory selection button is clicked Called when the path in the `PathEdit` has changed
:param openlp.core.common.path.Path file_path: The new path.
:rtype: None
""" """
Settings().setValue(self.plugin.settings_section + '/last directory export', path_to_str(file_path)) Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)
def accept(self): def accept(self):
""" """

View File

@ -50,7 +50,7 @@ __default_settings__ = {
'songusage/active': False, 'songusage/active': False,
'songusage/to date': QtCore.QDate(YEAR, 8, 31), 'songusage/to date': QtCore.QDate(YEAR, 8, 31),
'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1), 'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1),
'songusage/last directory export': '' 'songusage/last directory export': None
} }

View File

@ -42,12 +42,14 @@ class TestAppLocation(TestCase):
""" """
with patch('openlp.core.common.applocation.Settings') as mocked_class, \ with patch('openlp.core.common.applocation.Settings') as mocked_class, \
patch('openlp.core.common.AppLocation.get_directory') as mocked_get_directory, \ patch('openlp.core.common.AppLocation.get_directory') as mocked_get_directory, \
patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists: patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists, \
patch('openlp.core.common.applocation.os') as mocked_os:
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory() # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
mocked_settings = mocked_class.return_value mocked_settings = mocked_class.return_value
mocked_settings.contains.return_value = False mocked_settings.contains.return_value = False
mocked_get_directory.return_value = Path('test', 'dir') mocked_get_directory.return_value = os.path.join('test', 'dir')
mocked_check_directory_exists.return_value = True mocked_check_directory_exists.return_value = True
mocked_os.path.normpath.return_value = os.path.join('test', 'dir')
# WHEN: we call AppLocation.get_data_path() # WHEN: we call AppLocation.get_data_path()
data_path = AppLocation.get_data_path() data_path = AppLocation.get_data_path()
@ -55,8 +57,8 @@ class TestAppLocation(TestCase):
# THEN: check that all the correct methods were called, and the result is correct # THEN: check that all the correct methods were called, and the result is correct
mocked_settings.contains.assert_called_with('advanced/data path') mocked_settings.contains.assert_called_with('advanced/data path')
mocked_get_directory.assert_called_with(AppLocation.DataDir) mocked_get_directory.assert_called_with(AppLocation.DataDir)
mocked_check_directory_exists.assert_called_with(Path('test', 'dir')) mocked_check_directory_exists.assert_called_with(os.path.join('test', 'dir'))
self.assertEqual(Path('test', 'dir'), data_path, 'Result should be "test/dir"') self.assertEqual(os.path.join('test', 'dir'), data_path, 'Result should be "test/dir"')
def test_get_data_path_with_custom_location(self): def test_get_data_path_with_custom_location(self):
""" """

View File

@ -26,7 +26,6 @@ from unittest import TestCase
from unittest.mock import patch from unittest.mock import patch
from openlp.core.common import Settings from openlp.core.common import Settings
from openlp.core.common.settings import recent_files_conv
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -48,25 +47,6 @@ class TestSettings(TestCase, TestMixin):
""" """
self.destroy_settings() self.destroy_settings()
def test_recent_files_conv(self):
"""
Test that recent_files_conv, converts various possible types of values correctly.
"""
# GIVEN: A list of possible value types and the expected results
possible_values = [(['multiple', 'values'], ['multiple', 'values']),
(['single value'], ['single value']),
('string value', ['string value']),
(b'bytes value', ['bytes value']),
([], []),
(None, [])]
# WHEN: Calling recent_files_conv with the possible values
for value, expected_result in possible_values:
actual_result = recent_files_conv(value)
# THEN: The actual result should be the same as the expected result
self.assertEqual(actual_result, expected_result)
def test_settings_basic(self): def test_settings_basic(self):
""" """
Test the Settings creation and its default usage Test the Settings creation and its default usage

View File

@ -29,6 +29,7 @@ from unittest import TestCase
from unittest.mock import mock_open, patch from unittest.mock import mock_open, patch
from openlp.core.common import Registry from openlp.core.common import Registry
from openlp.core.common.path import Path
from openlp.core.ui import exceptionform from openlp.core.ui import exceptionform
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -154,7 +155,7 @@ class TestExceptionForm(TestMixin, TestCase):
# THEN: Verify strings were formatted properly # THEN: Verify strings were formatted properly
mocked_add_query_item.assert_called_with('body', MAIL_ITEM_TEXT) mocked_add_query_item.assert_called_with('body', MAIL_ITEM_TEXT)
@patch("openlp.core.ui.exceptionform.QtWidgets.QFileDialog.getSaveFileName") @patch("openlp.core.ui.exceptionform.FileDialog.getSaveFileName")
@patch("openlp.core.ui.exceptionform.Qt") @patch("openlp.core.ui.exceptionform.Qt")
def test_on_save_report_button_clicked(self, def test_on_save_report_button_clicked(self,
mocked_qt, mocked_qt,
@ -181,7 +182,7 @@ class TestExceptionForm(TestMixin, TestCase):
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test' mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False mocked_is_linux.return_value = False
mocked_application_version.return_value = 'Trunk Test' mocked_application_version.return_value = 'Trunk Test'
mocked_save_filename.return_value = ['testfile.txt', ] mocked_save_filename.return_value = (Path('testfile.txt'), 'filter')
test_form = exceptionform.ExceptionForm() test_form = exceptionform.ExceptionForm()
test_form.file_attachment = None test_form.file_attachment = None

View File

@ -28,6 +28,7 @@ from unittest.mock import ANY, MagicMock, patch
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry from openlp.core.common import Registry
from openlp.core.common.path import Path
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
from openlp.plugins.images.lib.mediaitem import ImageMediaItem from openlp.plugins.images.lib.mediaitem import ImageMediaItem
@ -65,7 +66,7 @@ class TestImageMediaItem(TestCase):
# THEN: load_list should have been called with the file list and None, # THEN: load_list should have been called with the file list and None,
# the directory should have been saved to the settings # the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, None) mocked_load_list.assert_called_once_with(file_list, None)
mocked_settings().setValue.assert_called_once_with(ANY, '/path1') mocked_settings().setValue.assert_called_once_with(ANY, Path('/', 'path1'))
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list') @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list')
@patch('openlp.plugins.images.lib.mediaitem.Settings') @patch('openlp.plugins.images.lib.mediaitem.Settings')
@ -82,7 +83,7 @@ class TestImageMediaItem(TestCase):
# THEN: load_list should have been called with the file list and the group name, # THEN: load_list should have been called with the file list and the group name,
# the directory should have been saved to the settings # the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, 'group') mocked_load_list.assert_called_once_with(file_list, 'group')
mocked_settings().setValue.assert_called_once_with(ANY, '/path1') mocked_settings().setValue.assert_called_once_with(ANY, Path('/', 'path1'))
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_empty_list(self, mocked_load_full_list): def test_save_new_images_list_empty_list(self, mocked_load_full_list):

View File

@ -28,6 +28,7 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore from PyQt5 import QtCore
from openlp.core import Settings from openlp.core import Settings
from openlp.core.common.path import Path
from openlp.plugins.media.lib.mediaitem import MediaMediaItem from openlp.plugins.media.lib.mediaitem import MediaMediaItem
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -66,7 +67,7 @@ class MediaItemTest(TestCase, TestMixin):
Media Remote Search Successful find Media Remote Search Successful find
""" """
# GIVEN: The Mediaitem set up a list of media # GIVEN: The Mediaitem set up a list of media
Settings().setValue(self.media_item.settings_section + '/media files', ['test.mp3', 'test.mp4']) Settings().setValue(self.media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file # WHEN: Retrieving the test file
result = self.media_item.search('test.mp4', False) result = self.media_item.search('test.mp4', False)
# THEN: a file should be found # THEN: a file should be found
@ -77,7 +78,7 @@ class MediaItemTest(TestCase, TestMixin):
Media Remote Search not find Media Remote Search not find
""" """
# GIVEN: The Mediaitem set up a list of media # GIVEN: The Mediaitem set up a list of media
Settings().setValue(self.media_item.settings_section + '/media files', ['test.mp3', 'test.mp4']) Settings().setValue(self.media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file # WHEN: Retrieving the test file
result = self.media_item.search('test.mpx', False) result = self.media_item.search('test.mpx', False)
# THEN: a file should be found # THEN: a file should be found

View File

@ -32,6 +32,7 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
from openlp.core.common import Registry, Settings from openlp.core.common import Registry, Settings
from openlp.core.common.path import Path
from openlp.core.lib.pluginmanager import PluginManager from openlp.core.lib.pluginmanager import PluginManager
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -48,7 +49,7 @@ class TestPluginManager(TestCase, TestMixin):
""" """
self.setup_application() self.setup_application()
self.build_settings() self.build_settings()
self.temp_dir = mkdtemp('openlp') self.temp_dir = Path(mkdtemp('openlp'))
Settings().setValue('advanced/data path', self.temp_dir) Settings().setValue('advanced/data path', self.temp_dir)
Registry.create() Registry.create()
Registry().register('service_list', MagicMock()) Registry().register('service_list', MagicMock())
@ -62,7 +63,7 @@ class TestPluginManager(TestCase, TestMixin):
# On windows we need to manually garbage collect to close sqlalchemy files # On windows we need to manually garbage collect to close sqlalchemy files
# to avoid errors when temporary files are deleted. # to avoid errors when temporary files are deleted.
gc.collect() gc.collect()
shutil.rmtree(self.temp_dir) shutil.rmtree(str(self.temp_dir))
@patch('openlp.plugins.songusage.lib.db.init_schema') @patch('openlp.plugins.songusage.lib.db.init_schema')
@patch('openlp.plugins.songs.lib.db.init_schema') @patch('openlp.plugins.songs.lib.db.init_schema')