openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #32019
[Merge] lp:~phill-ridout/openlp/pathlib4 into lp:openlp
Phill has proposed merging lp:~phill-ridout/openlp/pathlib4 into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
For more details, see:
https://code.launchpad.net/~phill-ridout/openlp/pathlib4/+merge/329671
I'm just proposing this merge to get a clear diff
--
Your team OpenLP Core is requested to review the proposed merge of lp:~phill-ridout/openlp/pathlib4 into lp:openlp.
=== modified file 'openlp/core/__init__.py'
--- openlp/core/__init__.py 2017-08-23 20:13:58 +0000
+++ openlp/core/__init__.py 2017-08-26 15:41:28 +0000
@@ -33,13 +33,13 @@
import shutil
import sys
import time
-from pathlib import Path
from traceback import format_exception
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, is_macosx, is_win, translate
+from openlp.core.common.path import Path
from openlp.core.common.versionchecker import VersionThread, get_application_version
from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources
@@ -347,8 +347,7 @@
"""
Setup our logging using log_path
- :param pathlib.Path log_path: The file to save the log to
- :return: None
+ :param openlp.core.common.path.Path log_path: The file to save the log to.
:rtype: None
"""
check_directory_exists(log_path, True)
@@ -406,7 +405,7 @@
# Set our data path
log.info('Data path: {name}'.format(name=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.sync()
else:
@@ -423,8 +422,8 @@
if application.is_data_path_missing():
application.shared_memory.detach()
sys.exit()
- # Remove/convert obsolete settings.
- Settings().remove_obsolete_settings()
+ # Upgrade settings.
+ Settings().upgrade_settings()
# First time checks in settings
if not Settings().value('core/has run wizard'):
if not FirstTimeLanguageForm().exec():
=== modified file 'openlp/core/api/endpoint/controller.py'
--- openlp/core/api/endpoint/controller.py 2017-08-24 19:53:55 +0000
+++ openlp/core/api/endpoint/controller.py 2017-08-26 15:41:28 +0000
@@ -79,8 +79,7 @@
item['title'] = str(frame['display_title'])
if current_item.is_capable(ItemCapabilities.HasNotes):
item['slide_notes'] = str(frame['notes'])
- if current_item.is_capable(ItemCapabilities.HasThumbnails) and \
- Settings().value('api/thumbnails'):
+ if current_item.is_capable(ItemCapabilities.HasThumbnails) and Settings().value('api/thumbnails'):
# If the file is under our app directory tree send the portion after the match
data_path = str(AppLocation.get_data_path())
if frame['image'][0:len(data_path)] == data_path:
=== modified file 'openlp/core/common/__init__.py'
--- openlp/core/common/__init__.py 2017-08-12 17:45:56 +0000
+++ openlp/core/common/__init__.py 2017-08-26 15:41:28 +0000
@@ -66,9 +66,8 @@
"""
Check a directory exists and if not create it
- :param pathlib.Path directory: The directory to make sure exists
+ :param openlp.core.common.path.Path directory: The directory to make sure exists
:param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready.
- :return: None
:rtype: None
"""
if not do_not_log:
@@ -89,7 +88,6 @@
:param str glob_pattern: A glob pattern used to find the extension(s) to be imported. Should be relative to the
application directory. i.e. plugins/*/*plugin.py
:param list[str] excluded_files: A list of file names to exclude that the glob pattern may find.
- :return: None
:rtype: None
"""
app_dir = AppLocation.get_directory(AppLocation.AppDir)
@@ -110,7 +108,7 @@
"""
Convert a path to a module name (i.e openlp.core.common)
- :param pathlib.Path path: The path to convert to a module name.
+ :param openlp.core.common.path.Path path: The path to convert to a module name.
:return: The module name.
:rtype: str
"""
@@ -377,7 +375,7 @@
"""
Deletes a file from the system.
- :param pathlib.Path file_path: The file, including path, to delete.
+ :param openlp.core.common.path.Path file_path: The file, including path, to delete.
:return: True if the deletion was successful, or the file never existed. False otherwise.
:rtype: bool
"""
@@ -412,7 +410,7 @@
"""
Validate that the file is not an image file.
- :param pathlib.Path file_path: The file to be checked.
+ :param openlp.core.common.path.Path file_path: The file to be checked.
:return: If the file is not an image
:rtype: bool
"""
@@ -440,7 +438,7 @@
"""
Function that checks whether a binary exists.
- :param pathlib.Path program_path: The full path to the binary to check.
+ :param openlp.core.common.path.Path program_path: The full path to the binary to check.
:return: program output to be parsed
:rtype: bytes
"""
@@ -466,7 +464,7 @@
"""
Utility function to incrementally detect the file encoding.
- :param pathlib.Path file_path: Filename for the file to determine the encoding for.
+ :param openlp.core.common.path.Path file_path: Filename for the file to determine the encoding for.
:return: A dict with the keys 'encoding' and 'confidence'
:rtype: dict[str, float]
"""
=== modified file 'openlp/core/common/applocation.py'
--- openlp/core/common/applocation.py 2017-08-18 19:34:20 +0000
+++ openlp/core/common/applocation.py 2017-08-26 15:41:28 +0000
@@ -25,9 +25,9 @@
import logging
import os
import sys
-from pathlib import Path
from openlp.core.common import Settings, is_win, is_macosx
+from openlp.core.common.path import Path
if not is_win() and not is_macosx():
@@ -64,10 +64,8 @@
Return the appropriate directory according to the directory type.
:param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*
- :type dir_type: AppLocation Enum
-
:return: The requested path
- :rtype: pathlib.Path
+ :rtype: openlp.core.common.path.Path
"""
if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:
return get_frozen_path(FROZEN_APP_PATH, APP_PATH)
@@ -84,11 +82,11 @@
Return the path OpenLP stores all its data under.
:return: The data path to use.
- :rtype: pathlib.Path
+ :rtype: openlp.core.common.path.Path
"""
# Check if we have a different data location.
if Settings().contains('advanced/data path'):
- path = Path(Settings().value('advanced/data path'))
+ path = Settings().value('advanced/data path')
else:
path = AppLocation.get_directory(AppLocation.DataDir)
check_directory_exists(path)
@@ -104,7 +102,7 @@
:param str extension: Defaults to ''. The extension to search for. For example::
'.png'
:return: List of files found.
- :rtype: list[pathlib.Path]
+ :rtype: list[openlp.core.common.path.Path]
"""
path = AppLocation.get_data_path()
if section:
@@ -120,9 +118,8 @@
"""
Return the path a particular module stores its data under.
- :type section: str
-
- :rtype: pathlib.Path
+ :param str section:
+ :rtype: openlp.core.common.path.Path
"""
path = AppLocation.get_data_path() / section
check_directory_exists(path)
@@ -135,7 +132,7 @@
:param dir_type: AppLocation Enum of the requested path type
:return: The requested path
- :rtype: pathlib.Path
+ :rtype: openlp.core.common.path.Path
"""
# If running from source, return the language directory from the source directory
if dir_type == AppLocation.LanguageDir:
=== added file 'openlp/core/common/json.py'
--- openlp/core/common/json.py 1970-01-01 00:00:00 +0000
+++ openlp/core/common/json.py 2017-08-26 15:41:28 +0000
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2017 OpenLP Developers #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+from json import JSONDecoder, JSONEncoder
+
+from openlp.core.common.path import Path
+
+
+class OpenLPJsonDecoder(JSONDecoder):
+ """
+ Implement a custom JSONDecoder to handle Path objects
+
+ Example Usage:
+ object = json.loads(json_string, cls=OpenLPJsonDecoder)
+ """
+ def __init__(self, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True,
+ object_pairs_hook=None, **kwargs):
+ """
+ Re-implement __init__ so that we can pass in our object_hook method. Any additional kwargs, are stored in the
+ instance and are passed to custom objects upon encoding or decoding.
+ """
+ self.kwargs = kwargs
+ if not object_hook:
+ object_hook = self.object_hook
+ super().__init__(object_hook, parse_float, parse_int, parse_constant, strict, object_pairs_hook)
+
+ def object_hook(self, obj):
+ """
+ Implement a custom Path object decoder.
+
+ :param dict obj: A decoded JSON object
+ :return: The original object literal, or a Path object if the object literal contains a key '__Path__'
+ :rtype: dict | openlp.core.common.path.Path
+ """
+ if '__Path__' in obj:
+ obj = Path.encode_json(obj, **self.kwargs)
+ return obj
+
+
+class OpenLPJsonEncoder(JSONEncoder):
+ """
+ Implement a custom JSONEncoder to handle Path objects
+
+ Example Usage:
+ json_string = json.dumps(object, cls=OpenLPJsonEncoder)
+ """
+ def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
+ indent=None, separators=None, default=None, **kwargs):
+ """
+ Re-implement __init__ so that we can pass in additional kwargs, which are stored in the instance and are passed
+ to custom objects upon encoding or decoding.
+ """
+ self.kwargs = kwargs
+ super().__init__(skipkeys, ensure_ascii, check_circular, allow_nan, sort_keys, indent, separators, default)
+
+ def default(self, obj):
+ """
+ Convert any Path objects into a dictionary object which can be serialized.
+
+ :param object obj: The object to convert
+ :return: The serializable object
+ :rtype: dict
+ """
+ if isinstance(obj, Path):
+ return obj.json_object(**self.kwargs)
+ return super().default(obj)
=== modified file 'openlp/core/common/path.py'
--- openlp/core/common/path.py 2017-08-04 17:40:57 +0000
+++ openlp/core/common/path.py 2017-08-26 15:41:28 +0000
@@ -19,17 +19,23 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
-
-from pathlib import Path
-
-
-def path_to_str(path):
+import pathlib
+from contextlib import suppress
+
+from openlp.core.common import is_win
+
+
+if is_win():
+ path_variant = pathlib.WindowsPath
+else:
+ path_variant = pathlib.PosixPath
+
+
+def path_to_str(path=None):
"""
A utility function to convert a Path object or NoneType to a string equivalent.
- :param path: The value to convert to a string
- :type: pathlib.Path or None
-
+ :param openlp.core.common.path.Path | None path: The value to convert to a string
:return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
:rtype: str
"""
@@ -48,14 +54,49 @@
This function is of particular use because initating a Path object with an empty string causes the Path object to
point to the current working directory.
- :param string: The string to convert
- :type string: str
-
+ :param str string: The string to convert
:return: None if :param:`string` is empty, or a Path object representation of :param:`string`
- :rtype: pathlib.Path or None
+ :rtype: openlp.core.common.path.Path | None
"""
if not isinstance(string, str):
raise TypeError('parameter \'string\' must be of type str')
if string == '':
return None
return Path(string)
+
+
+class Path(path_variant):
+ """
+ Subclass pathlib.Path, so we can add json conversion methods
+ """
+ @staticmethod
+ def encode_json(obj, base_path=None, **kwargs):
+ """
+ Create a Path object from a dictionary representation. The dictionary has been constructed by JSON encoding of
+ a JSON reprensation of a Path object.
+
+ :param dict[str] obj: The dictionary representation
+ :param openlp.core.common.path.Path base_path: If specified, an absolute path to base the relative path off of.
+ :param kwargs: Contains any extra parameters. Not used!
+ :return: The reconstructed Path object
+ :rtype: openlp.core.common.path.Path
+ """
+ path = Path(*obj['__Path__'])
+ if base_path and not path.is_absolute():
+ return base_path / path
+ return path
+
+ def json_object(self, base_path=None, **kwargs):
+ """
+ Create a dictionary that can be JSON decoded.
+
+ :param openlp.core.common.path.Path base_path: If specified, an absolute path to make a relative path from.
+ :param kwargs: Contains any extra parameters. Not used!
+ :return: The dictionary representation of this Path object.
+ :rtype: dict[tuple]
+ """
+ path = self
+ if base_path:
+ with suppress(ValueError):
+ path = path.relative_to(base_path)
+ return {'__Path__': path.parts}
=== modified file 'openlp/core/common/settings.py'
--- openlp/core/common/settings.py 2017-08-25 04:26:25 +0000
+++ openlp/core/common/settings.py 2017-08-26 15:41:28 +0000
@@ -24,15 +24,18 @@
"""
import datetime
import logging
+import json
import os
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__)
+__version__ = 2
# Fix for bug #1014422.
X11_BYPASS_DEFAULT = True
@@ -44,21 +47,6 @@
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):
"""
If phonon is in the setting string replace it with system
@@ -73,14 +61,24 @@
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 to wrap QSettings.
* Exposes all the methods of QSettings.
- * Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to
- ``IniFormat``, and the path to the Ini file is set using ``set_filename``,
- then the Settings constructor (without any arguments) will create a Settings
+ * Adds functionality for OpenLP Portable. If the ``defaultFormat`` is set to ``IniFormat``, and the path to the Ini
+ file is set using ``set_filename``, then the Settings constructor (without any arguments) will create a Settings
object for accessing settings stored in that Ini file.
``__default_settings__``
@@ -91,7 +89,7 @@
('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 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 @@
So, if the type of the old value is bool, then there must be two rules.
"""
__default_settings__ = {
+ 'settings/version': 0,
'advanced/add page break': False,
'advanced/alternate rows': not is_win(),
'advanced/autoscrolling': {'dist': 1, 'pos': 0},
'advanced/current media plugin': -1,
- 'advanced/data path': '',
+ 'advanced/data path': None,
# 7 stands for now, 0 to 6 is Monday to Sunday.
'advanced/default service day': 7,
'advanced/default service enabled': True,
@@ -143,7 +142,7 @@
'api/authentication enabled': False,
'api/ip address': '0.0.0.0',
'api/thumbnails': True,
- 'crashreport/last directory': '',
+ 'crashreport/last directory': None,
'formattingTags/html_tags': '',
'core/audio repeat list': False,
'core/auto open': False,
@@ -162,7 +161,7 @@
'core/screen blank': False,
'core/show splash': True,
'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/songselect password': '',
'core/songselect username': '',
@@ -177,17 +176,17 @@
'media/players': 'system,webkit',
'media/override player': QtCore.Qt.Unchecked,
'players/background color': '#000000',
- 'servicemanager/last directory': '',
- 'servicemanager/last file': '',
- 'servicemanager/service theme': '',
+ 'servicemanager/last directory': None,
+ 'servicemanager/last file': None,
+ 'servicemanager/service theme': None,
'SettingsImport/file_date_created': datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
'SettingsImport/Make_Changes': 'At_Own_RISK',
'SettingsImport/type': 'OpenLP_settings_export',
'SettingsImport/version': '',
'themes/global theme': '',
- 'themes/last directory': '',
- 'themes/last directory export': '',
- 'themes/last directory import': '',
+ 'themes/last directory': None,
+ 'themes/last directory export': None,
+ 'themes/last directory import': None,
'themes/theme level': ThemeLevel.Song,
'themes/wrap footer': False,
'user interface/live panel': True,
@@ -208,22 +207,20 @@
'projector/db database': '',
'projector/enable': True,
'projector/connect on start': False,
- 'projector/last directory import': '',
- 'projector/last directory export': '',
+ 'projector/last directory import': None,
+ 'projector/last directory export': None,
'projector/poll time': 20, # PJLink timeout is 30 seconds
'projector/socket timeout': 5, # 5 second socket timeout
'projector/source dialog type': 0 # Source select dialog box type
}
__file_path__ = ''
- __obsolete_settings__ = [
+ __setting_upgrade_1__ = [
# 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', []),
('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
('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 port', '', []),
('remotes/twelve hour', 'api/twelve hour', []),
@@ -234,7 +231,6 @@
('remotes/authentication enabled', 'api/authentication enabled', []),
('remotes/ip address', 'api/ip address', []),
('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/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.
@@ -243,7 +239,28 @@
# 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', []),
('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
@@ -256,13 +273,16 @@
Settings.__default_settings__.update(default_values)
@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.
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
def set_up_default_values():
@@ -431,14 +451,22 @@
key = self.group() + '/' + 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
``__obsolete_settings__`` for more details.
"""
- for old_key, new_key, rules in Settings.__obsolete_settings__:
- # Once removed we don't have to do this again.
- if self.contains(old_key):
+ current_version = self.value('settings/version')
+ if __version__ == current_version:
+ 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:
# Get the value of the old_key.
old_value = super(Settings, self).value(old_key)
@@ -457,14 +485,17 @@
old_value = new
break
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):
"""
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.
- :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 self.group():
@@ -474,6 +505,18 @@
setting = super(Settings, self).value(key, 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):
"""
This converts the given ``setting`` to the type of the given ``default_value``.
@@ -491,8 +534,11 @@
if isinstance(default_value, str):
return ''
# An empty list saved to the settings results in a None type being returned.
- else:
+ elif isinstance(default_value, list):
return []
+ elif isinstance(setting, str):
+ if '__Path__' in setting:
+ return json.loads(setting, cls=OpenLPJsonDecoder)
# Convert the setting to the correct type.
if isinstance(default_value, bool):
if isinstance(setting, bool):
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2017-08-25 04:26:25 +0000
+++ openlp/core/lib/__init__.py 2017-08-26 15:41:28 +0000
@@ -89,7 +89,7 @@
returns False. If there is an error loading the file or the content can't be decoded then the function will return
None.
- :param pathlib.Path text_file_path: The path to the file.
+ :param openlp.core.common.path.Path text_file_path: The path to the file.
:return: The contents of the file, False if the file does not exist, or None if there is an Error reading or
decoding the file.
:rtype: str | False | None
@@ -610,17 +610,11 @@
"""
Apply a transformation function to the specified args or kwargs
- :param args: Positional arguments
- :type args: (,)
-
- :param kwargs: Key Word arguments
- :type kwargs: dict
-
+ :param tuple args: Positional arguments
+ :param dict kwargs: Key Word arguments
:param params: A tuple of tuples with the position and the key word to replace.
- :type params: ((int, str, path_to_str),)
-
:return: The modified positional and keyword arguments
- :rtype: (tuple, dict)
+ :rtype: tuple[tuple, dict]
Usage:
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py 2017-08-11 20:47:52 +0000
+++ openlp/core/lib/mediamanageritem.py 2017-08-26 15:41:28 +0000
@@ -29,7 +29,7 @@
from PyQt5 import QtCore, QtWidgets
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.searchedit import SearchEdit
from openlp.core.lib.ui import create_widget_action, critical_error_message_box
@@ -313,7 +313,7 @@
"""
file_paths, selected_filter = FileDialog.getOpenFileNames(
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)
log.info('New files(s) {file_paths}'.format(file_paths=file_paths))
if file_paths:
@@ -377,9 +377,8 @@
self.list_view.clear()
self.load_list(full_list, target_group)
last_dir = os.path.split(files[0])[0]
- Settings().setValue(self.settings_section + '/last directory', last_dir)
- Settings().setValue('{section}/{section} files'.format(section=self.settings_section),
- self.get_file_list())
+ Settings().setValue(self.settings_section + '/last directory', Path(last_dir))
+ Settings().setValue('{section}/{section} files'.format(section=self.settings_section), self.get_file_list())
if duplicates_found:
critical_error_message_box(UiStrings().Duplicate,
translate('OpenLP.MediaManagerItem',
@@ -400,13 +399,15 @@
def get_file_list(self):
"""
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()):
list_item = self.list_view.item(index)
filename = list_item.data(QtCore.Qt.UserRole)
- file_list.append(filename)
- return file_list
+ file_paths.append(str_to_path(filename))
+ return file_paths
def load_list(self, load_list, target_group):
"""
=== removed file 'openlp/core/lib/path.py'
--- openlp/core/lib/path.py 2017-08-02 06:09:38 +0000
+++ openlp/core/lib/path.py 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
-
-###############################################################################
-# OpenLP - Open Source Lyrics Projection #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2017 OpenLP Developers #
-# --------------------------------------------------------------------------- #
-# This program is free software; you can redistribute it and/or modify it #
-# under the terms of the GNU General Public License as published by the Free #
-# Software Foundation; version 2 of the License. #
-# #
-# This program is distributed in the hope that it will be useful, but WITHOUT #
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
-# more details. #
-# #
-# You should have received a copy of the GNU General Public License along #
-# with this program; if not, write to the Free Software Foundation, Inc., 59 #
-# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
-###############################################################################
-
-from pathlib import Path
-
-
-def path_to_str(path):
- """
- A utility function to convert a Path object or NoneType to a string equivalent.
-
- :param path: The value to convert to a string
- :type: pathlib.Path or None
-
- :return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
- :rtype: str
- """
- if not isinstance(path, Path) and path is not None:
- raise TypeError('parameter \'path\' must be of type Path or NoneType')
- if path is None:
- return ''
- else:
- return str(path)
-
-
-def str_to_path(string):
- """
- A utility function to convert a str object to a Path or NoneType.
-
- This function is of particular use because initating a Path object with an empty string causes the Path object to
- point to the current working directory.
-
- :param string: The string to convert
- :type string: str
-
- :return: None if :param:`string` is empty, or a Path object representation of :param:`string`
- :rtype: pathlib.Path or None
- """
- if not isinstance(string, str):
- raise TypeError('parameter \'string\' must be of type str')
- if string == '':
- return None
- return Path(string)
=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py 2016-12-31 11:01:36 +0000
+++ openlp/core/lib/plugin.py 2017-08-26 15:41:28 +0000
@@ -150,7 +150,7 @@
self.status = PluginStatus.Inactive
# Add the default status to the default settings.
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
# which have a mediamanager need this).
if media_item_class is not None:
=== modified file 'openlp/core/ui/exceptionform.py'
--- openlp/core/ui/exceptionform.py 2016-12-31 11:01:36 +0000
+++ openlp/core/ui/exceptionform.py 2017-08-26 15:41:28 +0000
@@ -70,9 +70,9 @@
except ImportError:
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 import RegistryProperties, is_linux
+from openlp.core.ui.lib.filedialog import FileDialog
from .exceptiondialog import Ui_ExceptionDialog
@@ -139,17 +139,17 @@
"""
Saving exception log and system information to a file.
"""
- filename = QtWidgets.QFileDialog.getSaveFileName(
+ file_path, filter_used = FileDialog.getSaveFileName(
self,
translate('OpenLP.ExceptionForm', 'Save Crash Report'),
Settings().value(self.settings_section + '/last directory'),
- translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)'))[0]
- if filename:
- filename = str(filename).replace('/', os.path.sep)
- Settings().setValue(self.settings_section + '/last directory', os.path.dirname(filename))
+ translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)'))
+ if file_path:
+ Settings().setValue(self.settings_section + '/last directory', file_path.parent)
opts = self._create_report()
report_text = self.report_text.format(version=opts['version'], description=opts['description'],
traceback=opts['traceback'], libs=opts['libs'], system=opts['system'])
+ filename = str(file_path)
try:
report_file = open(filename, 'w')
try:
@@ -212,17 +212,16 @@
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,
- translate('ImagePlugin.ExceptionDialog',
- 'Select Attachment'),
- Settings().value(self.settings_section +
- '/last directory'),
- '{text} (*)'.format(text=UiStrings().AllFiles))
- log.info('New files(s) {files}'.format(files=str(files)))
- if files:
- self.file_attachment = str(files)
+ file_path, filter_used = \
+ FileDialog.getOpenFileName(self,
+ translate('ImagePlugin.ExceptionDialog', 'Select Attachment'),
+ Settings().value(self.settings_section + '/last directory'),
+ '{text} (*)'.format(text=UiStrings().AllFiles))
+ log.info('New file {file}'.format(file=file_path))
+ if file_path:
+ self.file_attachment = str(file_path)
def __button_state(self, state):
"""
=== modified file 'openlp/core/ui/firsttimeform.py'
--- openlp/core/ui/firsttimeform.py 2017-08-23 20:13:58 +0000
+++ openlp/core/ui/firsttimeform.py 2017-08-26 15:41:28 +0000
@@ -30,13 +30,13 @@
import urllib.parse
import urllib.error
from configparser import ConfigParser, MissingSectionHeaderError, NoOptionError, NoSectionError
-from pathlib import Path
from tempfile import gettempdir
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, \
translate, clean_button_text, trace_error_handler
+from openlp.core.common.path import Path
from openlp.core.lib import PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.common.httputils import get_web_page, get_url_file_size, url_get_file, CONNECTION_TIMEOUT
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py 2017-08-04 21:53:02 +0000
+++ openlp/core/ui/generaltab.py 2017-08-26 15:41:28 +0000
@@ -23,12 +23,11 @@
The general tab of the configuration dialog.
"""
import logging
-from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter
-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 SettingsTab, ScreenList
from openlp.core.ui.lib import ColorButton, PathEdit
@@ -294,7 +293,7 @@
self.auto_open_check_box.setChecked(settings.value('auto open'))
self.show_splash_check_box.setChecked(settings.value('show splash'))
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_color_button.color = self.logo_background_color
self.check_for_updates_check_box.setChecked(settings.value('update check'))
@@ -328,7 +327,7 @@
settings.setValue('auto open', self.auto_open_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 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('update check', self.check_for_updates_check_box.isChecked())
settings.setValue('save prompt', self.save_check_service_check_box.isChecked())
=== modified file 'openlp/core/ui/lib/filedialog.py'
--- openlp/core/ui/lib/filedialog.py 2017-08-10 06:28:30 +0000
+++ openlp/core/ui/lib/filedialog.py 2017-08-26 15:41:28 +0000
@@ -20,11 +20,9 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
""" Patch the QFileDialog so it accepts and returns Path objects"""
-from pathlib import Path
-
from PyQt5 import QtWidgets
-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 replace_params
@@ -36,7 +34,7 @@
:type parent: QtWidgets.QWidget or None
:type caption: str
- :type directory: pathlib.Path
+ :type directory: openlp.core.common.path.Path
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
@@ -55,7 +53,7 @@
:type parent: QtWidgets.QWidget or None
:type caption: str
- :type directory: pathlib.Path
+ :type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
@@ -76,7 +74,7 @@
:type parent: QtWidgets.QWidget or None
:type caption: str
- :type directory: pathlib.Path
+ :type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
@@ -98,7 +96,7 @@
:type parent: QtWidgets.QWidget or None
:type caption: str
- :type directory: pathlib.Path
+ :type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
=== modified file 'openlp/core/ui/lib/pathedit.py'
--- openlp/core/ui/lib/pathedit.py 2017-08-07 20:50:01 +0000
+++ openlp/core/ui/lib/pathedit.py 2017-08-26 15:41:28 +0000
@@ -20,12 +20,11 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from enum import Enum
-from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import 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 build_icon
from openlp.core.ui.lib.filedialog import FileDialog
@@ -46,19 +45,10 @@
"""
Initialise the PathEdit widget
- :param parent: The parent of the widget. This is just passed to the super method.
- :type parent: QWidget or None
-
- :param dialog_caption: Used to customise the caption in the QFileDialog.
- :type dialog_caption: str
-
- :param default_path: The default path. This is set as the path when the revert button is clicked
- :type default_path: pathlib.Path
-
- :param show_revert: Used to determine if the 'revert button' should be visible.
- :type show_revert: bool
-
- :return: None
+ :param QtWidget.QWidget | None: The parent of the widget. This is just passed to the super method.
+ :param str dialog_caption: Used to customise the caption in the QFileDialog.
+ :param openlp.core.common.path.Path default_path: The default path. This is set as the path when the revert button is clicked
+ :param bool show_revert: Used to determine if the 'revert button' should be visible.
:rtype: None
"""
super().__init__(parent)
@@ -72,10 +62,7 @@
def _setup(self, show_revert):
"""
Set up the widget
- :param show_revert: Show or hide the revert button
- :type show_revert: bool
-
- :return: None
+ :param bool show_revert: Show or hide the revert button
:rtype: None
"""
widget_layout = QtWidgets.QHBoxLayout()
@@ -102,7 +89,7 @@
A property getter method to return the selected path.
:return: The selected path
- :rtype: pathlib.Path
+ :rtype: openlp.core.common.path.Path
"""
return self._path
@@ -111,10 +98,7 @@
"""
A Property setter method to set the selected path
- :param path: The path to set the widget to
- :type path: pathlib.Path
-
- :return: None
+ :param openlp.core.common.path.Path path: The path to set the widget to
:rtype: None
"""
self._path = path
@@ -138,10 +122,7 @@
"""
A Property setter method to set the path type
- :param path_type: The type of path to select
- :type path_type: PathType
-
- :return: None
+ :param PathType path_type: The type of path to select
:rtype: None
"""
self._path_type = path_type
@@ -151,7 +132,6 @@
"""
Called to update the tooltips on the buttons. This is changing path types, and when the widget is initalised
- :return: None
:rtype: None
"""
if self._path_type == PathType.Directories:
@@ -167,7 +147,6 @@
Show the QFileDialog and process the input from the user
- :return: None
:rtype: None
"""
caption = self.dialog_caption
@@ -189,7 +168,6 @@
Set the new path to the value of the default_path instance variable.
- :return: None
:rtype: None
"""
self.on_new_path(self.default_path)
@@ -198,7 +176,6 @@
"""
A handler to handle when the line edit has finished being edited.
- :return: None
:rtype: None
"""
path = str_to_path(self.line_edit.text())
@@ -210,10 +187,7 @@
Emits the pathChanged Signal
- :param path: The new path
- :type path: pathlib.Path
-
- :return: None
+ :param openlp.core.common.path.Path path: The new path
:rtype: None
"""
if self._path != path:
=== modified file 'openlp/core/ui/lib/wizard.py'
--- openlp/core/ui/lib/wizard.py 2017-06-09 06:06:49 +0000
+++ openlp/core/ui/lib/wizard.py 2017-08-26 15:41:28 +0000
@@ -30,6 +30,7 @@
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings, translate, is_macosx
from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page
+from openlp.core.ui.lib.filedialog import FileDialog
log = logging.getLogger(__name__)
@@ -278,37 +279,38 @@
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 editbox: An editbox (QLineEdit).
- :param 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 title: The title of the dialog.
+ :param QtWidgets.QLineEdit editbox: An QLineEdit.
+ :param str setting_name: The place where to save the last opened directory.
+ :param str filters: The file extension filters. It should contain the file description
as well as the file extension. For example::
'OpenLP 2 Databases (*.sqlite)'
+ :rtype: None
"""
if filters:
filters += ';;'
filters += '%s (*)' % UiStrings().AllFiles
- filename, filter_used = QtWidgets.QFileDialog.getOpenFileName(
- self, title, os.path.dirname(Settings().value(self.plugin.settings_section + '/' + setting_name)),
- filters)
- if filename:
- editbox.setText(filename)
- Settings().setValue(self.plugin.settings_section + '/' + setting_name, filename)
+ file_path, filter_used = FileDialog.getOpenFileName(
+ self, title, Settings().value(self.plugin.settings_section + '/' + setting_name), filters)
+ if file_path:
+ editbox.setText(str(file_path))
+ Settings().setValue(self.plugin.settings_section + '/' + setting_name, file_path.parent)
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 editbox: An editbox (QLineEdit).
- :param setting_name: The place where to save the last opened directory.
+ :param str title: The title of the dialog.
+ :param QtWidgets.QLineEdit editbox: An QLineEditbox.
+ :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),
QtWidgets.QFileDialog.ShowDirsOnly)
- if folder:
- editbox.setText(folder)
- Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder)
+ if folder_path:
+ editbox.setText(str(folder_path))
+ Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder_path)
=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py 2017-08-01 20:59:41 +0000
+++ openlp/core/ui/maindisplay.py 2017-08-26 15:41:28 +0000
@@ -37,6 +37,7 @@
from openlp.core.common import AppLocation, Registry, RegistryProperties, OpenLPMixin, Settings, translate,\
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.theme import BackgroundType
from openlp.core.ui import HideMode, AlertLocation, DisplayControllerType
@@ -259,7 +260,7 @@
background_color.setNamedColor(Settings().value('core/logo background color'))
if not background_color.isValid():
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)
self.initial_fame = QtGui.QImage(
self.screen['size'].width(),
=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py 2017-08-23 20:13:58 +0000
+++ openlp/core/ui/mainwindow.py 2017-08-26 15:41:28 +0000
@@ -30,7 +30,6 @@
from datetime import datetime
from distutils import dir_util
from distutils.errors import DistutilsFileError
-from pathlib import Path
from tempfile import gettempdir
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -40,6 +39,7 @@
from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder
+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.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon
from openlp.core.lib.ui import create_action
@@ -879,8 +879,8 @@
# Convert image files
log.info('hook upgrade_plugin_settings')
self.plugin_manager.hook_upgrade_plugin_settings(import_settings)
- # Remove/rename old settings to prepare the import.
- import_settings.remove_obsolete_settings()
+ # Upgrade settings to prepare the import.
+ 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
# load what we can from it, and just silently ignore anything we don't recognise.
if import_settings.value('SettingsImport/type') != 'OpenLP_settings_export':
@@ -1277,7 +1277,7 @@
settings.remove('custom slide')
settings.remove('service')
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.beginGroup(self.ui_settings_section)
self.move(settings.value('main window position'))
@@ -1301,7 +1301,7 @@
log.debug('Saving QSettings')
settings = Settings()
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.beginGroup(self.ui_settings_section)
settings.setValue('main window position', self.pos())
@@ -1443,7 +1443,7 @@
log.info('No data copy requested')
# Change the location of data directory in config file.
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.
if self.new_data_path == str(AppLocation.get_directory(AppLocation.DataDir)):
settings.remove('advanced/data path')
=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py 2017-08-23 20:13:58 +0000
+++ openlp/core/ui/servicemanager.py 2017-08-26 15:41:28 +0000
@@ -28,7 +28,6 @@
import shutil
import zipfile
from datetime import datetime, timedelta
-from pathlib import Path
from tempfile import mkstemp
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -36,11 +35,13 @@
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, ThemeLevel, OpenLPMixin, \
RegistryMixin, check_directory_exists, UiStrings, translate, split_filename, delete_file
from openlp.core.common.actions import ActionList, CategoryOrder
+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.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.lib import OpenLPToolbar
-from openlp.core.common.languagemanager import format_time
+from openlp.core.ui.lib.filedialog import FileDialog
class ServiceManagerList(QtWidgets.QTreeWidget):
@@ -373,7 +374,7 @@
"""
self._file_name = str(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')
def file_name(self):
@@ -435,18 +436,17 @@
elif result == QtWidgets.QMessageBox.Save:
self.decide_save_method()
if not load_file:
- file_name, filter_used = QtWidgets.QFileDialog.getOpenFileName(
+ file_path, filter_used = FileDialog.getOpenFileName(
self.main_window,
translate('OpenLP.ServiceManager', 'Open File'),
Settings().value(self.main_window.service_manager_settings_section + '/last directory'),
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
- if not file_name:
+ if not file_path:
return False
else:
- file_name = load_file
- Settings().setValue(self.main_window.service_manager_settings_section + '/last directory',
- split_filename(file_name)[0])
- self.load_file(file_name)
+ file_path = str_to_path(load_file)
+ Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', file_path.parent)
+ self.load_file(str(file_path))
def save_modified_service(self):
"""
@@ -477,7 +477,7 @@
self.set_file_name('')
self.service_id += 1
self.set_modified(False)
- Settings().setValue('servicemanager/last file', '')
+ Settings().setValue('servicemanager/last file', None)
self.plugin_manager.new_service_created()
def create_basic_service(self):
@@ -513,7 +513,7 @@
base_name = os.path.splitext(file_name)[0]
service_file_name = '{name}.osj'.format(name=base_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()
write_list = []
missing_list = []
@@ -634,7 +634,7 @@
base_name = os.path.splitext(file_name)[0]
service_file_name = '{name}.osj'.format(name=base_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()
self.application.set_busy_cursor()
# Number of items + 1 to zip it
@@ -695,7 +695,7 @@
default_file_name = format_time(default_pattern, local_time)
else:
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)
# 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.
@@ -778,7 +778,7 @@
delete_file(Path(p_file))
self.main_window.add_recent_file(file_name)
self.set_modified(False)
- Settings().setValue('servicemanager/last file', file_name)
+ Settings().setValue('servicemanager/last file', Path(file_name))
else:
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
self.log_error('File contains no service data')
@@ -843,7 +843,7 @@
Load the last service item from the service manager when the service was last closed. Can be blank if there was
no service present.
"""
- file_name = Settings().value('servicemanager/last file')
+ file_name = str_to_path(Settings().value('servicemanager/last file'))
if file_name:
self.load_file(file_name)
=== modified file 'openlp/core/ui/themeform.py'
--- openlp/core/ui/themeform.py 2017-08-12 17:45:56 +0000
+++ openlp/core/ui/themeform.py 2017-08-26 15:41:28 +0000
@@ -24,12 +24,11 @@
"""
import logging
import os
-from pathlib import Path
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_to_str, str_to_path
+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
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2017-08-12 17:45:56 +0000
+++ openlp/core/ui/thememanager.py 2017-08-26 15:41:28 +0000
@@ -25,14 +25,13 @@
import os
import zipfile
import shutil
-from pathlib import Path
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_to_str, str_to_path
+from openlp.core.common.path import Path, path_to_str, str_to_path
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
@@ -379,16 +378,16 @@
critical_error_message_box(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.'))
return
theme = item.data(QtCore.Qt.UserRole)
- path, filter_used = \
- QtWidgets.QFileDialog.getSaveFileName(self.main_window,
- translate('OpenLP.ThemeManager', 'Save Theme - ({name})').
- format(name=theme),
- Settings().value(self.settings_section + '/last directory export'),
- translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
+ export_path, filter_used = \
+ FileDialog.getSaveFileName(self.main_window,
+ translate('OpenLP.ThemeManager', 'Save Theme - ({name})').
+ format(name=theme),
+ Settings().value(self.settings_section + '/last directory export'),
+ translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'))
self.application.set_busy_cursor()
- if path:
- Settings().setValue(self.settings_section + '/last directory export', path)
- if self._export_theme(path, theme):
+ if export_path:
+ Settings().setValue(self.settings_section + '/last directory export', export_path.parent)
+ if self._export_theme(str(export_path, theme)):
QtWidgets.QMessageBox.information(self,
translate('OpenLP.ThemeManager', 'Theme Exported'),
translate('OpenLP.ThemeManager',
@@ -429,16 +428,15 @@
file_paths, selected_filter = FileDialog.getOpenFileNames(
self,
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)'))
self.log_info('New Themes {file_paths}'.format(file_paths=file_paths))
if not file_paths:
return
self.application.set_busy_cursor()
for file_path in file_paths:
- file_name = path_to_str(file_path)
- Settings().setValue(self.settings_section + '/last directory import', str(file_name))
- self.unzip_theme(file_name, self.path)
+ self.unzip_theme(path_to_str(file_path), self.path)
+ Settings().setValue(self.settings_section + '/last directory import', file_path)
self.load_themes()
self.application.set_normal_cursor()
=== modified file 'openlp/core/ui/themewizard.py'
--- openlp/core/ui/themewizard.py 2017-08-07 20:50:01 +0000
+++ openlp/core/ui/themewizard.py 2017-08-26 15:41:28 +0000
@@ -22,11 +22,10 @@
"""
The Create/Edit theme wizard
"""
-from pathlib import Path
-
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import UiStrings, translate, is_macosx
+from openlp.core.common.path import Path
from openlp.core.lib import build_icon
from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets
=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py 2017-08-03 17:54:40 +0000
+++ openlp/plugins/bibles/bibleplugin.py 2017-08-26 15:41:28 +0000
@@ -59,7 +59,7 @@
'bibles/range separator': '',
'bibles/list separator': '',
'bibles/end separator': '',
- 'bibles/last directory import': '',
+ 'bibles/last directory import': None,
'bibles/hide combined quick error': False,
'bibles/is search while typing enabled': True
}
=== modified file 'openlp/plugins/bibles/lib/importers/csvbible.py'
--- openlp/plugins/bibles/lib/importers/csvbible.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/bibles/lib/importers/csvbible.py 2017-08-26 15:41:28 +0000
@@ -51,9 +51,9 @@
"""
import csv
from collections import namedtuple
-from pathlib import Path
from openlp.core.common import get_file_encoding, translate
+from openlp.core.common.path import Path
from openlp.core.lib.exceptions import ValidationError
from openlp.plugins.bibles.lib.bibleimport import BibleImport
=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/bibles/lib/manager.py 2017-08-26 15:41:28 +0000
@@ -21,10 +21,9 @@
###############################################################################
import logging
-import os
-from pathlib import Path
from openlp.core.common import AppLocation, OpenLPMixin, RegistryProperties, Settings, translate, delete_file, UiStrings
+from openlp.core.common.path import Path
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from .importers.csvbible import CSVBible
@@ -306,13 +305,10 @@
"""
Does a verse search for the given bible and text.
- :param bible: The bible to search
- :type bible: str
- :param text: The text to search for
- :type text: str
-
+ :param str bible: The bible to search
+ :param str text: The text to search for
:return: The search results if valid, or None if the search is invalid.
- :rtype: None, list
+ :rtype: None | list
"""
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
if not text:
=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py 2017-06-09 15:56:40 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py 2017-08-26 15:41:28 +0000
@@ -465,8 +465,7 @@
"""
Show the selected tab and set focus to it
- :param index: The tab selected
- :type index: int
+ :param int index: The tab selected
:return: None
"""
if index == SearchTabs.Search or index == SearchTabs.Select:
@@ -483,7 +482,7 @@
Update list_widget with the contents of the selected list
:param index: The index of the tab that has been changed to. (int)
- :return: None
+ :rtype: None
"""
if index == ResultsTab.Saved:
self.add_built_results_to_list_widget(self.saved_results)
=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/images/lib/mediaitem.py 2017-08-26 15:41:28 +0000
@@ -22,12 +22,12 @@
import logging
import os
-from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, AppLocation, Settings, UiStrings, check_directory_exists, translate, \
delete_file, get_images_filter
+from openlp.core.common.path import Path
from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, build_icon, \
check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import create_widget_action, critical_error_message_box
@@ -390,7 +390,7 @@
self.application.set_normal_cursor()
self.load_list(files, target_group)
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):
"""
=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/media/lib/mediaitem.py 2017-08-26 15:41:28 +0000
@@ -22,12 +22,12 @@
import logging
import os
-from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, UiStrings,\
translate
+from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \
build_icon, check_item_selected
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box
@@ -303,7 +303,7 @@
self.list_view.clear()
self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails')
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()
def rebuild_players(self):
@@ -401,14 +401,14 @@
:param media_type: Type to get, defaults to audio.
:return: The media list
"""
- media = Settings().value(self.settings_section + '/media files')
- media.sort(key=lambda filename: get_locale_key(os.path.split(str(filename))[1]))
+ media_file_paths = Settings().value(self.settings_section + '/media files')
+ media_file_paths.sort(key=lambda file_path: get_locale_key(file_path.name))
if media_type == MediaType.Audio:
extension = self.media_controller.audio_extensions_list
else:
extension = self.media_controller.video_extensions_list
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
def search(self, string, show_error):
@@ -419,13 +419,12 @@
:param show_error: Should the error be shown (True)
:return: The search result.
"""
- files = Settings().value(self.settings_section + '/media files')
results = []
string = string.lower()
- for file in files:
- filename = os.path.split(str(file))[1]
- if filename.lower().find(string) > -1:
- results.append([file, filename])
+ for file_path in Settings().value(self.settings_section + '/media files'):
+ file_name = file_path.name
+ if file_name.lower().find(string) > -1:
+ results.append([str(file_path), file_name])
return results
def on_load_optical(self):
@@ -446,13 +445,13 @@
: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 optical in full_list:
+ if optical in file_paths:
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Mediaclip already saved'),
translate('MediaPlugin.MediaItem', 'This mediaclip has already been saved'))
return
# Append the optical string to the media list
- full_list.append(optical)
+ file_paths.append(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)
=== modified file 'openlp/plugins/media/mediaplugin.py'
--- openlp/plugins/media/mediaplugin.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/media/mediaplugin.py 2017-08-26 15:41:28 +0000
@@ -26,12 +26,11 @@
import logging
import os
import re
-from pathlib import Path
-
from PyQt5 import QtCore
from openlp.core.api.http import register_endpoint
from openlp.core.common import AppLocation, translate, check_binary_exists
+from openlp.core.common.path import Path
from openlp.core.lib import Plugin, StringContent, build_icon
from openlp.plugins.media.endpoint import api_media_endpoint, media_endpoint
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
--- openlp/plugins/presentations/lib/impresscontroller.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/presentations/lib/impresscontroller.py 2017-08-26 15:41:28 +0000
@@ -34,9 +34,9 @@
import logging
import os
import time
-from pathlib import Path
-from openlp.core.common import is_win, Registry, get_uno_command, get_uno_instance, delete_file
+from openlp.core.common import is_win, Registry, delete_file
+from openlp.core.common.path import Path
if is_win():
from win32com.client import Dispatch
=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py 2017-03-03 19:27:31 +0000
+++ openlp/plugins/presentations/lib/mediaitem.py 2017-08-26 15:41:28 +0000
@@ -26,10 +26,11 @@
from PyQt5 import QtCore, QtGui, QtWidgets
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,\
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.common.languagemanager import get_locale_key
from openlp.plugins.presentations.lib import MessageListener
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
@@ -126,8 +127,8 @@
Populate the media manager tab
"""
self.list_view.setIconSize(QtCore.QSize(88, 50))
- files = Settings().value(self.settings_section + '/presentations files')
- self.load_list(files, initial_load=True)
+ file_paths = Settings().value(self.settings_section + '/presentations files')
+ self.load_list([path_to_str(file) for file in file_paths], initial_load=True)
self.populate_display_types()
def populate_display_types(self):
@@ -157,7 +158,7 @@
existing files, and when the user adds new files via the media manager.
"""
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()
if not initial_load:
self.main_window.display_progress_bar(len(files))
@@ -410,11 +411,11 @@
:param show_error: not used
:return:
"""
- files = Settings().value(self.settings_section + '/presentations files')
+ file_paths = Settings().value(self.settings_section + '/presentations files')
results = []
string = string.lower()
- for file in files:
- filename = os.path.split(str(file))[1]
- if filename.lower().find(string) > -1:
- results.append([file, filename])
+ for file_path in file_paths:
+ file_name = file_path.name
+ if file_name.lower().find(string) > -1:
+ results.append([path_to_str(file_path), file_name])
return results
=== modified file 'openlp/plugins/presentations/lib/pdfcontroller.py'
--- openlp/plugins/presentations/lib/pdfcontroller.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/presentations/lib/pdfcontroller.py 2017-08-26 15:41:28 +0000
@@ -23,12 +23,12 @@
import os
import logging
import re
-from pathlib import Path
from shutil import which
from subprocess import check_output, CalledProcessError
from openlp.core.common import AppLocation, check_binary_exists
from openlp.core.common import Settings, is_win
+from openlp.core.common.path import Path, path_to_str
from openlp.core.lib import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
@@ -113,7 +113,7 @@
self.also_supports = []
# Use the user defined program if given
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)
if program_type == 'gs':
self.gsbin = pdf_program
=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
--- openlp/plugins/presentations/lib/presentationcontroller.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/presentations/lib/presentationcontroller.py 2017-08-26 15:41:28 +0000
@@ -23,11 +23,11 @@
import logging
import os
import shutil
-from pathlib import Path
from PyQt5 import QtCore
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, md5_hash
+from openlp.core.common.path import Path
from openlp.core.lib import create_thumb, validate_thumb
log = logging.getLogger(__name__)
=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
--- openlp/plugins/presentations/lib/presentationtab.py 2017-08-04 21:53:02 +0000
+++ openlp/plugins/presentations/lib/presentationtab.py 2017-08-26 15:41:28 +0000
@@ -155,9 +155,7 @@
enable_pdf_program = Settings().value(self.settings_section + '/enable_pdf_program')
self.pdf_program_check_box.setChecked(enable_pdf_program)
self.program_path_edit.setEnabled(enable_pdf_program)
- pdf_program = Settings().value(self.settings_section + '/pdf_program')
- if pdf_program:
- self.program_path_edit.path = str_to_path(pdf_program)
+ self.program_path_edit.path = Settings().value(self.settings_section + '/pdf_program')
def save(self):
"""
@@ -193,13 +191,13 @@
Settings().setValue(setting_key, self.ppt_window_check_box.checkState())
changed = True
# 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()
# If the given program is blank disable using the program
- if pdf_program == '':
+ if not pdf_program_path:
enable_pdf_program = 0
- if pdf_program != Settings().value(self.settings_section + '/pdf_program'):
- Settings().setValue(self.settings_section + '/pdf_program', pdf_program)
+ if pdf_program_path != Settings().value(self.settings_section + '/pdf_program'):
+ Settings().setValue(self.settings_section + '/pdf_program', pdf_program_path)
changed = True
if enable_pdf_program != Settings().value(self.settings_section + '/enable_pdf_program'):
Settings().setValue(self.settings_section + '/enable_pdf_program', enable_pdf_program)
=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/presentations/presentationplugin.py 2017-08-26 15:41:28 +0000
@@ -39,7 +39,7 @@
__default_settings__ = {'presentations/override app': QtCore.Qt.Unchecked,
'presentations/enable_pdf_program': QtCore.Qt.Unchecked,
- 'presentations/pdf_program': '',
+ 'presentations/pdf_program': None,
'presentations/Impress': QtCore.Qt.Checked,
'presentations/Powerpoint': QtCore.Qt.Checked,
'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2017-08-26 15:41:28 +0000
@@ -28,12 +28,11 @@
import re
import os
import shutil
-from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, UiStrings, check_directory_exists, translate
-from openlp.core.common.path import path_to_str
+from openlp.core.common.path import Path, path_to_str
from openlp.core.lib import PluginStatus, MediaType, create_separated_list
from openlp.core.lib.ui import set_case_insensitive_completer, critical_error_message_box, find_and_set_in_combo_box
from openlp.core.ui.lib.filedialog import FileDialog
=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py 2017-08-07 20:50:01 +0000
+++ openlp/plugins/songs/forms/songimportform.py 2017-08-26 15:41:28 +0000
@@ -239,13 +239,11 @@
filters += ';;'
filters += '{text} (*)'.format(text=UiStrings().AllFiles)
file_paths, selected_filter = FileDialog.getOpenFileNames(
- self, title,
- str_to_path(Settings().value(self.plugin.settings_section + '/last directory import')), filters)
+ self, title, Settings().value(self.plugin.settings_section + '/last directory import'), filters)
if file_paths:
file_names = [path_to_str(file_path) for file_path in file_paths]
listbox.addItems(file_names)
- Settings().setValue(self.plugin.settings_section + '/last directory import',
- os.path.split(str(file_names[0]))[0])
+ Settings().setValue(self.plugin.settings_section + '/last directory import', file_paths[0].parent)
def get_list_of_files(self, list_box):
"""
@@ -363,14 +361,15 @@
def on_error_save_to_button_clicked(self):
"""
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'))
- if not filename:
+ if not file_path:
return
- report_file = codecs.open(filename, 'w', 'utf-8')
- report_file.write(self.error_report_text_edit.toPlainText())
- report_file.close()
+ with file_path.open('w', encoding='utf-8') as report_file:
+ report_file.write(self.error_report_text_edit.toPlainText())
def add_file_select_item(self):
"""
=== modified file 'openlp/plugins/songs/lib/importers/songbeamer.py'
--- openlp/plugins/songs/lib/importers/songbeamer.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/songs/lib/importers/songbeamer.py 2017-08-26 15:41:28 +0000
@@ -27,11 +27,11 @@
import re
import base64
import math
-from pathlib import Path
+from openlp.core.common import Settings, is_win, is_macosx, get_file_encoding
+from openlp.core.common.path import Path
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.importers.songimport import SongImport
-from openlp.core.common import Settings, is_win, is_macosx, get_file_encoding
log = logging.getLogger(__name__)
=== modified file 'openlp/plugins/songs/lib/importers/songimport.py'
--- openlp/plugins/songs/lib/importers/songimport.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/songs/lib/importers/songimport.py 2017-08-26 15:41:28 +0000
@@ -24,11 +24,11 @@
import re
import shutil
import os
-from pathlib import Path
from PyQt5 import QtCore
from openlp.core.common import Registry, AppLocation, check_directory_exists, translate
+from openlp.core.common.path import Path
from openlp.core.ui.lib.wizard import WizardStrings
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2017-08-23 20:13:58 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2017-08-26 15:41:28 +0000
@@ -23,12 +23,12 @@
import logging
import os
import shutil
-from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_, or_
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, UiStrings, translate
+from openlp.core.common.path import Path
from openlp.core.lib import MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \
check_item_selected, create_separated_list
from openlp.core.lib.ui import create_widget_action
=== modified file 'openlp/plugins/songs/lib/openlyricsexport.py'
--- openlp/plugins/songs/lib/openlyricsexport.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/songs/lib/openlyricsexport.py 2017-08-26 15:41:28 +0000
@@ -25,11 +25,11 @@
"""
import logging
import os
-from pathlib import Path
from lxml import etree
from openlp.core.common import RegistryProperties, check_directory_exists, translate, clean_filename
+from openlp.core.common.path import Path
from openlp.plugins.songs.lib.openlyricsxml import OpenLyrics
log = logging.getLogger(__name__)
=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py 2017-06-11 19:41:34 +0000
+++ openlp/plugins/songs/songsplugin.py 2017-08-26 15:41:28 +0000
@@ -66,8 +66,8 @@
'songs/display songbook': False,
'songs/display written by': True,
'songs/display copyright symbol': False,
- 'songs/last directory import': '',
- 'songs/last directory export': '',
+ 'songs/last directory import': None,
+ 'songs/last directory export': None,
'songs/songselect username': '',
'songs/songselect password': '',
'songs/songselect searches': '',
=== modified file 'openlp/plugins/songusage/forms/songusagedetailform.py'
--- openlp/plugins/songusage/forms/songusagedetailform.py 2017-08-12 17:45:56 +0000
+++ openlp/plugins/songusage/forms/songusagedetailform.py 2017-08-26 15:41:28 +0000
@@ -22,13 +22,12 @@
import logging
import os
-from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_
from openlp.core.common import RegistryProperties, Settings, check_directory_exists, 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.ui import critical_error_message_box
from openlp.plugins.songusage.lib.db import SongUsageItem
from .songusagedetaildialog import Ui_SongUsageDetailDialog
@@ -57,14 +56,16 @@
"""
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.report_path_edit.path = str_to_path(
- Settings().value(self.plugin.settings_section + '/last directory export'))
+ self.report_path_edit.path = Settings().value(self.plugin.settings_section + '/last directory export')
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):
"""
=== modified file 'openlp/plugins/songusage/songusageplugin.py'
--- openlp/plugins/songusage/songusageplugin.py 2016-12-31 11:01:36 +0000
+++ openlp/plugins/songusage/songusageplugin.py 2017-08-26 15:41:28 +0000
@@ -50,7 +50,7 @@
'songusage/active': False,
'songusage/to date': QtCore.QDate(YEAR, 8, 31),
'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1),
- 'songusage/last directory export': ''
+ 'songusage/last directory export': None
}
=== modified file 'tests/functional/openlp_core_common/test_applocation.py'
--- tests/functional/openlp_core_common/test_applocation.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_common/test_applocation.py 2017-08-26 15:41:28 +0000
@@ -22,13 +22,12 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
-import copy
import os
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common import AppLocation, get_frozen_path
+from openlp.core.common.path import Path
FILE_LIST = ['file1', 'file2', 'file3.txt', 'file4.txt', 'file5.mp3', 'file6.mp3']
@@ -43,12 +42,14 @@
"""
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.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()
mocked_settings = mocked_class.return_value
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_os.path.normpath.return_value = os.path.join('test', 'dir')
# WHEN: we call AppLocation.get_data_path()
data_path = AppLocation.get_data_path()
@@ -56,8 +57,8 @@
# THEN: check that all the correct methods were called, and the result is correct
mocked_settings.contains.assert_called_with('advanced/data path')
mocked_get_directory.assert_called_with(AppLocation.DataDir)
- mocked_check_directory_exists.assert_called_with(Path('test', 'dir'))
- self.assertEqual(Path('test', 'dir'), data_path, 'Result should be "test/dir"')
+ mocked_check_directory_exists.assert_called_with(os.path.join('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):
"""
=== modified file 'tests/functional/openlp_core_common/test_common.py'
--- tests/functional/openlp_core_common/test_common.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_common/test_common.py 2017-08-26 15:41:28 +0000
@@ -22,13 +22,12 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, call, patch
-from openlp.core import common
from openlp.core.common import check_directory_exists, clean_button_text, de_hump, extension_loader, is_macosx, \
is_linux, is_win, path_to_module, trace_error_handler, translate
+from openlp.core.common.path import Path
class TestCommonFunctions(TestCase):
=== modified file 'tests/functional/openlp_core_common/test_init.py'
--- tests/functional/openlp_core_common/test_init.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_common/test_init.py 2017-08-26 15:41:28 +0000
@@ -24,12 +24,12 @@
"""
import os
from io import BytesIO
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, PropertyMock, call, patch
from openlp.core.common import add_actions, clean_filename, delete_file, get_file_encoding, get_filesystem_encoding, \
get_uno_command, get_uno_instance, split_filename
+from openlp.core.common.path import Path
from tests.helpers.testmixin import TestMixin
=== added file 'tests/functional/openlp_core_common/test_json.py'
--- tests/functional/openlp_core_common/test_json.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_common/test_json.py 2017-08-26 15:41:28 +0000
@@ -0,0 +1,122 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2017 OpenLP Developers #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it #
+# under the terms of the GNU General Public License as published by the Free #
+# Software Foundation; version 2 of the License. #
+# #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
+# more details. #
+# #
+# You should have received a copy of the GNU General Public License along #
+# with this program; if not, write to the Free Software Foundation, Inc., 59 #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
+###############################################################################
+"""
+Package to test the openlp.core.common.json package.
+"""
+import json
+from unittest import TestCase
+from unittest.mock import patch
+
+from openlp.core.common.path import Path
+from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
+
+
+class TestOpenLPJsonDecoder(TestCase):
+ """
+ Test the OpenLPJsonDecoder class
+ """
+ def test_object_hook_path_object(self):
+ """
+ Test the object_hook method when called with a decoded Path JSON object
+ """
+ # GIVEN: An instance of OpenLPJsonDecoder
+ instance = OpenLPJsonDecoder()
+
+ # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
+ result = instance.object_hook({'__Path__': ['test', 'path']})
+
+ # THEN: A Path object should be returned
+ self.assertEqual(result, Path('test', 'path'))
+
+ def test_object_hook_non_path_object(self):
+ """
+ Test the object_hook method when called with a decoded JSON object
+ """
+ # GIVEN: An instance of OpenLPJsonDecoder
+ instance = OpenLPJsonDecoder()
+
+ # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
+ with patch('openlp.core.common.json.Path') as mocked_path:
+ result = instance.object_hook({'key': 'value'})
+
+ # THEN: The object should be returned unchanged and a Path object should not have been initiated
+ self.assertEqual(result, {'key': 'value'})
+ self.assertFalse(mocked_path.called)
+
+ def test_json_decode(self):
+ """
+ Test the OpenLPJsonDecoder when decoding a JSON string
+ """
+ # GIVEN: A JSON encoded string
+ json_string = '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'
+
+ # WHEN: Decoding the string using the OpenLPJsonDecoder class
+ obj = json.loads(json_string, cls=OpenLPJsonDecoder)
+
+ # THEN: The object returned should be a python version of the JSON string
+ self.assertEqual(obj, [Path('test', 'path1'), Path('test', 'path2')])
+
+
+class TestOpenLPJsonEncoder(TestCase):
+ """
+ Test the OpenLPJsonEncoder class
+ """
+ def test_default_path_object(self):
+ """
+ Test the default method when called with a Path object
+ """
+ # GIVEN: An instance of OpenLPJsonEncoder
+ instance = OpenLPJsonEncoder()
+
+ # WHEN: Calling the default method with a Path object
+ result = instance.default(Path('test', 'path'))
+
+ # THEN: A dictionary object that can be JSON encoded should be returned
+ self.assertEqual(result, {'__Path__': ('test', 'path')})
+
+ def test_default_non_path_object(self):
+ """
+ Test the default method when called with a object other than a Path object
+ """
+ with patch('openlp.core.common.json.JSONEncoder.default') as mocked_super_default:
+
+ # GIVEN: An instance of OpenLPJsonEncoder
+ instance = OpenLPJsonEncoder()
+
+ # WHEN: Calling the default method with a object other than a Path object
+ instance.default('invalid object')
+
+ # THEN: default method of the super class should have been called
+ mocked_super_default.assert_called_once_with('invalid object')
+
+ def test_json_encode(self):
+ """
+ Test the OpenLPJsonDEncoder when encoding an object conatining Path objects
+ """
+ # GIVEN: A list of Path objects
+ obj = [Path('test', 'path1'), Path('test', 'path2')]
+
+ # WHEN: Encoding the object using the OpenLPJsonEncoder class
+ json_string = json.dumps(obj, cls=OpenLPJsonEncoder)
+
+ # THEN: The JSON string return should be a representation of the object encoded
+ self.assertEqual(json_string, '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]')
=== modified file 'tests/functional/openlp_core_common/test_path.py'
--- tests/functional/openlp_core_common/test_path.py 2017-08-04 18:06:43 +0000
+++ tests/functional/openlp_core_common/test_path.py 2017-08-26 15:41:28 +0000
@@ -23,10 +23,9 @@
Package to test the openlp.core.common.path package.
"""
import os
-from pathlib import Path
from unittest import TestCase
-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
class TestPath(TestCase):
@@ -86,3 +85,54 @@
# THEN: `path_to_str` should return None
self.assertEqual(result, None)
+
+ def test_path_encode_json(self):
+ """
+ Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
+ from JSON
+ """
+ # GIVEN: A Path object from openlp.core.common.path
+ # WHEN: Calling encode_json, with a dictionary representation
+ path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, extra=1, args=2)
+
+ # THEN: A Path object should have been returned
+ self.assertEqual(path, Path('path', 'to', 'fi.le'))
+
+ def test_path_encode_json_base_path(self):
+ """
+ Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
+ from JSON when the base_path arg is supplied.
+ """
+ # GIVEN: A Path object from openlp.core.common.path
+ # WHEN: Calling encode_json, with a dictionary representation
+ path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, base_path=Path('/base'))
+
+ # THEN: A Path object should have been returned with an absolute path
+ self.assertEqual(path, Path('/', 'base', 'path', 'to', 'fi.le'))
+
+ def test_path_json_object(self):
+ """
+ Test that `Path.json_object` creates a JSON decode-able object from a Path object
+ """
+ # GIVEN: A Path object from openlp.core.common.path
+ path = Path('/base', 'path', 'to', 'fi.le')
+
+ # WHEN: Calling json_object
+ obj = path.json_object(extra=1, args=2)
+
+ # THEN: A JSON decodable object should have been returned.
+ self.assertEqual(obj, {'__Path__': ('/', 'base', 'path', 'to', 'fi.le')})
+
+ def test_path_json_object_base_path(self):
+ """
+ Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
+ base_path
+ """
+ # GIVEN: A Path object from openlp.core.common.path
+ path = Path('/base', 'path', 'to', 'fi.le')
+
+ # WHEN: Calling json_object with a base_path
+ obj = path.json_object(base_path=Path('/', 'base'))
+
+ # THEN: A JSON decodable object should have been returned.
+ self.assertEqual(obj, {'__Path__': ('path', 'to', 'fi.le')})
=== modified file 'tests/functional/openlp_core_common/test_settings.py'
--- tests/functional/openlp_core_common/test_settings.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_common/test_settings.py 2017-08-26 15:41:28 +0000
@@ -26,7 +26,6 @@
from unittest.mock import patch
from openlp.core.common import Settings
-from openlp.core.common.settings import recent_files_conv
from tests.helpers.testmixin import TestMixin
@@ -48,25 +47,6 @@
"""
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):
"""
Test the Settings creation and its default usage
=== modified file 'tests/functional/openlp_core_lib/test_db.py'
--- tests/functional/openlp_core_lib/test_db.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_lib/test_db.py 2017-08-26 15:41:28 +0000
@@ -22,9 +22,7 @@
"""
Package to test the openlp.core.lib package.
"""
-import os
import shutil
-from pathlib import Path
from tempfile import mkdtemp
from unittest import TestCase
@@ -34,6 +32,7 @@
from sqlalchemy.orm.scoping import ScopedSession
from sqlalchemy import MetaData
+from openlp.core.common.path import Path
from openlp.core.lib.db import init_db, get_upgrade_op, delete_database, upgrade_db
from openlp.core.lib.projector import upgrade as pjlink_upgrade
=== modified file 'tests/functional/openlp_core_lib/test_lib.py'
--- tests/functional/openlp_core_lib/test_lib.py 2017-08-25 04:26:25 +0000
+++ tests/functional/openlp_core_lib/test_lib.py 2017-08-26 15:41:28 +0000
@@ -24,12 +24,12 @@
"""
import os
from datetime import datetime, timedelta
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui
+from openlp.core.common.path import Path
from openlp.core.lib import FormattingTags, build_icon, check_item_selected, clean_tags, compare_chord_lyric, \
create_separated_list, create_thumb, expand_chords, expand_chords_for_printing, expand_tags, find_formatting_tags, \
get_text_file_string, image_to_byte, replace_params, resize_image, str_to_bool, validate_thumb
=== modified file 'tests/functional/openlp_core_lib/test_path.py'
--- tests/functional/openlp_core_lib/test_path.py 2017-08-02 06:09:38 +0000
+++ tests/functional/openlp_core_lib/test_path.py 2017-08-26 15:41:28 +0000
@@ -23,10 +23,9 @@
Package to test the openlp.core.lib.path package.
"""
import os
-from pathlib import Path
from unittest import TestCase
-from openlp.core.lib.path import path_to_str, str_to_path
+from openlp.core.common.path import Path, path_to_str, str_to_path
class TestPath(TestCase):
=== modified file 'tests/functional/openlp_core_ui/test_exceptionform.py'
--- tests/functional/openlp_core_ui/test_exceptionform.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_ui/test_exceptionform.py 2017-08-26 15:41:28 +0000
@@ -29,6 +29,7 @@
from unittest.mock import mock_open, patch
from openlp.core.common import Registry
+from openlp.core.common.path import Path
from openlp.core.ui import exceptionform
from tests.helpers.testmixin import TestMixin
@@ -154,7 +155,7 @@
# THEN: Verify strings were formatted properly
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")
def test_on_save_report_button_clicked(self,
mocked_qt,
@@ -181,7 +182,7 @@
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False
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.file_attachment = None
=== modified file 'tests/functional/openlp_core_ui/test_firsttimeform.py'
--- tests/functional/openlp_core_ui/test_firsttimeform.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_core_ui/test_firsttimeform.py 2017-08-26 15:41:28 +0000
@@ -25,11 +25,11 @@
import os
import tempfile
import urllib
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common import Registry
+from openlp.core.common.path import Path
from openlp.core.ui.firsttimeform import FirstTimeForm
from tests.helpers.testmixin import TestMixin
=== modified file 'tests/functional/openlp_core_ui/test_themeform.py'
--- tests/functional/openlp_core_ui/test_themeform.py 2017-08-04 17:40:57 +0000
+++ tests/functional/openlp_core_ui/test_themeform.py 2017-08-26 15:41:28 +0000
@@ -22,10 +22,10 @@
"""
Package to test the openlp.core.ui.themeform package.
"""
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
+from openlp.core.common.path import Path
from openlp.core.ui import ThemeForm
=== modified file 'tests/functional/openlp_core_ui_lib/test_filedialog.py'
--- tests/functional/openlp_core_ui_lib/test_filedialog.py 2017-08-07 21:01:16 +0000
+++ tests/functional/openlp_core_ui_lib/test_filedialog.py 2017-08-26 15:41:28 +0000
@@ -1,10 +1,10 @@
import os
from unittest import TestCase
from unittest.mock import patch
-from pathlib import Path
from PyQt5 import QtWidgets
+from openlp.core.common.path import Path
from openlp.core.ui.lib.filedialog import FileDialog
=== modified file 'tests/functional/openlp_core_ui_lib/test_pathedit.py'
--- tests/functional/openlp_core_ui_lib/test_pathedit.py 2017-08-07 20:50:01 +0000
+++ tests/functional/openlp_core_ui_lib/test_pathedit.py 2017-08-26 15:41:28 +0000
@@ -23,10 +23,10 @@
This module contains tests for the openlp.core.ui.lib.pathedit module
"""
import os
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, PropertyMock, patch
+from openlp.core.common.path import Path
from openlp.core.ui.lib import PathEdit, PathType
from openlp.core.ui.lib.filedialog import FileDialog
=== modified file 'tests/functional/openlp_plugins/bibles/test_manager.py'
--- tests/functional/openlp_plugins/bibles/test_manager.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_plugins/bibles/test_manager.py 2017-08-26 15:41:28 +0000
@@ -22,10 +22,10 @@
"""
This module contains tests for the manager submodule of the Bibles plugin.
"""
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
+from openlp.core.common.path import Path
from openlp.plugins.bibles.lib.manager import BibleManager
=== modified file 'tests/functional/openlp_plugins/images/test_lib.py'
--- tests/functional/openlp_plugins/images/test_lib.py 2017-05-08 19:04:14 +0000
+++ tests/functional/openlp_plugins/images/test_lib.py 2017-08-26 15:41:28 +0000
@@ -28,6 +28,7 @@
from PyQt5 import QtCore, QtWidgets
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.mediaitem import ImageMediaItem
@@ -65,7 +66,7 @@
# THEN: load_list should have been called with the file list and None,
# the directory should have been saved to the settings
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.Settings')
@@ -82,7 +83,7 @@
# THEN: load_list should have been called with the file list and the group name,
# the directory should have been saved to the settings
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')
def test_save_new_images_list_empty_list(self, mocked_load_full_list):
=== modified file 'tests/functional/openlp_plugins/media/test_mediaitem.py'
--- tests/functional/openlp_plugins/media/test_mediaitem.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_plugins/media/test_mediaitem.py 2017-08-26 15:41:28 +0000
@@ -28,6 +28,7 @@
from PyQt5 import QtCore
from openlp.core import Settings
+from openlp.core.common.path import Path
from openlp.plugins.media.lib.mediaitem import MediaMediaItem
from tests.helpers.testmixin import TestMixin
@@ -66,7 +67,7 @@
Media Remote Search Successful find
"""
# 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
result = self.media_item.search('test.mp4', False)
# THEN: a file should be found
@@ -77,7 +78,7 @@
Media Remote Search not find
"""
# 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
result = self.media_item.search('test.mpx', False)
# THEN: a file should be found
=== modified file 'tests/functional/openlp_plugins/presentations/test_presentationcontroller.py'
--- tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-08-12 17:45:56 +0000
+++ tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-08-26 15:41:28 +0000
@@ -24,10 +24,10 @@
classes and related methods.
"""
import os
-from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, mock_open, patch
+from openlp.core.common.path import Path
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder'
=== modified file 'tests/interfaces/openlp_core_common/test_utils.py'
--- tests/interfaces/openlp_core_common/test_utils.py 2017-08-12 17:45:56 +0000
+++ tests/interfaces/openlp_core_common/test_utils.py 2017-08-26 15:41:28 +0000
@@ -22,10 +22,10 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
-from pathlib import Path
from unittest import TestCase
from openlp.core.common import is_not_image_file
+from openlp.core.common.path import Path
from tests.utils.constants import TEST_RESOURCES_PATH
from tests.helpers.testmixin import TestMixin
=== modified file 'tests/interfaces/openlp_core_lib/test_pluginmanager.py'
--- tests/interfaces/openlp_core_lib/test_pluginmanager.py 2017-04-24 05:17:55 +0000
+++ tests/interfaces/openlp_core_lib/test_pluginmanager.py 2017-08-26 15:41:28 +0000
@@ -32,6 +32,7 @@
from PyQt5 import QtWidgets
from openlp.core.common import Registry, Settings
+from openlp.core.common.path import Path
from openlp.core.lib.pluginmanager import PluginManager
from tests.helpers.testmixin import TestMixin
@@ -48,7 +49,7 @@
"""
self.setup_application()
self.build_settings()
- self.temp_dir = mkdtemp('openlp')
+ self.temp_dir = Path(mkdtemp('openlp'))
Settings().setValue('advanced/data path', self.temp_dir)
Registry.create()
Registry().register('service_list', MagicMock())
@@ -62,7 +63,7 @@
# On windows we need to manually garbage collect to close sqlalchemy files
# to avoid errors when temporary files are deleted.
gc.collect()
- shutil.rmtree(self.temp_dir)
+ shutil.rmtree(str(self.temp_dir))
@patch('openlp.plugins.songusage.lib.db.init_schema')
@patch('openlp.plugins.songs.lib.db.init_schema')
Follow ups