Merge lp:~phill-ridout/openlp/json_refactors into lp:openlp

Proposed by Phill
Status: Merged
Merged at revision: 2872
Proposed branch: lp:~phill-ridout/openlp/json_refactors
Merge into: lp:openlp
Diff against target: 3324 lines (+584/-568)
94 files modified
openlp/core/api/deploy.py (+1/-1)
openlp/core/api/endpoint/controller.py (+1/-1)
openlp/core/app.py (+4/-2)
openlp/core/common/__init__.py (+5/-5)
openlp/core/common/applocation.py (+7/-6)
openlp/core/common/httputils.py (+1/-1)
openlp/core/common/json.py (+130/-20)
openlp/core/common/path.py (+6/-115)
openlp/core/common/settings.py (+10/-8)
openlp/core/display/window.py (+6/-6)
openlp/core/lib/__init__.py (+6/-6)
openlp/core/lib/db.py (+15/-18)
openlp/core/lib/mediamanageritem.py (+3/-3)
openlp/core/lib/serviceitem.py (+3/-3)
openlp/core/lib/theme.py (+7/-7)
openlp/core/server.py (+2/-1)
openlp/core/ui/advancedtab.py (+2/-2)
openlp/core/ui/firsttimeform.py (+2/-1)
openlp/core/ui/generaltab.py (+1/-1)
openlp/core/ui/mainwindow.py (+5/-3)
openlp/core/ui/servicemanager.py (+11/-10)
openlp/core/ui/slidecontroller.py (+1/-1)
openlp/core/ui/themeform.py (+2/-2)
openlp/core/ui/thememanager.py (+15/-13)
openlp/core/widgets/dialogs.py (+8/-8)
openlp/core/widgets/edits.py (+6/-5)
openlp/core/widgets/views.py (+6/-5)
openlp/plugins/bibles/lib/bibleimport.py (+1/-1)
openlp/plugins/bibles/lib/db.py (+3/-3)
openlp/plugins/bibles/lib/importers/csvbible.py (+1/-1)
openlp/plugins/bibles/lib/importers/wordproject.py (+1/-1)
openlp/plugins/bibles/lib/manager.py (+1/-1)
openlp/plugins/images/lib/mediaitem.py (+6/-5)
openlp/plugins/images/lib/upgrade.py (+3/-3)
openlp/plugins/media/forms/mediaclipselectorform.py (+1/-1)
openlp/plugins/presentations/lib/impresscontroller.py (+1/-1)
openlp/plugins/presentations/lib/mediaitem.py (+3/-3)
openlp/plugins/presentations/lib/messagelistener.py (+1/-1)
openlp/plugins/presentations/lib/pdfcontroller.py (+3/-3)
openlp/plugins/presentations/lib/powerpointcontroller.py (+1/-1)
openlp/plugins/presentations/lib/presentationcontroller.py (+11/-9)
openlp/plugins/presentations/lib/presentationtab.py (+1/-1)
openlp/plugins/songs/forms/editsongform.py (+2/-1)
openlp/plugins/songs/forms/mediafilesform.py (+2/-2)
openlp/plugins/songs/lib/importers/easyworship.py (+1/-1)
openlp/plugins/songs/lib/importers/powersong.py (+2/-2)
openlp/plugins/songs/lib/importers/presentationmanager.py (+1/-1)
openlp/plugins/songs/lib/importers/propresenter.py (+1/-1)
openlp/plugins/songs/lib/importers/songbeamer.py (+1/-1)
openlp/plugins/songs/lib/importers/songimport.py (+4/-3)
openlp/plugins/songs/lib/importers/songpro.py (+1/-1)
openlp/plugins/songs/lib/importers/sundayplus.py (+2/-2)
openlp/plugins/songs/lib/importers/videopsalm.py (+1/-1)
openlp/plugins/songs/lib/mediaitem.py (+3/-2)
openlp/plugins/songs/lib/openlyricsexport.py (+1/-1)
openlp/plugins/songs/lib/upgrade.py (+3/-3)
openlp/plugins/songs/reporting.py (+1/-1)
openlp/plugins/songs/songsplugin.py (+1/-1)
openlp/plugins/songusage/forms/songusagedetailform.py (+1/-1)
tests/functional/openlp_core/api/test_deploy.py (+3/-2)
tests/functional/openlp_core/common/test_applocation.py (+1/-1)
tests/functional/openlp_core/common/test_common.py (+1/-1)
tests/functional/openlp_core/common/test_httputils.py (+1/-1)
tests/functional/openlp_core/common/test_init.py (+1/-1)
tests/functional/openlp_core/common/test_json.py (+198/-20)
tests/functional/openlp_core/common/test_path.py (+4/-187)
tests/functional/openlp_core/common/test_settings.py (+2/-1)
tests/functional/openlp_core/lib/test_db.py (+1/-1)
tests/functional/openlp_core/lib/test_lib.py (+1/-1)
tests/functional/openlp_core/lib/test_serviceitem.py (+1/-1)
tests/functional/openlp_core/test_server.py (+1/-1)
tests/functional/openlp_core/ui/test_exceptionform.py (+1/-1)
tests/functional/openlp_core/ui/test_firsttimeform.py (+1/-1)
tests/functional/openlp_core/ui/test_themeform.py (+1/-1)
tests/functional/openlp_core/ui/test_thememanager.py (+8/-8)
tests/functional/openlp_core/widgets/test_dialogs.py (+1/-1)
tests/functional/openlp_core/widgets/test_edits.py (+1/-1)
tests/functional/openlp_plugins/bibles/test_bibleimport.py (+1/-1)
tests/functional/openlp_plugins/bibles/test_csvimport.py (+1/-1)
tests/functional/openlp_plugins/bibles/test_manager.py (+1/-1)
tests/functional/openlp_plugins/bibles/test_wordprojectimport.py (+1/-1)
tests/functional/openlp_plugins/images/test_lib.py (+1/-1)
tests/functional/openlp_plugins/images/test_upgrade.py (+1/-1)
tests/functional/openlp_plugins/media/test_mediaitem.py (+1/-1)
tests/functional/openlp_plugins/presentations/test_mediaitem.py (+1/-1)
tests/functional/openlp_plugins/presentations/test_pdfcontroller.py (+4/-4)
tests/functional/openlp_plugins/presentations/test_presentationcontroller.py (+1/-1)
tests/functional/openlp_plugins/songs/test_openlyricsexport.py (+3/-2)
tests/helpers/songfileimport.py (+1/-1)
tests/interfaces/openlp_core/lib/test_pluginmanager.py (+3/-2)
tests/interfaces/openlp_core/ui/test_firsttimeform.py (+1/-1)
tests/interfaces/openlp_core/ui/test_thememanager.py (+1/-1)
tests/utils/__init__.py (+1/-1)
tests/utils/constants.py (+1/-2)
To merge this branch: bzr merge lp:~phill-ridout/openlp/json_refactors
Reviewer Review Type Date Requested Status
Tomas Groth Approve
Review via email: mp+367868@code.launchpad.net

Commit message

rework json handling for custom objects
refactor path file

Description of the change

The standard library now has much better support for paths, so I've removed the patches that were implemented.
Rework the custom object json handling

To post a comment you must log in.
Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Linux tests passed!

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

Linting passed!

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

macOS tests passed!

Revision history for this message
Tomas Groth (tomasgroth) wrote :

Looks ok to me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/api/deploy.py'
--- openlp/core/api/deploy.py 2019-04-13 13:00:22 +0000
+++ openlp/core/api/deploy.py 2019-05-23 20:08:25 +0000
@@ -34,7 +34,7 @@
34 Process the downloaded zip file and add to the correct directory34 Process the downloaded zip file and add to the correct directory
3535
36 :param str zip_name: the zip file name to be processed36 :param str zip_name: the zip file name to be processed
37 :param openlp.core.common.path.Path app_root_path: The directory to expand the zip to37 :param pathlib.Path app_root_path: The directory to expand the zip to
3838
39 :return: None39 :return: None
40 """40 """
4141
=== modified file 'openlp/core/api/endpoint/controller.py'
--- openlp/core/api/endpoint/controller.py 2019-04-13 13:00:22 +0000
+++ openlp/core/api/endpoint/controller.py 2019-05-23 20:08:25 +0000
@@ -24,11 +24,11 @@
24import os24import os
25import urllib.error25import urllib.error
26import urllib.request26import urllib.request
27from pathlib import Path
2728
28from openlp.core.api.http import requires_auth29from openlp.core.api.http import requires_auth
29from openlp.core.api.http.endpoint import Endpoint30from openlp.core.api.http.endpoint import Endpoint
30from openlp.core.common.applocation import AppLocation31from openlp.core.common.applocation import AppLocation
31from openlp.core.common.path import Path
32from openlp.core.common.registry import Registry32from openlp.core.common.registry import Registry
33from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
34from openlp.core.lib import create_thumb34from openlp.core.lib import create_thumb
3535
=== modified file 'openlp/core/app.py'
--- openlp/core/app.py 2019-05-04 09:13:29 +0000
+++ openlp/core/app.py 2019-05-23 20:08:25 +0000
@@ -32,6 +32,8 @@
32import time32import time
33import os33import os
34from datetime import datetime34from datetime import datetime
35from pathlib import Path
36from shutil import copytree
35from traceback import format_exception37from traceback import format_exception
3638
37from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets # noqa39from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets # noqa
@@ -41,7 +43,7 @@
41from openlp.core.common.applocation import AppLocation43from openlp.core.common.applocation import AppLocation
42from openlp.core.loader import loader44from openlp.core.loader import loader
43from openlp.core.common.i18n import LanguageManager, UiStrings, translate45from openlp.core.common.i18n import LanguageManager, UiStrings, translate
44from openlp.core.common.path import copytree, create_paths, Path46from openlp.core.common.path import create_paths
45from openlp.core.common.registry import Registry47from openlp.core.common.registry import Registry
46from openlp.core.common.settings import Settings48from openlp.core.common.settings import Settings
47from openlp.core.display.screens import ScreenList49from openlp.core.display.screens import ScreenList
@@ -316,7 +318,7 @@
316 """318 """
317 Setup our logging using log_path319 Setup our logging using log_path
318320
319 :param openlp.core.common.path.Path log_path: The file to save the log to.321 :param Path log_path: The file to save the log to.
320 :rtype: None322 :rtype: None
321 """323 """
322 create_paths(log_path, do_not_log=True)324 create_paths(log_path, do_not_log=True)
323325
=== modified file 'openlp/core/common/__init__.py'
--- openlp/core/common/__init__.py 2019-05-04 11:49:20 +0000
+++ openlp/core/common/__init__.py 2019-05-23 20:08:25 +0000
@@ -142,7 +142,7 @@
142 """142 """
143 Convert a path to a module name (i.e openlp.core.common)143 Convert a path to a module name (i.e openlp.core.common)
144144
145 :param openlp.core.common.path.Path path: The path to convert to a module name.145 :param pathlib.Path path: The path to convert to a module name.
146 :return: The module name.146 :return: The module name.
147 :rtype: str147 :rtype: str
148 """148 """
@@ -371,7 +371,7 @@
371 """371 """
372 Deletes a file from the system.372 Deletes a file from the system.
373373
374 :param openlp.core.common.path.Path file_path: The file, including path, to delete.374 :param pathlib.Path file_path: The file, including path, to delete.
375 :return: True if the deletion was successful, or the file never existed. False otherwise.375 :return: True if the deletion was successful, or the file never existed. False otherwise.
376 :rtype: bool376 :rtype: bool
377 """377 """
@@ -407,7 +407,7 @@
407 """407 """
408 Validate that the file is not an image file.408 Validate that the file is not an image file.
409409
410 :param openlp.core.common.path.Path file_path: The file to be checked.410 :param pathlib.Path file_path: The file to be checked.
411 :return: If the file is not an image411 :return: If the file is not an image
412 :rtype: bool412 :rtype: bool
413 """413 """
@@ -435,7 +435,7 @@
435 """435 """
436 Function that checks whether a binary exists.436 Function that checks whether a binary exists.
437437
438 :param openlp.core.common.path.Path program_path: The full path to the binary to check.438 :param pathlib.Path program_path: The full path to the binary to check.
439 :return: program output to be parsed439 :return: program output to be parsed
440 :rtype: bytes440 :rtype: bytes
441 """441 """
@@ -462,7 +462,7 @@
462 """462 """
463 Utility function to incrementally detect the file encoding.463 Utility function to incrementally detect the file encoding.
464464
465 :param openlp.core.common.path.Path file_path: Filename for the file to determine the encoding for.465 :param pathlib.Path file_path: Filename for the file to determine the encoding for.
466 :return: The name of the encoding detected466 :return: The name of the encoding detected
467 :rtype: str467 :rtype: str
468 """468 """
469469
=== modified file 'openlp/core/common/applocation.py'
--- openlp/core/common/applocation.py 2019-04-13 13:00:22 +0000
+++ openlp/core/common/applocation.py 2019-05-23 20:08:25 +0000
@@ -25,12 +25,13 @@
25import logging25import logging
26import os26import os
27import sys27import sys
28from pathlib import Path
2829
29import appdirs30import appdirs
3031
31import openlp32import openlp
32from openlp.core.common import get_frozen_path, is_macosx, is_win33from openlp.core.common import get_frozen_path, is_macosx, is_win
33from openlp.core.common.path import Path, create_paths34from openlp.core.common.path import create_paths
34from openlp.core.common.settings import Settings35from openlp.core.common.settings import Settings
3536
3637
@@ -58,7 +59,7 @@
5859
59 :param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*60 :param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*
60 :return: The requested path61 :return: The requested path
61 :rtype: openlp.core.common.path.Path62 :rtype: Path
62 """63 """
63 if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:64 if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:
64 return get_frozen_path(FROZEN_APP_PATH, APP_PATH)65 return get_frozen_path(FROZEN_APP_PATH, APP_PATH)
@@ -75,7 +76,7 @@
75 Return the path OpenLP stores all its data under.76 Return the path OpenLP stores all its data under.
7677
77 :return: The data path to use.78 :return: The data path to use.
78 :rtype: openlp.core.common.path.Path79 :rtype: Path
79 """80 """
80 # Check if we have a different data location.81 # Check if we have a different data location.
81 if Settings().contains('advanced/data path'):82 if Settings().contains('advanced/data path'):
@@ -95,7 +96,7 @@
95 :param str extension: Defaults to ''. The extension to search for. For example::96 :param str extension: Defaults to ''. The extension to search for. For example::
96 '.png'97 '.png'
97 :return: List of files found.98 :return: List of files found.
98 :rtype: list[openlp.core.common.path.Path]99 :rtype: list[Path]
99 """100 """
100 path = AppLocation.get_data_path()101 path = AppLocation.get_data_path()
101 if section:102 if section:
@@ -112,7 +113,7 @@
112 Return the path a particular module stores its data under.113 Return the path a particular module stores its data under.
113114
114 :param str section:115 :param str section:
115 :rtype: openlp.core.common.path.Path116 :rtype: Path
116 """117 """
117 path = AppLocation.get_data_path() / section118 path = AppLocation.get_data_path() / section
118 create_paths(path)119 create_paths(path)
@@ -125,7 +126,7 @@
125126
126 :param dir_type: AppLocation Enum of the requested path type127 :param dir_type: AppLocation Enum of the requested path type
127 :return: The requested path128 :return: The requested path
128 :rtype: openlp.core.common.path.Path129 :rtype: Path
129 """130 """
130 # If running from source, return the language directory from the source directory131 # If running from source, return the language directory from the source directory
131 if dir_type == AppLocation.LanguageDir:132 if dir_type == AppLocation.LanguageDir:
132133
=== modified file 'openlp/core/common/httputils.py'
--- openlp/core/common/httputils.py 2019-04-13 13:00:22 +0000
+++ openlp/core/common/httputils.py 2019-05-23 20:08:25 +0000
@@ -26,6 +26,7 @@
26import logging26import logging
27import sys27import sys
28import time28import time
29from pathlib import Path
29from random import randint30from random import randint
30from tempfile import gettempdir31from tempfile import gettempdir
3132
@@ -33,7 +34,6 @@
33from PyQt5 import QtCore34from PyQt5 import QtCore
3435
35from openlp.core.common import trace_error_handler36from openlp.core.common import trace_error_handler
36from openlp.core.common.path import Path
37from openlp.core.common.registry import Registry37from openlp.core.common.registry import Registry
38from openlp.core.common.settings import ProxyMode, Settings38from openlp.core.common.settings import ProxyMode, Settings
39from openlp.core.threading import ThreadWorker39from openlp.core.threading import ThreadWorker
4040
=== modified file 'openlp/core/common/json.py'
--- openlp/core/common/json.py 2019-04-13 13:00:22 +0000
+++ openlp/core/common/json.py 2019-05-23 20:08:25 +0000
@@ -19,14 +19,76 @@
19# You should have received a copy of the GNU General Public License #19# You should have received a copy of the GNU General Public License #
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22from contextlib import suppress
22from json import JSONDecoder, JSONEncoder23from json import JSONDecoder, JSONEncoder
2324from pathlib import Path
24from openlp.core.common.path import Path25
2526
2627_registered_classes = {}
27class OpenLPJsonDecoder(JSONDecoder):28
28 """29
29 Implement a custom JSONDecoder to handle Path objects30class JSONMixin(object):
31 """
32 :class:`JSONMixin` is a mixin class to simplify the serialization of a subclass to JSON.
33
34 :cvar:`_json_keys` is used to specify the attributes of the subclass that you wish to serialize.
35 :vartype _json_keys: list[str]
36 :cvar:`_name` set to override the the subclass name, useful if using a `proxy` class
37 :vartype _name: str
38 """
39 _json_keys = []
40 _name = None
41 _version = 1
42
43 def __init_subclass__(cls, register_names=None, **kwargs):
44 """
45 Register the subclass.
46
47 :param collections.Iterable[str] register_names: Alternative names to register instead of the class name
48 :param kwargs: Other args to pass to the super method
49 :return None:
50 """
51 super().__init_subclass__(**kwargs)
52 for key in register_names or [cls.__name__]:
53 _registered_classes[key] = cls
54
55 @classmethod
56 def encode_json(cls, obj, **kwargs):
57 """
58 Create a instance of the subclass from the dictionary that has been constructed by the JSON representation.
59 Only use the keys specified in :cvar:`_json_keys`.
60
61 :param dict[str] obj: The dictionary representation of the subclass (deserailized from the JSON)
62 :param kwargs: Contains any extra parameters. Not used!
63 :return: The desrialized object
64 """
65 return cls(**{key: obj[key] for key in cls._json_keys if obj.get(key) is not None})
66
67 @classmethod
68 def attach_meta(cls, j_dict):
69 """
70 Attach meta data to the serialized dictionary.
71
72 :param dict[str] j_dict: The dictionary to update with the meta data
73 :return None:
74 """
75 j_dict.update({'json_meta': {'class': cls._name or cls.__name__, 'version': cls._version}})
76
77 def json_object(self, **kwargs):
78 """
79 Create a dictionary that can be JSON decoded.
80
81 :param kwargs: Contains any extra parameters. Not used!
82 :return dict[str]: The dictionary representation of this Path object.
83 """
84 j_dict = {key: self.__dict__[key] for key in self._json_keys if self.__dict__.get(key) is not None}
85 self.attach_meta(j_dict)
86 return j_dict
87
88
89class OpenLPJSONDecoder(JSONDecoder):
90 """
91 Implement a custom JSONDecoder to extend compatibility to custom objects
3092
31 Example Usage:93 Example Usage:
32 object = json.loads(json_string, cls=OpenLPJsonDecoder)94 object = json.loads(json_string, cls=OpenLPJsonDecoder)
@@ -45,23 +107,26 @@
45107
46 def custom_object_hook(self, obj):108 def custom_object_hook(self, obj):
47 """109 """
48 Implement a custom Path object decoder.110 Implement a custom object decoder.
49111
50 :param dict obj: A decoded JSON object112 :param dict obj: A decoded JSON object
51 :return: The original object literal, or a Path object if the object literal contains a key '__Path__'113 :return: The custom object from the serialized data if the custom object is registered, else obj
52 :rtype: dict | openlp.core.common.path.Path
53 """114 """
54 if '__Path__' in obj:115 try:
55 obj = Path.encode_json(obj, **self.kwargs)116 key = obj['json_meta']['class']
117 except KeyError:
118 return obj
119 if key in _registered_classes:
120 return _registered_classes[key].encode_json(obj, **self.kwargs)
56 return obj121 return obj
57122
58123
59class OpenLPJsonEncoder(JSONEncoder):124class OpenLPJSONEncoder(JSONEncoder):
60 """125 """
61 Implement a custom JSONEncoder to handle Path objects126 Implement a custom JSONEncoder to handle to extend compatibility to custom objects
62127
63 Example Usage:128 Example Usage:
64 json_string = json.dumps(object, cls=OpenLPJsonEncoder)129 json_string = json.dumps(object, cls=OpenLPJSONEncoder)
65 """130 """
66 def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,131 def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
67 indent=None, separators=None, default=None, **kwargs):132 indent=None, separators=None, default=None, **kwargs):
@@ -78,12 +143,57 @@
78143
79 def custom_default(self, obj):144 def custom_default(self, obj):
80 """145 """
81 Convert any Path objects into a dictionary object which can be serialized.146 Convert any registered objects into a dictionary object which can be serialized.
82147
83 :param object obj: The object to convert148 :param object obj: The object to convert
84 :return: The serializable object149 :return dict: The serializable object
85 :rtype: dict
86 """150 """
87 if isinstance(obj, Path):151 if isinstance(obj, JSONMixin):
88 return obj.json_object(**self.kwargs)152 return obj.json_object()
153 elif obj.__class__.__name__ in _registered_classes:
154 return _registered_classes[obj.__class__.__name__].json_object(obj)
89 return super().default(obj)155 return super().default(obj)
156
157
158def is_serializable(obj):
159 return obj.__class__.__name__ in _registered_classes
160
161
162class PathSerializer(JSONMixin, register_names=('Path', 'PosixPath', 'WindowsPath')):
163 """
164 Implement a de/serializer for pathlib.Path objects
165 """
166 _name = 'Path'
167
168 @staticmethod
169 def encode_json(obj, base_path=None, **kwargs):
170 """
171 Reimplement encode_json to create a Path object from a dictionary representation.
172
173 :param dict[str] obj: The dictionary representation
174 :param Path base_path: If specified, an absolute path to base the relative path off of.
175 :param kwargs: Contains any extra parameters. Not used!
176 :return Path: The deserialized Path object
177 """
178 path = Path(*obj['parts'])
179 if base_path and not path.is_absolute():
180 return base_path / path
181 return path
182
183 @classmethod
184 def json_object(cls, obj, base_path=None, **kwargs):
185 """
186 Create a dictionary that can be JSON decoded.
187
188 :param Path base_path: If specified, an absolute path to make a relative path from.
189 :param kwargs: Contains any extra parameters. Not used!
190 :return: The dictionary representation of this Path object.
191 :rtype: dict[tuple]
192 """
193 path = obj
194 if base_path:
195 with suppress(ValueError):
196 path = path.relative_to(base_path)
197 json_dict = {'parts': path.parts}
198 cls.attach_meta(json_dict)
199 return json_dict
90200
=== modified file 'openlp/core/common/path.py'
--- openlp/core/common/path.py 2019-04-13 13:00:22 +0000
+++ openlp/core/common/path.py 2019-05-23 20:08:25 +0000
@@ -21,66 +21,11 @@
21##########################################################################21##########################################################################
22import logging22import logging
23import shutil23import shutil
24from contextlib import suppress24from pathlib import Path
25
26from openlp.core.common import is_win
27
28
29if is_win():
30 from pathlib import WindowsPath as PathVariant # pragma: nocover
31else:
32 from pathlib import PosixPath as PathVariant # pragma: nocover
3325
34log = logging.getLogger(__name__)26log = logging.getLogger(__name__)
3527
3628
37class Path(PathVariant):
38 """
39 Subclass pathlib.Path, so we can add json conversion methods
40 """
41 @staticmethod
42 def encode_json(obj, base_path=None, **kwargs):
43 """
44 Create a Path object from a dictionary representation. The dictionary has been constructed by JSON encoding of
45 a JSON reprensation of a Path object.
46
47 :param dict[str] obj: The dictionary representation
48 :param openlp.core.common.path.Path base_path: If specified, an absolute path to base the relative path off of.
49 :param kwargs: Contains any extra parameters. Not used!
50 :return: The reconstructed Path object
51 :rtype: openlp.core.common.path.Path
52 """
53 path = Path(*obj['__Path__'])
54 if base_path and not path.is_absolute():
55 return base_path / path
56 return path
57
58 def json_object(self, base_path=None, **kwargs):
59 """
60 Create a dictionary that can be JSON decoded.
61
62 :param openlp.core.common.path.Path base_path: If specified, an absolute path to make a relative path from.
63 :param kwargs: Contains any extra parameters. Not used!
64 :return: The dictionary representation of this Path object.
65 :rtype: dict[tuple]
66 """
67 path = self
68 if base_path:
69 with suppress(ValueError):
70 path = path.relative_to(base_path)
71 return {'__Path__': path.parts}
72
73 def rmtree(self, ignore_errors=False, onerror=None):
74 """
75 Provide an interface to :func:`shutil.rmtree`
76
77 :param bool ignore_errors: Ignore errors
78 :param onerror: Handler function to handle any errors
79 :rtype: None
80 """
81 shutil.rmtree(self, ignore_errors, onerror)
82
83
84def replace_params(args, kwargs, params):29def replace_params(args, kwargs, params):
85 """30 """
86 Apply a transformation function to the specified args or kwargs31 Apply a transformation function to the specified args or kwargs
@@ -110,65 +55,11 @@
110 return tuple(args), kwargs55 return tuple(args), kwargs
11156
11257
113def copy(*args, **kwargs):
114 """
115 Wraps :func:`shutil.copy` so that we can accept Path objects.
116
117 :param src openlp.core.common.path.Path: Takes a Path object which is then converted to a str object
118 :param dst openlp.core.common.path.Path: Takes a Path object which is then converted to a str object
119 :return: Converts the str object received from :func:`shutil.copy` to a Path or NoneType object
120 :rtype: openlp.core.common.path.Path | None
121
122 See the following link for more information on the other parameters:
123 https://docs.python.org/3/library/shutil.html#shutil.copy
124 """
125
126 args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
127
128 return str_to_path(shutil.copy(*args, **kwargs))
129
130
131def copyfile(*args, **kwargs):
132 """
133 Wraps :func:`shutil.copyfile` so that we can accept Path objects.
134
135 :param openlp.core.common.path.Path src: Takes a Path object which is then converted to a str object
136 :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object
137 :return: Converts the str object received from :func:`shutil.copyfile` to a Path or NoneType object
138 :rtype: openlp.core.common.path.Path | None
139
140 See the following link for more information on the other parameters:
141 https://docs.python.org/3/library/shutil.html#shutil.copyfile
142 """
143
144 args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
145
146 return str_to_path(shutil.copyfile(*args, **kwargs))
147
148
149def copytree(*args, **kwargs):
150 """
151 Wraps :func:shutil.copytree` so that we can accept Path objects.
152
153 :param openlp.core.common.path.Path src : Takes a Path object which is then converted to a str object
154 :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object
155 :return: Converts the str object received from :func:`shutil.copytree` to a Path or NoneType object
156 :rtype: openlp.core.common.path.Path | None
157
158 See the following link for more information on the other parameters:
159 https://docs.python.org/3/library/shutil.html#shutil.copytree
160 """
161
162 args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
163
164 return str_to_path(shutil.copytree(*args, **kwargs))
165
166
167def which(*args, **kwargs):58def which(*args, **kwargs):
168 """59 """
169 Wraps :func:shutil.which` so that it return a Path objects.60 Wraps :func:shutil.which` so that it return a Path objects.
17061
171 :rtype: openlp.core.common.Path62 :rtype: Path
17263
173 See the following link for more information on the other parameters:64 See the following link for more information on the other parameters:
174 https://docs.python.org/3/library/shutil.html#shutil.which65 https://docs.python.org/3/library/shutil.html#shutil.which
@@ -183,7 +74,7 @@
183 """74 """
184 A utility function to convert a Path object or NoneType to a string equivalent.75 A utility function to convert a Path object or NoneType to a string equivalent.
18576
186 :param openlp.core.common.path.Path | None path: The value to convert to a string77 :param Path | None path: The value to convert to a string
187 :return: An empty string if :param:`path` is None, else a string representation of the :param:`path`78 :return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
188 :rtype: str79 :rtype: str
189 """80 """
@@ -204,7 +95,7 @@
20495
205 :param str string: The string to convert96 :param str string: The string to convert
206 :return: None if :param:`string` is empty, or a Path object representation of :param:`string`97 :return: None if :param:`string` is empty, or a Path object representation of :param:`string`
207 :rtype: openlp.core.common.path.Path | None98 :rtype: Path | None
208 """99 """
209 if not isinstance(string, str):100 if not isinstance(string, str):
210 log.error('parameter \'string\' must be of type str, got {} which is a {} instead'.format(string, type(string)))101 log.error('parameter \'string\' must be of type str, got {} which is a {} instead'.format(string, type(string)))
@@ -218,7 +109,7 @@
218 """109 """
219 Create one or more paths110 Create one or more paths
220111
221 :param openlp.core.common.path.Path paths: The paths to create112 :param Path paths: The paths to create
222 :param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready.113 :param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready.
223 :rtype: None114 :rtype: None
224 """115 """
@@ -239,7 +130,7 @@
239130
240 :param list[str] file_names: The list of file names to convert.131 :param list[str] file_names: The list of file names to convert.
241 :return: The list converted to file paths132 :return: The list converted to file paths
242 :rtype: openlp.core.common.path.Path133 :rtype: Path
243 """134 """
244 if file_names:135 if file_names:
245 return [str_to_path(file_name) for file_name in file_names]136 return [str_to_path(file_name) for file_name in file_names]
246137
=== modified file 'openlp/core/common/settings.py'
--- openlp/core/common/settings.py 2019-05-04 19:47:06 +0000
+++ openlp/core/common/settings.py 2019-05-23 20:08:25 +0000
@@ -27,13 +27,14 @@
27import logging27import logging
28import os28import os
29from enum import IntEnum29from enum import IntEnum
30from pathlib import Path
30from tempfile import gettempdir31from tempfile import gettempdir
3132
32from PyQt5 import QtCore, QtGui33from PyQt5 import QtCore, QtGui
3334
34from openlp.core.common import SlideLimits, ThemeLevel, is_linux, is_win35from openlp.core.common import SlideLimits, ThemeLevel, is_linux, is_win
35from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder36from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder, is_serializable
36from openlp.core.common.path import Path, files_to_paths, str_to_path37from openlp.core.common.path import files_to_paths, str_to_path
3738
3839
39log = logging.getLogger(__name__)40log = logging.getLogger(__name__)
@@ -337,7 +338,7 @@
337338
338 Does not affect existing Settings objects.339 Does not affect existing Settings objects.
339340
340 :param openlp.core.common.path.Path ini_path: ini file path341 :param Path ini_path: ini file path
341 :rtype: None342 :rtype: None
342 """343 """
343 Settings.__file_path__ = str(ini_path)344 Settings.__file_path__ = str(ini_path)
@@ -584,8 +585,9 @@
584 :param value: The value to save585 :param value: The value to save
585 :rtype: None586 :rtype: None
586 """587 """
587 if isinstance(value, (Path, dict)) or (isinstance(value, list) and value and isinstance(value[0], Path)):588 if is_serializable(value) or isinstance(value, dict) or \
588 value = json.dumps(value, cls=OpenLPJsonEncoder)589 (isinstance(value, list) and value and is_serializable(value[0])):
590 value = json.dumps(value, cls=OpenLPJSONEncoder)
589 super().setValue(key, value)591 super().setValue(key, value)
590592
591 def _convert_value(self, setting, default_value):593 def _convert_value(self, setting, default_value):
@@ -611,8 +613,8 @@
611 elif isinstance(default_value, dict):613 elif isinstance(default_value, dict):
612 return {}614 return {}
613 elif isinstance(setting, str):615 elif isinstance(setting, str):
614 if '__Path__' in setting or setting.startswith('{'):616 if 'json_meta' in setting or setting.startswith('{'):
615 return json.loads(setting, cls=OpenLPJsonDecoder)617 return json.loads(setting, cls=OpenLPJSONDecoder)
616 # Convert the setting to the correct type.618 # Convert the setting to the correct type.
617 if isinstance(default_value, bool):619 if isinstance(default_value, bool):
618 if isinstance(setting, bool):620 if isinstance(setting, bool):
@@ -629,7 +631,7 @@
629 """631 """
630 Export the settings to file.632 Export the settings to file.
631633
632 :param openlp.core.common.path.Path dest_path: The file path to create the export file.634 :param Path dest_path: The file path to create the export file.
633 :return: Success635 :return: Success
634 :rtype: bool636 :rtype: bool
635 """637 """
636638
=== modified file 'openlp/core/display/window.py'
--- openlp/core/display/window.py 2019-05-04 09:13:29 +0000
+++ openlp/core/display/window.py 2019-05-23 20:08:25 +0000
@@ -249,18 +249,18 @@
249 """249 """
250 Set images in the display250 Set images in the display
251 """251 """
252 for image in images:252 imagesr = copy.deepcopy(images)
253 if not image['path'].startswith('file://'):253 for image in imagesr:
254 image['path'] = 'file://' + image['path']254 image['path'] = image['path'].as_uri()
255 json_images = json.dumps(images)255 json_images = json.dumps(imagesr)
256 self.run_javascript('Display.setImageSlides({images});'.format(images=json_images))256 self.run_javascript('Display.setImageSlides({images});'.format(images=json_images))
257257
258 def load_video(self, video):258 def load_video(self, video):
259 """259 """
260 Load video in the display260 Load video in the display
261 """261 """
262 if not video['path'].startswith('file://'):262 video = copy.deepcopy(video)
263 video['path'] = 'file://' + video['path']263 video['path'] = video['path'].as_uri()
264 json_video = json.dumps(video)264 json_video = json.dumps(video)
265 self.run_javascript('Display.setVideo({video});'.format(video=json_video))265 self.run_javascript('Display.setVideo({video});'.format(video=json_video))
266266
267267
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py 2019-04-13 13:00:22 +0000
+++ openlp/core/lib/__init__.py 2019-05-23 20:08:25 +0000
@@ -24,11 +24,11 @@
24OpenLP work.24OpenLP work.
25"""25"""
26import logging26import logging
27from pathlib import Path
2728
28from PyQt5 import QtCore, QtGui, QtWidgets29from PyQt5 import QtCore, QtGui, QtWidgets
2930
30from openlp.core.common.i18n import translate31from openlp.core.common.i18n import translate
31from openlp.core.common.path import Path
3232
33log = logging.getLogger(__name__ + '.__init__')33log = logging.getLogger(__name__ + '.__init__')
3434
@@ -181,7 +181,7 @@
181 returns False. If there is an error loading the file or the content can't be decoded then the function will return181 returns False. If there is an error loading the file or the content can't be decoded then the function will return
182 None.182 None.
183183
184 :param openlp.core.common.path.Path text_file_path: The path to the file.184 :param Path text_file_path: The path to the file.
185 :return: The contents of the file, False if the file does not exist, or None if there is an Error reading or185 :return: The contents of the file, False if the file does not exist, or None if there is an Error reading or
186 decoding the file.186 decoding the file.
187 :rtype: str | False | None187 :rtype: str | False | None
@@ -263,8 +263,8 @@
263 """263 """
264 Create a thumbnail from the given image path and depending on ``return_icon`` it returns an icon from this thumb.264 Create a thumbnail from the given image path and depending on ``return_icon`` it returns an icon from this thumb.
265265
266 :param openlp.core.common.path.Path image_path: The image file to create the icon from.266 :param Path image_path: The image file to create the icon from.
267 :param openlp.core.common.path.Path thumb_path: The filename to save the thumbnail to.267 :param Path thumb_path: The filename to save the thumbnail to.
268 :param return_icon: States if an icon should be build and returned from the thumb. Defaults to ``True``.268 :param return_icon: States if an icon should be build and returned from the thumb. Defaults to ``True``.
269 :param size: Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means that a default269 :param size: Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means that a default
270 height of 88 is used.270 height of 88 is used.
@@ -311,8 +311,8 @@
311 Validates whether an file's thumb still exists and if is up to date. **Note**, you must **not** call this function,311 Validates whether an file's thumb still exists and if is up to date. **Note**, you must **not** call this function,
312 before checking the existence of the file.312 before checking the existence of the file.
313313
314 :param openlp.core.common.path.Path file_path: The path to the file. The file **must** exist!314 :param Path file_path: The path to the file. The file **must** exist!
315 :param openlp.core.common.path.Path thumb_path: The path to the thumb.315 :param Path thumb_path: The path to the thumb.
316 :return: Has the image changed since the thumb was created?316 :return: Has the image changed since the thumb was created?
317 :rtype: bool317 :rtype: bool
318 """318 """
319319
=== modified file 'openlp/core/lib/db.py'
--- openlp/core/lib/db.py 2019-04-13 13:00:22 +0000
+++ openlp/core/lib/db.py 2019-05-23 20:08:25 +0000
@@ -40,7 +40,7 @@
40from openlp.core.common import delete_file40from openlp.core.common import delete_file
41from openlp.core.common.applocation import AppLocation41from openlp.core.common.applocation import AppLocation
42from openlp.core.common.i18n import translate42from openlp.core.common.i18n import translate
43from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder43from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
44from openlp.core.common.settings import Settings44from openlp.core.common.settings import Settings
45from openlp.core.lib.ui import critical_error_message_box45from openlp.core.lib.ui import critical_error_message_box
4646
@@ -132,7 +132,7 @@
132 Create a path to a database from the plugin name and database name132 Create a path to a database from the plugin name and database name
133133
134 :param plugin_name: Name of plugin134 :param plugin_name: Name of plugin
135 :param openlp.core.common.path.Path | str | None db_file_name: File name of database135 :param pathlib.Path | str | None db_file_name: File name of database
136 :return: The path to the database136 :return: The path to the database
137 :rtype: str137 :rtype: str
138 """138 """
@@ -150,7 +150,7 @@
150 Log and report to the user that a database cannot be loaded150 Log and report to the user that a database cannot be loaded
151151
152 :param plugin_name: Name of plugin152 :param plugin_name: Name of plugin
153 :param openlp.core.common.path.Path db_file_path: File name of database153 :param pathlib.Path db_file_path: File name of database
154 :return: None154 :return: None
155 """155 """
156 db_path = get_db_path(plugin_name, db_file_path)156 db_path = get_db_path(plugin_name, db_file_path)
@@ -165,8 +165,8 @@
165 Construct the connection string for a database.165 Construct the connection string for a database.
166166
167 :param plugin_name: The name of the plugin for the database creation.167 :param plugin_name: The name of the plugin for the database creation.
168 :param openlp.core.common.path.Path | str | None db_file_name: The database file name. Defaults to None resulting168 :param pathlib.Path | str | None db_file_name: The database file name. Defaults to None resulting in the plugin_name
169 in the plugin_name being used.169 being used.
170 :return: The database URL170 :return: The database URL
171 :rtype: str171 :rtype: str
172 """172 """
@@ -215,7 +215,7 @@
215 Create a PathType for storing Path objects with SQLAlchemy. Behind the scenes we convert the Path object to a JSON215 Create a PathType for storing Path objects with SQLAlchemy. Behind the scenes we convert the Path object to a JSON
216 representation and store it as a Unicode type216 representation and store it as a Unicode type
217 """217 """
218 impl = types.UnicodeText218 impl = types.Unicode
219219
220 def coerce_compared_value(self, op, value):220 def coerce_compared_value(self, op, value):
221 """221 """
@@ -224,10 +224,8 @@
224224
225 :param op: The operation being carried out. Not used, as we only care about the type that is being used with the225 :param op: The operation being carried out. Not used, as we only care about the type that is being used with the
226 operation.226 operation.
227 :param openlp.core.common.path.Path | str value: The value being used for the comparison. Most likely a Path227 :param pathlib.Path | str value: The value being used for the comparison. Most likely a Path Object or str.
228 Object or str.228 :return PathType | UnicodeText: The coerced value stored in the db
229 :return: The coerced value stored in the db
230 :rtype: PathType or UnicodeText
231 """229 """
232 if isinstance(value, str):230 if isinstance(value, str):
233 return UnicodeText()231 return UnicodeText()
@@ -238,13 +236,12 @@
238 """236 """
239 Convert the Path object to a JSON representation237 Convert the Path object to a JSON representation
240238
241 :param openlp.core.common.path.Path value: The value to convert239 :param pathlib.Path value: The value to convert
242 :param dialect: Not used240 :param dialect: Not used
243 :return: The Path object as a JSON string241 :return str: The Path object as a JSON string
244 :rtype: str
245 """242 """
246 data_path = AppLocation.get_data_path()243 data_path = AppLocation.get_data_path()
247 return json.dumps(value, cls=OpenLPJsonEncoder, base_path=data_path)244 return json.dumps(value, cls=OpenLPJSONEncoder, base_path=data_path)
248245
249 def process_result_value(self, value, dialect):246 def process_result_value(self, value, dialect):
250 """247 """
@@ -253,10 +250,10 @@
253 :param types.UnicodeText value: The value to convert250 :param types.UnicodeText value: The value to convert
254 :param dialect: Not used251 :param dialect: Not used
255 :return: The JSON object converted Python object (in this case it should be a Path object)252 :return: The JSON object converted Python object (in this case it should be a Path object)
256 :rtype: openlp.core.common.path.Path253 :rtype: pathlib.Path
257 """254 """
258 data_path = AppLocation.get_data_path()255 data_path = AppLocation.get_data_path()
259 return json.loads(value, cls=OpenLPJsonDecoder, base_path=data_path)256 return json.loads(value, cls=OpenLPJSONDecoder, base_path=data_path)
260257
261258
262def upgrade_db(url, upgrade):259def upgrade_db(url, upgrade):
@@ -351,8 +348,8 @@
351348
352 :param plugin_name: The name to setup paths and settings section names349 :param plugin_name: The name to setup paths and settings section names
353 :param init_schema: The init_schema function for this database350 :param init_schema: The init_schema function for this database
354 :param openlp.core.common.path.Path db_file_path: The file name to use for this database. Defaults to None351 :param pathlib.Path | None db_file_path: The file name to use for this database. Defaults to None resulting in
355 resulting in the plugin_name being used.352 the plugin_name being used.
356 :param upgrade_mod: The upgrade_schema function for this database353 :param upgrade_mod: The upgrade_schema function for this database
357 """354 """
358 super().__init__()355 super().__init__()
359356
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py 2019-05-04 18:25:59 +0000
+++ openlp/core/lib/mediamanageritem.py 2019-05-23 20:08:25 +0000
@@ -369,7 +369,7 @@
369 Process a list for files either from the File Dialog or from Drag and369 Process a list for files either from the File Dialog or from Drag and
370 Drop370 Drop
371371
372 :param list[openlp.core.common.path.Path] file_paths: The files to be loaded.372 :param list[pathlib.Path] file_paths: The files to be loaded.
373 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files373 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
374 """374 """
375 full_list = []375 full_list = []
@@ -410,7 +410,7 @@
410 """410 """
411 Return the current list of files411 Return the current list of files
412412
413 :rtype: list[openlp.core.common.path.Path]413 :rtype: list[pathlib.Path]
414 """414 """
415 file_paths = []415 file_paths = []
416 for index in range(self.list_view.count()):416 for index in range(self.list_view.count()):
@@ -462,7 +462,7 @@
462 :param item: The database item to be used to build the service item462 :param item: The database item to be used to build the service item
463 :param remote: Was this remote triggered (False)463 :param remote: Was this remote triggered (False)
464 :param context: The service context464 :param context: The service context
465 :param openlp.core.common.path.Path file_path:465 :param pathlib.Path file_path:
466 """466 """
467 raise NotImplementedError('MediaManagerItem.generate_slide_data needs to be defined by the plugin')467 raise NotImplementedError('MediaManagerItem.generate_slide_data needs to be defined by the plugin')
468468
469469
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py 2019-04-13 13:00:22 +0000
+++ openlp/core/lib/serviceitem.py 2019-05-23 20:08:25 +0000
@@ -29,6 +29,7 @@
29import os29import os
30import uuid30import uuid
31from copy import deepcopy31from copy import deepcopy
32from pathlib import Path
3233
33from PyQt5 import QtGui34from PyQt5 import QtGui
3435
@@ -37,7 +38,6 @@
37from openlp.core.common.applocation import AppLocation38from openlp.core.common.applocation import AppLocation
38from openlp.core.common.i18n import translate39from openlp.core.common.i18n import translate
39from openlp.core.common.mixins import RegistryProperties40from openlp.core.common.mixins import RegistryProperties
40from openlp.core.common.path import Path
41from openlp.core.common.settings import Settings41from openlp.core.common.settings import Settings
42from openlp.core.display.render import remove_tags, render_tags42from openlp.core.display.render import remove_tags, render_tags
43from openlp.core.lib import ItemCapabilities43from openlp.core.lib import ItemCapabilities
@@ -264,8 +264,8 @@
264 if image and not self.has_original_files and self.name == 'presentations':264 if image and not self.has_original_files and self.name == 'presentations':
265 file_location = os.path.join(path, file_name)265 file_location = os.path.join(path, file_name)
266 file_location_hash = md5_hash(file_location.encode('utf-8'))266 file_location_hash = md5_hash(file_location.encode('utf-8'))
267 image = os.path.join(str(AppLocation.get_section_data_path(self.name)), 'thumbnails',267 image = os.path.join(AppLocation.get_section_data_path(self.name), 'thumbnails', file_location_hash,
268 file_location_hash, ntpath.basename(image)) # TODO: Pathlib268 ntpath.basename(image)) # TODO: Pathlib
269 self.slides.append({'title': file_name, 'image': image, 'path': path, 'display_title': display_title,269 self.slides.append({'title': file_name, 'image': image, 'path': path, 'display_title': display_title,
270 'notes': notes, 'thumbnail': image})270 'notes': notes, 'thumbnail': image})
271 # if self.is_capable(ItemCapabilities.HasThumbnails):271 # if self.is_capable(ItemCapabilities.HasThumbnails):
272272
=== modified file 'openlp/core/lib/theme.py'
--- openlp/core/lib/theme.py 2019-05-04 09:13:29 +0000
+++ openlp/core/lib/theme.py 2019-05-23 20:08:25 +0000
@@ -29,7 +29,7 @@
2929
30from openlp.core.common import de_hump30from openlp.core.common import de_hump
31from openlp.core.common.applocation import AppLocation31from openlp.core.common.applocation import AppLocation
32from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder32from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
33from openlp.core.display.screens import ScreenList33from openlp.core.display.screens import ScreenList
34from openlp.core.lib import get_text_file_string, str_to_bool34from openlp.core.lib import get_text_file_string, str_to_bool
3535
@@ -190,7 +190,7 @@
190 """190 """
191 Add the path name to the image name so the background can be rendered.191 Add the path name to the image name so the background can be rendered.
192192
193 :param openlp.core.common.path.Path path: The path name to be added.193 :param pathlib.Path path: The path name to be added.
194 :rtype: None194 :rtype: None
195 """195 """
196 if self.background_type == 'image' or self.background_type == 'video':196 if self.background_type == 'image' or self.background_type == 'video':
@@ -216,13 +216,13 @@
216 Convert the JSON file and expand it.216 Convert the JSON file and expand it.
217217
218 :param theme: the theme string218 :param theme: the theme string
219 :param openlp.core.common.path.Path theme_path: The path to the theme219 :param pathlib.Path theme_path: The path to the theme
220 :rtype: None220 :rtype: None
221 """221 """
222 if theme_path:222 if theme_path:
223 jsn = json.loads(theme, cls=OpenLPJsonDecoder, base_path=theme_path)223 jsn = json.loads(theme, cls=OpenLPJSONDecoder, base_path=theme_path)
224 else:224 else:
225 jsn = json.loads(theme, cls=OpenLPJsonDecoder)225 jsn = json.loads(theme, cls=OpenLPJSONDecoder)
226 self.expand_json(jsn)226 self.expand_json(jsn)
227227
228 def export_theme(self, theme_path=None):228 def export_theme(self, theme_path=None):
@@ -234,8 +234,8 @@
234 for attr, value in self.__dict__.items():234 for attr, value in self.__dict__.items():
235 theme_data["{attr}".format(attr=attr)] = value235 theme_data["{attr}".format(attr=attr)] = value
236 if theme_path:236 if theme_path:
237 return json.dumps(theme_data, cls=OpenLPJsonEncoder, base_path=theme_path)237 return json.dumps(theme_data, cls=OpenLPJSONEncoder, base_path=theme_path)
238 return json.dumps(theme_data, cls=OpenLPJsonEncoder)238 return json.dumps(theme_data, cls=OpenLPJSONEncoder)
239239
240 def parse(self, xml):240 def parse(self, xml):
241 """241 """
242242
=== modified file 'openlp/core/server.py'
--- openlp/core/server.py 2019-05-04 09:13:29 +0000
+++ openlp/core/server.py 2019-05-23 20:08:25 +0000
@@ -19,10 +19,11 @@
19# You should have received a copy of the GNU General Public License #19# You should have received a copy of the GNU General Public License #
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22from pathlib import Path
23
22from PyQt5 import QtCore, QtNetwork24from PyQt5 import QtCore, QtNetwork
2325
24from openlp.core.common.mixins import LogMixin26from openlp.core.common.mixins import LogMixin
25from openlp.core.common.path import Path
26from openlp.core.common.registry import Registry27from openlp.core.common.registry import Registry
2728
2829
2930
=== modified file 'openlp/core/ui/advancedtab.py'
--- openlp/core/ui/advancedtab.py 2019-05-03 17:26:37 +0000
+++ openlp/core/ui/advancedtab.py 2019-05-23 20:08:25 +0000
@@ -518,7 +518,7 @@
518 """518 """
519 Handle the `editPathChanged` signal of the data_directory_path_edit519 Handle the `editPathChanged` signal of the data_directory_path_edit
520520
521 :param openlp.core.common.path.Path new_path: The new path521 :param pathlib.Path new_path: The new path
522 :rtype: None522 :rtype: None
523 """523 """
524 # Make sure they want to change the data.524 # Make sure they want to change the data.
@@ -552,7 +552,7 @@
552 """552 """
553 Check if there's already data in the target directory.553 Check if there's already data in the target directory.
554554
555 :param openlp.core.common.path.Path data_path: The target directory to check555 :param pathlib.Path data_path: The target directory to check
556 """556 """
557 if (data_path / 'songs').exists():557 if (data_path / 'songs').exists():
558 self.data_exists = True558 self.data_exists = True
559559
=== modified file 'openlp/core/ui/firsttimeform.py'
--- openlp/core/ui/firsttimeform.py 2019-04-13 13:00:22 +0000
+++ openlp/core/ui/firsttimeform.py 2019-05-23 20:08:25 +0000
@@ -28,6 +28,7 @@
28import urllib.error28import urllib.error
29import urllib.parse29import urllib.parse
30import urllib.request30import urllib.request
31from pathlib import Path
31from tempfile import gettempdir32from tempfile import gettempdir
3233
33from PyQt5 import QtCore, QtWidgets34from PyQt5 import QtCore, QtWidgets
@@ -37,7 +38,7 @@
37from openlp.core.common.httputils import DownloadWorker, download_file, get_url_file_size, get_web_page38from openlp.core.common.httputils import DownloadWorker, download_file, get_url_file_size, get_web_page
38from openlp.core.common.i18n import translate39from openlp.core.common.i18n import translate
39from openlp.core.common.mixins import RegistryProperties40from openlp.core.common.mixins import RegistryProperties
40from openlp.core.common.path import Path, create_paths41from openlp.core.common.path import create_paths
41from openlp.core.common.registry import Registry42from openlp.core.common.registry import Registry
42from openlp.core.common.settings import Settings43from openlp.core.common.settings import Settings
43from openlp.core.lib import build_icon44from openlp.core.lib import build_icon
4445
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py 2019-05-03 17:26:37 +0000
+++ openlp/core/ui/generaltab.py 2019-05-23 20:08:25 +0000
@@ -23,12 +23,12 @@
23The general tab of the configuration dialog.23The general tab of the configuration dialog.
24"""24"""
25import logging25import logging
26from pathlib import Path
2627
27from PyQt5 import QtGui, QtWidgets28from PyQt5 import QtGui, QtWidgets
2829
29from openlp.core.common import get_images_filter30from openlp.core.common import get_images_filter
30from openlp.core.common.i18n import UiStrings, translate31from openlp.core.common.i18n import UiStrings, translate
31from openlp.core.common.path import Path
32from openlp.core.common.settings import Settings32from openlp.core.common.settings import Settings
33from openlp.core.display.screens import ScreenList33from openlp.core.display.screens import ScreenList
34from openlp.core.lib.settingstab import SettingsTab34from openlp.core.lib.settingstab import SettingsTab
3535
=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py 2019-05-04 12:05:53 +0000
+++ openlp/core/ui/mainwindow.py 2019-05-23 20:08:25 +0000
@@ -23,9 +23,11 @@
23This is the main window, where all the action happens.23This is the main window, where all the action happens.
24"""24"""
25import os25import os
26import shutil
26from datetime import datetime27from datetime import datetime
27from distutils import dir_util28from distutils import dir_util
28from distutils.errors import DistutilsFileError29from distutils.errors import DistutilsFileError
30from pathlib import Path
29from tempfile import gettempdir31from tempfile import gettempdir
3032
31from PyQt5 import QtCore, QtGui, QtWidgets33from PyQt5 import QtCore, QtGui, QtWidgets
@@ -38,7 +40,7 @@
38from openlp.core.common.applocation import AppLocation40from openlp.core.common.applocation import AppLocation
39from openlp.core.common.i18n import LanguageManager, UiStrings, translate41from openlp.core.common.i18n import LanguageManager, UiStrings, translate
40from openlp.core.common.mixins import LogMixin, RegistryProperties42from openlp.core.common.mixins import LogMixin, RegistryProperties
41from openlp.core.common.path import Path, copyfile, create_paths43from openlp.core.common.path import create_paths
42from openlp.core.common.registry import Registry44from openlp.core.common.registry import Registry
43from openlp.core.common.settings import Settings45from openlp.core.common.settings import Settings
44from openlp.core.display.screens import ScreenList46from openlp.core.display.screens import ScreenList
@@ -658,7 +660,7 @@
658 plugin.first_time()660 plugin.first_time()
659 self.application.process_events()661 self.application.process_events()
660 temp_path = Path(gettempdir(), 'openlp')662 temp_path = Path(gettempdir(), 'openlp')
661 temp_path.rmtree(True)663 shutil.rmtree(temp_path, True)
662664
663 def on_first_time_wizard_clicked(self):665 def on_first_time_wizard_clicked(self):
664 """666 """
@@ -861,7 +863,7 @@
861 temp_dir_path = Path(gettempdir(), 'openlp')863 temp_dir_path = Path(gettempdir(), 'openlp')
862 create_paths(temp_dir_path)864 create_paths(temp_dir_path)
863 temp_config_path = temp_dir_path / import_file_path.name865 temp_config_path = temp_dir_path / import_file_path.name
864 copyfile(import_file_path, temp_config_path)866 shutil.copyfile(import_file_path, temp_config_path)
865 settings = Settings()867 settings = Settings()
866 import_settings = Settings(str(temp_config_path), Settings.IniFormat)868 import_settings = Settings(str(temp_config_path), Settings.IniFormat)
867869
868870
=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py 2019-05-04 18:25:59 +0000
+++ openlp/core/ui/servicemanager.py 2019-05-23 20:08:25 +0000
@@ -24,10 +24,12 @@
24"""24"""
25import html25import html
26import json26import json
27import shutil
27import os28import os
28import zipfile29import zipfile
29from contextlib import suppress30from contextlib import suppress
30from datetime import datetime, timedelta31from datetime import datetime, timedelta
32from pathlib import Path
31from tempfile import NamedTemporaryFile33from tempfile import NamedTemporaryFile
3234
33from PyQt5 import QtCore, QtGui, QtWidgets35from PyQt5 import QtCore, QtGui, QtWidgets
@@ -36,9 +38,8 @@
36from openlp.core.common.actions import ActionList, CategoryOrder38from openlp.core.common.actions import ActionList, CategoryOrder
37from openlp.core.common.applocation import AppLocation39from openlp.core.common.applocation import AppLocation
38from openlp.core.common.i18n import UiStrings, format_time, translate40from openlp.core.common.i18n import UiStrings, format_time, translate
39from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder41from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
40from openlp.core.common.mixins import LogMixin, RegistryProperties42from openlp.core.common.mixins import LogMixin, RegistryProperties
41from openlp.core.common.path import Path
42from openlp.core.common.registry import Registry, RegistryBase43from openlp.core.common.registry import Registry, RegistryBase
43from openlp.core.common.settings import Settings44from openlp.core.common.settings import Settings
44from openlp.core.lib import build_icon45from openlp.core.lib import build_icon
@@ -371,7 +372,7 @@
371 """372 """
372 Setter for service file.373 Setter for service file.
373374
374 :param openlp.core.common.path.Path file_path: The service file name375 :param Path file_path: The service file name
375 :rtype: None376 :rtype: None
376 """377 """
377 self._service_path = file_path378 self._service_path = file_path
@@ -386,7 +387,7 @@
386 """387 """
387 Return the current file name including path.388 Return the current file name including path.
388389
389 :rtype: openlp.core.common.path.Path390 :rtype: Path
390 """391 """
391 return self._service_path392 return self._service_path
392393
@@ -443,7 +444,7 @@
443 """444 """
444 Loads the service file and saves the existing one it there is one unchanged.445 Loads the service file and saves the existing one it there is one unchanged.
445446
446 :param openlp.core.common.path.Path | None file_path: The service file to the loaded.447 :param Path | None file_path: The service file to the loaded.
447 """448 """
448 if self.is_modified():449 if self.is_modified():
449 result = self.save_modified_service()450 result = self.save_modified_service()
@@ -518,7 +519,7 @@
518 Get a list of files used in the service and files that are missing.519 Get a list of files used in the service and files that are missing.
519520
520 :return: A list of files used in the service that exist, and a list of files that don't.521 :return: A list of files used in the service that exist, and a list of files that don't.
521 :rtype: (list[openlp.core.common.path.Path], list[openlp.core.common.path.Path])522 :rtype: (list[Path], list[Path])
522 """523 """
523 write_list = []524 write_list = []
524 missing_list = []525 missing_list = []
@@ -581,7 +582,7 @@
581 # Add the service item to the service.582 # Add the service item to the service.
582 service.append({'serviceitem': service_item})583 service.append({'serviceitem': service_item})
583 self.repaint_service_list(-1, -1)584 self.repaint_service_list(-1, -1)
584 service_content = json.dumps(service, cls=OpenLPJsonEncoder)585 service_content = json.dumps(service, cls=OpenLPJSONEncoder)
585 service_content_size = len(bytes(service_content, encoding='utf-8'))586 service_content_size = len(bytes(service_content, encoding='utf-8'))
586 total_size = service_content_size587 total_size = service_content_size
587 for file_item in write_list:588 for file_item in write_list:
@@ -679,7 +680,7 @@
679 """680 """
680 Load an existing service file.681 Load an existing service file.
681682
682 :param openlp.core.common.path.Path file_path: The service file to load.683 :param Path file_path: The service file to load.
683 """684 """
684 if not file_path.exists():685 if not file_path.exists():
685 return False686 return False
@@ -702,7 +703,7 @@
702 zip_file.extract(zip_info, self.service_path)703 zip_file.extract(zip_info, self.service_path)
703 self.main_window.increment_progress_bar(zip_info.compress_size)704 self.main_window.increment_progress_bar(zip_info.compress_size)
704 if service_data:705 if service_data:
705 items = json.loads(service_data, cls=OpenLPJsonDecoder)706 items = json.loads(service_data, cls=OpenLPJSONDecoder)
706 self.new_file()707 self.new_file()
707 self.process_service_items(items)708 self.process_service_items(items)
708 self.set_file_name(file_path)709 self.set_file_name(file_path)
@@ -1250,7 +1251,7 @@
1250 delete_file(file_path)1251 delete_file(file_path)
1251 audio_path = self.service_path / 'audio'1252 audio_path = self.service_path / 'audio'
1252 if audio_path.exists():1253 if audio_path.exists():
1253 audio_path.rmtree(True)1254 shutil.rmtree(audio_path, True)
12541255
1255 def on_theme_combo_box_selected(self, current_index):1256 def on_theme_combo_box_selected(self, current_index):
1256 """1257 """
12571258
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2019-05-07 16:56:21 +0000
+++ openlp/core/ui/slidecontroller.py 2019-05-23 20:08:25 +0000
@@ -25,6 +25,7 @@
25import copy25import copy
26import datetime26import datetime
27from collections import deque27from collections import deque
28from pathlib import Path
28from threading import Lock29from threading import Lock
2930
30from PyQt5 import QtCore, QtGui, QtWidgets31from PyQt5 import QtCore, QtGui, QtWidgets
@@ -33,7 +34,6 @@
33from openlp.core.common.actions import ActionList, CategoryOrder34from openlp.core.common.actions import ActionList, CategoryOrder
34from openlp.core.common.i18n import UiStrings, translate35from openlp.core.common.i18n import UiStrings, translate
35from openlp.core.common.mixins import LogMixin, RegistryProperties36from openlp.core.common.mixins import LogMixin, RegistryProperties
36from openlp.core.common.path import Path
37from openlp.core.common.registry import Registry, RegistryBase37from openlp.core.common.registry import Registry, RegistryBase
38from openlp.core.common.settings import Settings38from openlp.core.common.settings import Settings
39from openlp.core.display.screens import ScreenList39from openlp.core.display.screens import ScreenList
4040
=== modified file 'openlp/core/ui/themeform.py'
--- openlp/core/ui/themeform.py 2019-04-13 13:00:22 +0000
+++ openlp/core/ui/themeform.py 2019-05-23 20:08:25 +0000
@@ -462,7 +462,7 @@
462 """462 """
463 Handle the `pathEditChanged` signal from image_path_edit463 Handle the `pathEditChanged` signal from image_path_edit
464464
465 :param openlp.core.common.path.Path new_path: Path to the new image465 :param pathlib.Path new_path: Path to the new image
466 :rtype: None466 :rtype: None
467 """467 """
468 self.theme.background_filename = new_path468 self.theme.background_filename = new_path
@@ -472,7 +472,7 @@
472 """472 """
473 Handle the `pathEditChanged` signal from video_path_edit473 Handle the `pathEditChanged` signal from video_path_edit
474474
475 :param openlp.core.common.path.Path new_path: Path to the new video475 :param pathlib.Path new_path: Path to the new video
476 :rtype: None476 :rtype: None
477 """477 """
478 self.theme.background_filename = new_path478 self.theme.background_filename = new_path
479479
=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py 2019-05-03 17:26:37 +0000
+++ openlp/core/ui/thememanager.py 2019-05-23 20:08:25 +0000
@@ -23,7 +23,9 @@
23The Theme Manager manages adding, deleteing and modifying of themes.23The Theme Manager manages adding, deleteing and modifying of themes.
24"""24"""
25import os25import os
26import shutil
26import zipfile27import zipfile
28from pathlib import Path
27from xml.etree.ElementTree import XML, ElementTree29from xml.etree.ElementTree import XML, ElementTree
2830
29from PyQt5 import QtCore, QtWidgets31from PyQt5 import QtCore, QtWidgets
@@ -32,7 +34,7 @@
32from openlp.core.common.applocation import AppLocation34from openlp.core.common.applocation import AppLocation
33from openlp.core.common.i18n import UiStrings, get_locale_key, translate35from openlp.core.common.i18n import UiStrings, get_locale_key, translate
34from openlp.core.common.mixins import LogMixin, RegistryProperties36from openlp.core.common.mixins import LogMixin, RegistryProperties
35from openlp.core.common.path import Path, copyfile, create_paths37from openlp.core.common.path import create_paths
36from openlp.core.common.registry import Registry, RegistryBase38from openlp.core.common.registry import Registry, RegistryBase
37from openlp.core.common.settings import Settings39from openlp.core.common.settings import Settings
38from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb40from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
@@ -378,7 +380,7 @@
378 delete_file(self.theme_path / thumb)380 delete_file(self.theme_path / thumb)
379 delete_file(self.thumb_path / thumb)381 delete_file(self.thumb_path / thumb)
380 try:382 try:
381 (self.theme_path / theme).rmtree()383 shutil.rmtree(self.theme_path / theme)
382 except OSError:384 except OSError:
383 self.log_exception('Error deleting theme {name}'.format(name=theme))385 self.log_exception('Error deleting theme {name}'.format(name=theme))
384386
@@ -415,7 +417,7 @@
415 """417 """
416 Create the zipfile with the theme contents.418 Create the zipfile with the theme contents.
417419
418 :param openlp.core.common.path.Path theme_path: Location where the zip file will be placed420 :param Path theme_path: Location where the zip file will be placed
419 :param str theme_name: The name of the theme to be exported421 :param str theme_name: The name of the theme to be exported
420 :return: The success of creating the zip file422 :return: The success of creating the zip file
421 :rtype: bool423 :rtype: bool
@@ -433,7 +435,7 @@
433 'The {theme_name} export failed because this error occurred: {err}')435 'The {theme_name} export failed because this error occurred: {err}')
434 .format(theme_name=theme_name, err=ose.strerror))436 .format(theme_name=theme_name, err=ose.strerror))
435 if theme_path.exists():437 if theme_path.exists():
436 theme_path.rmtree(ignore_errors=True)438 shutil.rmtree(theme_path, ignore_errors=True)
437 return False439 return False
438440
439 def on_import_theme(self, checked=None):441 def on_import_theme(self, checked=None):
@@ -557,8 +559,8 @@
557 """559 """
558 Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version560 Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
559 and upgrade if necessary.561 and upgrade if necessary.
560 :param openlp.core.common.path.Path file_path:562 :param Path file_path:
561 :param openlp.core.common.path.Path directory_path:563 :param Path directory_path:
562 """564 """
563 self.log_debug('Unzipping theme {name}'.format(name=file_path))565 self.log_debug('Unzipping theme {name}'.format(name=file_path))
564 file_xml = None566 file_xml = None
@@ -642,8 +644,8 @@
642 Called by theme maintenance Dialog to save the theme and to trigger the reload of the theme list644 Called by theme maintenance Dialog to save the theme and to trigger the reload of the theme list
643645
644 :param Theme theme: The theme data object.646 :param Theme theme: The theme data object.
645 :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.647 :param Path image_source_path: Where the theme image is currently located.
646 :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to648 :param Path image_destination_path: Where the Theme Image is to be saved to
647 :rtype: None649 :rtype: None
648 """650 """
649 self._write_theme(theme, image_source_path, image_destination_path)651 self._write_theme(theme, image_source_path, image_destination_path)
@@ -653,8 +655,8 @@
653 Writes the theme to the disk and handles the background image if necessary655 Writes the theme to the disk and handles the background image if necessary
654656
655 :param Theme theme: The theme data object.657 :param Theme theme: The theme data object.
656 :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.658 :param Path image_source_path: Where the theme image is currently located.
657 :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to659 :param Path image_destination_path: Where the Theme Image is to be saved to
658 :rtype: None660 :rtype: None
659 """661 """
660 name = theme.theme_name662 name = theme.theme_name
@@ -671,7 +673,7 @@
671 delete_file(self.old_background_image_path)673 delete_file(self.old_background_image_path)
672 if image_source_path != image_destination_path:674 if image_source_path != image_destination_path:
673 try:675 try:
674 copyfile(image_source_path, image_destination_path)676 shutil.copyfile(image_source_path, image_destination_path)
675 except OSError:677 except OSError:
676 self.log_exception('Failed to save theme image')678 self.log_exception('Failed to save theme image')
677 self.generate_and_save_image(name, theme)679 self.generate_and_save_image(name, theme)
@@ -718,7 +720,7 @@
718 Return a theme object using information parsed from XML720 Return a theme object using information parsed from XML
719721
720 :param theme_xml: The Theme data object.722 :param theme_xml: The Theme data object.
721 :param openlp.core.common.path.Path image_path: Where the theme image is stored723 :param Path image_path: Where the theme image is stored
722 :return: Theme data.724 :return: Theme data.
723 :rtype: Theme725 :rtype: Theme
724 """726 """
@@ -732,7 +734,7 @@
732 Return a theme object using information parsed from JSON734 Return a theme object using information parsed from JSON
733735
734 :param theme_json: The Theme data object.736 :param theme_json: The Theme data object.
735 :param openlp.core.common.path.Path image_path: Where the theme image is stored737 :param Path image_path: Where the theme image is stored
736 :return: Theme data.738 :return: Theme data.
737 :rtype: Theme739 :rtype: Theme
738 """740 """
739741
=== modified file 'openlp/core/widgets/dialogs.py'
--- openlp/core/widgets/dialogs.py 2019-05-04 09:13:29 +0000
+++ openlp/core/widgets/dialogs.py 2019-05-23 20:08:25 +0000
@@ -33,9 +33,9 @@
3333
34 :type parent: QtWidgets.QWidget | None34 :type parent: QtWidgets.QWidget | None
35 :type caption: str35 :type caption: str
36 :type directory: openlp.core.common.path.Path36 :type directory: pathlib.Path
37 :type options: QtWidgets.QFileDialog.Options37 :type options: QtWidgets.QFileDialog.Options
38 :rtype: openlp.core.common.path.Path38 :rtype: pathlib.Path
39 """39 """
40 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))40 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
4141
@@ -52,11 +52,11 @@
5252
53 :type parent: QtWidgets.QWidget | None53 :type parent: QtWidgets.QWidget | None
54 :type caption: str54 :type caption: str
55 :type directory: openlp.core.common.path.Path55 :type directory: pathlib.Path
56 :type filter: str56 :type filter: str
57 :type initialFilter: str57 :type initialFilter: str
58 :type options: QtWidgets.QFileDialog.Options58 :type options: QtWidgets.QFileDialog.Options
59 :rtype: tuple[openlp.core.common.path.Path, str]59 :rtype: tuple[pathlib.Path, str]
60 """60 """
61 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))61 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
6262
@@ -73,11 +73,11 @@
7373
74 :type parent: QtWidgets.QWidget | None74 :type parent: QtWidgets.QWidget | None
75 :type caption: str75 :type caption: str
76 :type directory: openlp.core.common.path.Path76 :type directory: pathlib.Path
77 :type filter: str77 :type filter: str
78 :type initialFilter: str78 :type initialFilter: str
79 :type options: QtWidgets.QFileDialog.Options79 :type options: QtWidgets.QFileDialog.Options
80 :rtype: tuple[list[openlp.core.common.path.Path], str]80 :rtype: tuple[list[pathlib.Path], str]
81 """81 """
82 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))82 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
8383
@@ -95,11 +95,11 @@
9595
96 :type parent: QtWidgets.QWidget | None96 :type parent: QtWidgets.QWidget | None
97 :type caption: str97 :type caption: str
98 :type directory: openlp.core.common.path.Path98 :type directory: pathlib.Path
99 :type filter: str99 :type filter: str
100 :type initialFilter: str100 :type initialFilter: str
101 :type options: QtWidgets.QFileDialog.Options101 :type options: QtWidgets.QFileDialog.Options
102 :rtype: tuple[openlp.core.common.path.Path | None, str]102 :rtype: tuple[pathlib.Path | None, str]
103 """103 """
104 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))104 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
105105
106106
=== modified file 'openlp/core/widgets/edits.py'
--- openlp/core/widgets/edits.py 2019-04-28 19:21:23 +0000
+++ openlp/core/widgets/edits.py 2019-05-23 20:08:25 +0000
@@ -24,12 +24,13 @@
24"""24"""
25import logging25import logging
26import re26import re
27from pathlib import Path
2728
28from PyQt5 import QtCore, QtGui, QtWidgets29from PyQt5 import QtCore, QtGui, QtWidgets
2930
30from openlp.core.common import CONTROL_CHARS31from openlp.core.common import CONTROL_CHARS
31from openlp.core.common.i18n import UiStrings, translate32from openlp.core.common.i18n import UiStrings, translate
32from openlp.core.common.path import Path, path_to_str, str_to_path33from openlp.core.common.path import path_to_str, str_to_path
33from openlp.core.common.settings import Settings34from openlp.core.common.settings import Settings
34from openlp.core.lib.formattingtags import FormattingTags35from openlp.core.lib.formattingtags import FormattingTags
35from openlp.core.lib.ui import create_action, create_widget_action36from openlp.core.lib.ui import create_action, create_widget_action
@@ -207,7 +208,7 @@
207208
208 :param QtWidget.QWidget | None: The parent of the widget. This is just passed to the super method.209 :param QtWidget.QWidget | None: The parent of the widget. This is just passed to the super method.
209 :param str dialog_caption: Used to customise the caption in the QFileDialog.210 :param str dialog_caption: Used to customise the caption in the QFileDialog.
210 :param openlp.core.common.path.Path default_path: The default path. This is set as the path when the revert211 :param Path default_path: The default path. This is set as the path when the revert
211 button is clicked212 button is clicked
212 :param bool show_revert: Used to determine if the 'revert button' should be visible.213 :param bool show_revert: Used to determine if the 'revert button' should be visible.
213 :rtype: None214 :rtype: None
@@ -250,7 +251,7 @@
250 A property getter method to return the selected path.251 A property getter method to return the selected path.
251252
252 :return: The selected path253 :return: The selected path
253 :rtype: openlp.core.common.path.Path254 :rtype: Path
254 """255 """
255 return self._path256 return self._path
256257
@@ -259,7 +260,7 @@
259 """260 """
260 A Property setter method to set the selected path261 A Property setter method to set the selected path
261262
262 :param openlp.core.common.path.Path path: The path to set the widget to263 :param Path path: The path to set the widget to
263 :rtype: None264 :rtype: None
264 """265 """
265 self._path = path266 self._path = path
@@ -348,7 +349,7 @@
348349
349 Emits the pathChanged Signal350 Emits the pathChanged Signal
350351
351 :param openlp.core.common.path.Path path: The new path352 :param Path path: The new path
352 :rtype: None353 :rtype: None
353 """354 """
354 if self._path != path:355 if self._path != path:
355356
=== modified file 'openlp/core/widgets/views.py'
--- openlp/core/widgets/views.py 2019-05-04 09:13:29 +0000
+++ openlp/core/widgets/views.py 2019-05-23 20:08:25 +0000
@@ -23,12 +23,13 @@
23The :mod:`listpreviewwidget` is a widget that lists the slides in the slide controller.23The :mod:`listpreviewwidget` is a widget that lists the slides in the slide controller.
24It is based on a QTableWidget but represents its contents in list form.24It is based on a QTableWidget but represents its contents in list form.
25"""25"""
26from pathlib import Path
27
26from PyQt5 import QtCore, QtGui, QtWidgets28from PyQt5 import QtCore, QtGui, QtWidgets
2729
28from openlp.core.common import is_win30from openlp.core.common import is_win
29from openlp.core.common.i18n import UiStrings31from openlp.core.common.i18n import UiStrings
30from openlp.core.common.mixins import RegistryProperties32from openlp.core.common.mixins import RegistryProperties
31from openlp.core.common.path import Path
32from openlp.core.common.registry import Registry33from openlp.core.common.registry import Registry
33from openlp.core.common.settings import Settings34from openlp.core.common.settings import Settings
34from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem35from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
@@ -41,7 +42,7 @@
4142
42 :param QtCore.QMimeData mime_data: The mime data from the drag and drop opperation.43 :param QtCore.QMimeData mime_data: The mime data from the drag and drop opperation.
43 :return: A list of file paths that were dropped44 :return: A list of file paths that were dropped
44 :rtype: list[openlp.core.common.path.Path]45 :rtype: list[Path]
45 """46 """
46 file_paths = []47 file_paths = []
47 for url in mime_data.urls():48 for url in mime_data.urls():
@@ -201,14 +202,14 @@
201 label.setScaledContents(True)202 label.setScaledContents(True)
202 if self.service_item.is_command():203 if self.service_item.is_command():
203 if self.service_item.is_capable(ItemCapabilities.HasThumbnails):204 if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
204 pixmap = QtGui.QPixmap(remove_url_prefix(slide['thumbnail']))205 pixmap = QtGui.QPixmap(str(slide['thumbnail']))
205 else:206 else:
206 if isinstance(slide['image'], QtGui.QIcon):207 if isinstance(slide['image'], QtGui.QIcon):
207 pixmap = slide['image'].pixmap(QtCore.QSize(32, 32))208 pixmap = slide['image'].pixmap(QtCore.QSize(32, 32))
208 else:209 else:
209 pixmap = QtGui.QPixmap(remove_url_prefix(slide['image']))210 pixmap = QtGui.QPixmap(str(slide['image']))
210 else:211 else:
211 pixmap = QtGui.QPixmap(remove_url_prefix(slide['path']))212 pixmap = QtGui.QPixmap(str(slide['path']))
212 label.setPixmap(pixmap)213 label.setPixmap(pixmap)
213 container = QtWidgets.QWidget()214 container = QtWidgets.QWidget()
214 layout = AspectRatioLayout(container, self.screen_ratio)215 layout = AspectRatioLayout(container, self.screen_ratio)
215216
=== modified file 'openlp/plugins/bibles/lib/bibleimport.py'
--- openlp/plugins/bibles/lib/bibleimport.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/bibles/lib/bibleimport.py 2019-05-23 20:08:25 +0000
@@ -48,7 +48,7 @@
48 """48 """
49 Check if the supplied file is compressed49 Check if the supplied file is compressed
5050
51 :param openlp.core.common.path.Path file_path: A path to the file to check51 :param pathlib.Path file_path: A path to the file to check
52 """52 """
53 if is_zipfile(file_path):53 if is_zipfile(file_path):
54 critical_error_message_box(54 critical_error_message_box(
5555
=== modified file 'openlp/plugins/bibles/lib/db.py'
--- openlp/plugins/bibles/lib/db.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/bibles/lib/db.py 2019-05-23 20:08:25 +0000
@@ -24,6 +24,7 @@
24import re24import re
25import sqlite325import sqlite3
26import time26import time
27from pathlib import Path
2728
28import chardet29import chardet
29from PyQt5 import QtCore30from PyQt5 import QtCore
@@ -35,7 +36,6 @@
35from openlp.core.common import clean_filename36from openlp.core.common import clean_filename
36from openlp.core.common.applocation import AppLocation37from openlp.core.common.applocation import AppLocation
37from openlp.core.common.i18n import translate38from openlp.core.common.i18n import translate
38from openlp.core.common.path import Path
39from openlp.core.lib.db import BaseModel, Manager, init_db39from openlp.core.lib.db import BaseModel, Manager, init_db
40from openlp.core.lib.ui import critical_error_message_box40from openlp.core.lib.ui import critical_error_message_box
41from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection, upgrade41from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection, upgrade
@@ -130,13 +130,13 @@
130 :param parent:130 :param parent:
131 :param kwargs:131 :param kwargs:
132 ``path``132 ``path``
133 The path to the bible database file. Type: openlp.core.common.path.Path133 The path to the bible database file. Type: Path
134134
135 ``name``135 ``name``
136 The name of the database. This is also used as the file name for SQLite databases.136 The name of the database. This is also used as the file name for SQLite databases.
137137
138 ``file``138 ``file``
139 Type: openlp.core.common.path.Path139 Type: Path
140140
141 :rtype: None141 :rtype: None
142 """142 """
143143
=== modified file 'openlp/plugins/bibles/lib/importers/csvbible.py'
--- openlp/plugins/bibles/lib/importers/csvbible.py 2019-05-04 09:13:29 +0000
+++ openlp/plugins/bibles/lib/importers/csvbible.py 2019-05-23 20:08:25 +0000
@@ -96,7 +96,7 @@
96 """96 """
97 Parse the supplied CSV file.97 Parse the supplied CSV file.
9898
99 :param openlp.core.common.path.Path file_path: The name of the file to parse.99 :param pathlib.Path file_path: The name of the file to parse.
100 :param namedtuple results_tuple: The namedtuple to use to store the results.100 :param namedtuple results_tuple: The namedtuple to use to store the results.
101 :return: An list of namedtuples of type results_tuple101 :return: An list of namedtuples of type results_tuple
102 :rtype: list[namedtuple]102 :rtype: list[namedtuple]
103103
=== modified file 'openlp/plugins/bibles/lib/importers/wordproject.py'
--- openlp/plugins/bibles/lib/importers/wordproject.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/bibles/lib/importers/wordproject.py 2019-05-23 20:08:25 +0000
@@ -21,12 +21,12 @@
21##########################################################################21##########################################################################
22import logging22import logging
23import re23import re
24from pathlib import Path
24from tempfile import TemporaryDirectory25from tempfile import TemporaryDirectory
25from zipfile import ZipFile26from zipfile import ZipFile
2627
27from bs4 import BeautifulSoup, NavigableString, Tag28from bs4 import BeautifulSoup, NavigableString, Tag
2829
29from openlp.core.common.path import Path
30from openlp.plugins.bibles.lib.bibleimport import BibleImport30from openlp.plugins.bibles.lib.bibleimport import BibleImport
3131
3232
3333
=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py 2019-04-28 19:21:23 +0000
+++ openlp/plugins/bibles/lib/manager.py 2019-05-23 20:08:25 +0000
@@ -20,12 +20,12 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import logging22import logging
23from pathlib import Path
2324
24from openlp.core.common import delete_file25from openlp.core.common import delete_file
25from openlp.core.common.applocation import AppLocation26from openlp.core.common.applocation import AppLocation
26from openlp.core.common.i18n import UiStrings, translate27from openlp.core.common.i18n import UiStrings, translate
27from openlp.core.common.mixins import LogMixin, RegistryProperties28from openlp.core.common.mixins import LogMixin, RegistryProperties
28from openlp.core.common.path import Path
29from openlp.core.common.settings import Settings29from openlp.core.common.settings import Settings
30from openlp.plugins.bibles.lib import LanguageSelection, parse_reference30from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
31from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta31from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
3232
=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py 2019-05-04 09:13:29 +0000
+++ openlp/plugins/images/lib/mediaitem.py 2019-05-23 20:08:25 +0000
@@ -21,13 +21,14 @@
21##########################################################################21##########################################################################
2222
23import logging23import logging
24from pathlib import Path
2425
25from PyQt5 import QtCore, QtGui, QtWidgets26from PyQt5 import QtCore, QtGui, QtWidgets
2627
27from openlp.core.common import delete_file, get_images_filter28from openlp.core.common import delete_file, get_images_filter
28from openlp.core.common.applocation import AppLocation29from openlp.core.common.applocation import AppLocation
29from openlp.core.common.i18n import UiStrings, get_natural_key, translate30from openlp.core.common.i18n import UiStrings, get_natural_key, translate
30from openlp.core.common.path import Path, create_paths31from openlp.core.common.path import create_paths
31from openlp.core.common.registry import Registry32from openlp.core.common.registry import Registry
32from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
33from openlp.core.lib import ServiceItemContext, build_icon, check_item_selected, create_thumb, validate_thumb34from openlp.core.lib import ServiceItemContext, build_icon, check_item_selected, create_thumb, validate_thumb
@@ -343,7 +344,7 @@
343344
344 :param openlp.plugins.images.lib.db.ImageFilenames image: The image to generate the thumbnail path for.345 :param openlp.plugins.images.lib.db.ImageFilenames image: The image to generate the thumbnail path for.
345 :return: A path to the thumbnail346 :return: A path to the thumbnail
346 :rtype: openlp.core.common.path.Path347 :rtype: Path
347 """348 """
348 ext = image.file_path.suffix.lower()349 ext = image.file_path.suffix.lower()
349 return self.service_path / '{name:d}{ext}'.format(name=image.id, ext=ext)350 return self.service_path / '{name:d}{ext}'.format(name=image.id, ext=ext)
@@ -401,7 +402,7 @@
401 Process a list for files either from the File Dialog or from Drag and Drop.402 Process a list for files either from the File Dialog or from Drag and Drop.
402 This method is overloaded from MediaManagerItem.403 This method is overloaded from MediaManagerItem.
403404
404 :param list[openlp.core.common.path.Path] file_paths: A List of paths to be loaded405 :param list[Path] file_paths: A List of paths to be loaded
405 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files406 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
406 """407 """
407 self.application.set_normal_cursor()408 self.application.set_normal_cursor()
@@ -413,7 +414,7 @@
413 """414 """
414 Add new images to the database. This method is called when adding images using the Add button or DnD.415 Add new images to the database. This method is called when adding images using the Add button or DnD.
415416
416 :param list[openlp.core.common.Path] image_paths: A list of file paths to the images to be loaded417 :param list[Path] image_paths: A list of file paths to the images to be loaded
417 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files418 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
418 :param initial_load: When set to False, the busy cursor and progressbar will be shown while loading images419 :param initial_load: When set to False, the busy cursor and progressbar will be shown while loading images
419 """420 """
@@ -610,7 +611,7 @@
610 for image in images:611 for image in images:
611 name = image.file_path.name612 name = image.file_path.name
612 thumbnail_path = self.generate_thumbnail_path(image)613 thumbnail_path = self.generate_thumbnail_path(image)
613 service_item.add_from_image(str(image.file_path), name, background, str(thumbnail_path))614 service_item.add_from_image(image.file_path, name, background, str(thumbnail_path))
614 return True615 return True
615616
616 def check_group_exists(self, new_group):617 def check_group_exists(self, new_group):
617618
=== modified file 'openlp/plugins/images/lib/upgrade.py'
--- openlp/plugins/images/lib/upgrade.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/images/lib/upgrade.py 2019-05-23 20:08:25 +0000
@@ -24,13 +24,13 @@
24"""24"""
25import json25import json
26import logging26import logging
27from pathlib import Path
2728
28from sqlalchemy import Column, Table29from sqlalchemy import Column, Table
2930
30from openlp.core.common.applocation import AppLocation31from openlp.core.common.applocation import AppLocation
31from openlp.core.common.db import drop_columns32from openlp.core.common.db import drop_columns
32from openlp.core.common.json import OpenLPJsonEncoder33from openlp.core.common.json import OpenLPJSONEncoder
33from openlp.core.common.path import Path
34from openlp.core.lib.db import PathType, get_upgrade_op34from openlp.core.lib.db import PathType, get_upgrade_op
3535
3636
@@ -58,7 +58,7 @@
58 results = conn.execute('SELECT * FROM image_filenames')58 results = conn.execute('SELECT * FROM image_filenames')
59 data_path = AppLocation.get_data_path()59 data_path = AppLocation.get_data_path()
60 for row in results.fetchall():60 for row in results.fetchall():
61 file_path_json = json.dumps(Path(row.filename), cls=OpenLPJsonEncoder, base_path=data_path)61 file_path_json = json.dumps(Path(row.filename), cls=OpenLPJSONEncoder, base_path=data_path)
62 sql = 'UPDATE image_filenames SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(62 sql = 'UPDATE image_filenames SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(
63 file_path_json=file_path_json, id=row.id)63 file_path_json=file_path_json, id=row.id)
64 conn.execute(sql)64 conn.execute(sql)
6565
=== modified file 'openlp/plugins/media/forms/mediaclipselectorform.py'
--- openlp/plugins/media/forms/mediaclipselectorform.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/media/forms/mediaclipselectorform.py 2019-05-23 20:08:25 +0000
@@ -23,6 +23,7 @@
23import os23import os
24import re24import re
25from datetime import datetime25from datetime import datetime
26from pathlib import Path
26from time import sleep27from time import sleep
2728
28from PyQt5 import QtCore, QtWidgets29from PyQt5 import QtCore, QtWidgets
@@ -30,7 +31,6 @@
30from openlp.core.common import is_linux, is_macosx, is_win31from openlp.core.common import is_linux, is_macosx, is_win
31from openlp.core.common.i18n import translate32from openlp.core.common.i18n import translate
32from openlp.core.common.mixins import RegistryProperties33from openlp.core.common.mixins import RegistryProperties
33from openlp.core.common.path import Path
34from openlp.core.lib.ui import critical_error_message_box34from openlp.core.lib.ui import critical_error_message_box
35from openlp.core.ui.icons import UiIcons35from openlp.core.ui.icons import UiIcons
36from openlp.core.ui.media.vlcplayer import get_vlc36from openlp.core.ui.media.vlcplayer import get_vlc
3737
=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
--- openlp/plugins/presentations/lib/impresscontroller.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/presentations/lib/impresscontroller.py 2019-05-23 20:08:25 +0000
@@ -205,7 +205,7 @@
205 """205 """
206 Constructor, store information about the file and initialise.206 Constructor, store information about the file and initialise.
207207
208 :param openlp.core.common.path.Path document_path: File path for the document to load208 :param pathlib.Path document_path: File path for the document to load
209 :rtype: None209 :rtype: None
210 """210 """
211 log.debug('Init Presentation OpenOffice')211 log.debug('Init Presentation OpenOffice')
212212
=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py 2019-05-04 11:49:20 +0000
+++ openlp/plugins/presentations/lib/mediaitem.py 2019-05-23 20:08:25 +0000
@@ -156,7 +156,7 @@
156 Add presentations into the media manager. This is called both on initial load of the plugin to populate with156 Add presentations into the media manager. This is called both on initial load of the plugin to populate with
157 existing files, and when the user adds new files via the media manager.157 existing files, and when the user adds new files via the media manager.
158158
159 :param list[openlp.core.common.path.Path] file_paths: List of file paths to add to the media manager.159 :param list[pathlib.Path] file_paths: List of file paths to add to the media manager.
160 """160 """
161 current_paths = self.get_file_list()161 current_paths = self.get_file_list()
162 titles = [file_path.name for file_path in current_paths]162 titles = [file_path.name for file_path in current_paths]
@@ -241,7 +241,7 @@
241 """241 """
242 Clean up the files created such as thumbnails242 Clean up the files created such as thumbnails
243243
244 :param openlp.core.common.path.Path file_path: File path of the presentation to clean up after244 :param pathlib.Path file_path: File path of the presentation to clean up after
245 :param bool clean_for_update: Only clean thumbnails if update is needed245 :param bool clean_for_update: Only clean thumbnails if update is needed
246 :rtype: None246 :rtype: None
247 """247 """
@@ -385,7 +385,7 @@
385 set as the preferred controller. Find the first (alphabetic) enabled controller which "supports" the extension.385 set as the preferred controller. Find the first (alphabetic) enabled controller which "supports" the extension.
386 If none found, then look for a controller which "also supports" it instead.386 If none found, then look for a controller which "also supports" it instead.
387387
388 :param openlp.core.common.path.Path file_path: The file path388 :param pathlib.Path file_path: The file path
389 :return: The default application controller for this file type, or None if not supported389 :return: The default application controller for this file type, or None if not supported
390 :rtype: PresentationController390 :rtype: PresentationController
391 """391 """
392392
=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
--- openlp/plugins/presentations/lib/messagelistener.py 2019-05-02 17:11:55 +0000
+++ openlp/plugins/presentations/lib/messagelistener.py 2019-05-23 20:08:25 +0000
@@ -21,10 +21,10 @@
21##########################################################################21##########################################################################
22import copy22import copy
23import logging23import logging
24from pathlib import Path
2425
25from PyQt5 import QtCore26from PyQt5 import QtCore
2627
27from openlp.core.common.path import Path
28from openlp.core.common.registry import Registry28from openlp.core.common.registry import Registry
29from openlp.core.common.settings import Settings29from openlp.core.common.settings import Settings
30from openlp.core.lib import ServiceItemContext30from openlp.core.lib import ServiceItemContext
3131
=== modified file 'openlp/plugins/presentations/lib/pdfcontroller.py'
--- openlp/plugins/presentations/lib/pdfcontroller.py 2019-05-02 13:45:07 +0000
+++ openlp/plugins/presentations/lib/pdfcontroller.py 2019-05-23 20:08:25 +0000
@@ -21,11 +21,11 @@
21##########################################################################21##########################################################################
22import logging22import logging
23import re23import re
24from shutil import which
24from subprocess import CalledProcessError, check_output25from subprocess import CalledProcessError, check_output
2526
26from openlp.core.common import check_binary_exists, is_win27from openlp.core.common import check_binary_exists, is_win
27from openlp.core.common.applocation import AppLocation28from openlp.core.common.applocation import AppLocation
28from openlp.core.common.path import which
29from openlp.core.common.settings import Settings29from openlp.core.common.settings import Settings
30from openlp.core.display.screens import ScreenList30from openlp.core.display.screens import ScreenList
31from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument31from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
@@ -71,7 +71,7 @@
71 Function that checks whether a binary is either ghostscript or mudraw or neither.71 Function that checks whether a binary is either ghostscript or mudraw or neither.
72 Is also used from presentationtab.py72 Is also used from presentationtab.py
7373
74 :param openlp.core.common.path.Path program_path: The full path to the binary to check.74 :param pathlib.Path program_path: The full path to the binary to check.
75 :return: Type of the binary, 'gs' if ghostscript, 'mudraw' if mudraw, None if invalid.75 :return: Type of the binary, 'gs' if ghostscript, 'mudraw' if mudraw, None if invalid.
76 :rtype: str | None76 :rtype: str | None
77 """77 """
@@ -182,7 +182,7 @@
182 """182 """
183 Constructor, store information about the file and initialise.183 Constructor, store information about the file and initialise.
184184
185 :param openlp.core.common.path.Path document_path: Path to the document to load185 :param pathlib.Path document_path: Path to the document to load
186 :rtype: None186 :rtype: None
187 """187 """
188 log.debug('Init Presentation Pdf')188 log.debug('Init Presentation Pdf')
189189
=== modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
--- openlp/plugins/presentations/lib/powerpointcontroller.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/presentations/lib/powerpointcontroller.py 2019-05-23 20:08:25 +0000
@@ -124,7 +124,7 @@
124 Constructor, store information about the file and initialise.124 Constructor, store information about the file and initialise.
125125
126 :param controller:126 :param controller:
127 :param openlp.core.common.path.Path document_path: Path to the document to load127 :param pathlib.Path document_path: Path to the document to load
128 :rtype: None128 :rtype: None
129 """129 """
130 log.debug('Init Presentation Powerpoint')130 log.debug('Init Presentation Powerpoint')
131131
=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
--- openlp/plugins/presentations/lib/presentationcontroller.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/presentations/lib/presentationcontroller.py 2019-05-23 20:08:25 +0000
@@ -20,12 +20,14 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import logging22import logging
23import shutil
24from pathlib import Path
2325
24from PyQt5 import QtCore26from PyQt5 import QtCore
2527
26from openlp.core.common import md5_hash28from openlp.core.common import md5_hash
27from openlp.core.common.applocation import AppLocation29from openlp.core.common.applocation import AppLocation
28from openlp.core.common.path import Path, create_paths30from openlp.core.common.path import create_paths
29from openlp.core.common.registry import Registry31from openlp.core.common.registry import Registry
30from openlp.core.common.settings import Settings32from openlp.core.common.settings import Settings
31from openlp.core.lib import create_thumb, validate_thumb33from openlp.core.lib import create_thumb, validate_thumb
@@ -92,7 +94,7 @@
92 Constructor for the PresentationController class94 Constructor for the PresentationController class
9395
94 :param controller:96 :param controller:
95 :param openlp.core.common.path.Path document_path: Path to the document to load.97 :param Path document_path: Path to the document to load.
96 :rtype: None98 :rtype: None
97 """99 """
98 self.controller = controller100 self.controller = controller
@@ -102,7 +104,7 @@
102 """104 """
103 Run some initial setup. This method is separate from __init__ in order to mock it out in tests.105 Run some initial setup. This method is separate from __init__ in order to mock it out in tests.
104106
105 :param openlp.core.common.path.Path document_path: Path to the document to load.107 :param Path document_path: Path to the document to load.
106 :rtype: None108 :rtype: None
107 """109 """
108 self.slide_number = 0110 self.slide_number = 0
@@ -129,7 +131,7 @@
129 if thumbnail_folder_path.exists():131 if thumbnail_folder_path.exists():
130 thumbnail_folder_path.rmtree()132 thumbnail_folder_path.rmtree()
131 if temp_folder_path.exists():133 if temp_folder_path.exists():
132 temp_folder_path.rmtree()134 shutil.rmtree(temp_folder_path)
133 except OSError:135 except OSError:
134 log.exception('Failed to delete presentation controller files')136 log.exception('Failed to delete presentation controller files')
135137
@@ -138,7 +140,7 @@
138 The location where thumbnail images will be stored140 The location where thumbnail images will be stored
139141
140 :return: The path to the thumbnail142 :return: The path to the thumbnail
141 :rtype: openlp.core.common.path.Path143 :rtype: Path
142 """144 """
143 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in145 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in
144 # get_temp_folder and PresentationPluginapp_startup is removed146 # get_temp_folder and PresentationPluginapp_startup is removed
@@ -153,7 +155,7 @@
153 The location where thumbnail images will be stored155 The location where thumbnail images will be stored
154156
155 :return: The path to the temporary file folder157 :return: The path to the temporary file folder
156 :rtype: openlp.core.common.path.Path158 :rtype: Path
157 """159 """
158 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in160 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in
159 # get_thumbnail_folder and PresentationPluginapp_startup is removed161 # get_thumbnail_folder and PresentationPluginapp_startup is removed
@@ -260,7 +262,7 @@
260 """262 """
261 Convert the slide image the application made to a scaled 360px height .png image.263 Convert the slide image the application made to a scaled 360px height .png image.
262264
263 :param openlp.core.common.path.Path image_path: Path to the image to create a thumb nail of265 :param Path image_path: Path to the image to create a thumbnail of
264 :param int index: The index of the slide to create the thumbnail for.266 :param int index: The index of the slide to create the thumbnail for.
265 :rtype: None267 :rtype: None
266 """268 """
@@ -277,7 +279,7 @@
277 :param int slide_no: The slide an image is required for, starting at 1279 :param int slide_no: The slide an image is required for, starting at 1
278 :param bool check_exists: Check if the generated path exists280 :param bool check_exists: Check if the generated path exists
279 :return: The path, or None if the :param:`check_exists` is True and the file does not exist281 :return: The path, or None if the :param:`check_exists` is True and the file does not exist
280 :rtype: openlp.core.common.path.Path | None282 :rtype: Path | None
281 """283 """
282 path = self.get_thumbnail_folder() / (self.controller.thumbnail_prefix + str(slide_no) + '.png')284 path = self.get_thumbnail_folder() / (self.controller.thumbnail_prefix + str(slide_no) + '.png')
283 if path.is_file() or not check_exists:285 if path.is_file() or not check_exists:
@@ -473,7 +475,7 @@
473 """475 """
474 Called when a new presentation document is opened.476 Called when a new presentation document is opened.
475477
476 :param openlp.core.common.path.Path document_path: Path to the document to load478 :param Path document_path: Path to the document to load
477 :return: The document479 :return: The document
478 :rtype: PresentationDocument480 :rtype: PresentationDocument
479 """481 """
480482
=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
--- openlp/plugins/presentations/lib/presentationtab.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/presentations/lib/presentationtab.py 2019-05-23 20:08:25 +0000
@@ -221,7 +221,7 @@
221 """221 """
222 Handle the `pathEditChanged` signal from program_path_edit222 Handle the `pathEditChanged` signal from program_path_edit
223223
224 :param openlp.core.common.path.Path new_path: File path to the new program224 :param pathlib.Path new_path: File path to the new program
225 :rtype: None225 :rtype: None
226 """226 """
227 if new_path:227 if new_path:
228228
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2019-05-23 20:08:25 +0000
@@ -25,13 +25,14 @@
25"""25"""
26import logging26import logging
27import re27import re
28from shutil import copyfile
2829
29from PyQt5 import QtCore, QtWidgets30from PyQt5 import QtCore, QtWidgets
3031
31from openlp.core.common.applocation import AppLocation32from openlp.core.common.applocation import AppLocation
32from openlp.core.common.i18n import UiStrings, get_natural_key, translate33from openlp.core.common.i18n import UiStrings, get_natural_key, translate
33from openlp.core.common.mixins import RegistryProperties34from openlp.core.common.mixins import RegistryProperties
34from openlp.core.common.path import copyfile, create_paths35from openlp.core.common.path import create_paths
35from openlp.core.common.registry import Registry36from openlp.core.common.registry import Registry
36from openlp.core.lib import MediaType, create_separated_list37from openlp.core.lib import MediaType, create_separated_list
37from openlp.core.lib.plugin import PluginStatus38from openlp.core.lib.plugin import PluginStatus
3839
=== modified file 'openlp/plugins/songs/forms/mediafilesform.py'
--- openlp/plugins/songs/forms/mediafilesform.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/forms/mediafilesform.py 2019-05-23 20:08:25 +0000
@@ -43,7 +43,7 @@
4343
44 def populate_files(self, file_paths):44 def populate_files(self, file_paths):
45 """45 """
46 :param list[openlp.core.common.path.Path] file_paths:46 :param list[pathlib.Path] file_paths:
47 :return:47 :return:
48 """48 """
49 self.file_list_widget.clear()49 self.file_list_widget.clear()
@@ -54,6 +54,6 @@
5454
55 def get_selected_files(self):55 def get_selected_files(self):
56 """56 """
57 :rtype: list[openlp.core.common.path.Path]57 :rtype: list[pathlib.Path]
58 """58 """
59 return [item.data(QtCore.Qt.UserRole) for item in self.file_list_widget.selectedItems()]59 return [item.data(QtCore.Qt.UserRole) for item in self.file_list_widget.selectedItems()]
6060
=== modified file 'openlp/plugins/songs/lib/importers/easyworship.py'
--- openlp/plugins/songs/lib/importers/easyworship.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/easyworship.py 2019-05-23 20:08:25 +0000
@@ -28,9 +28,9 @@
28import sqlite328import sqlite3
29import struct29import struct
30import zlib30import zlib
31from pathlib import Path
3132
32from openlp.core.common.i18n import translate33from openlp.core.common.i18n import translate
33from openlp.core.common.path import Path
34from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf34from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf
3535
36from .songimport import SongImport36from .songimport import SongImport
3737
=== modified file 'openlp/plugins/songs/lib/importers/powersong.py'
--- openlp/plugins/songs/lib/importers/powersong.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/powersong.py 2019-05-23 20:08:25 +0000
@@ -24,9 +24,9 @@
24PowerSong songs into the OpenLP database.24PowerSong songs into the OpenLP database.
25"""25"""
26import logging26import logging
27from pathlib import Path
2728
28from openlp.core.common.i18n import translate29from openlp.core.common.i18n import translate
29from openlp.core.common.path import Path
30from openlp.plugins.songs.lib.importers.songimport import SongImport30from openlp.plugins.songs.lib.importers.songimport import SongImport
3131
3232
@@ -73,7 +73,7 @@
73 * is a directory73 * is a directory
74 * contains at least one * .song file74 * contains at least one * .song file
7575
76 :param openlp.core.common.path.Path import_source: Should be a Path object that fulfills the above criteria76 :param Path import_source: Should be a Path object that fulfills the above criteria
77 :return: If the source is valid77 :return: If the source is valid
78 :rtype: bool78 :rtype: bool
79 """79 """
8080
=== modified file 'openlp/plugins/songs/lib/importers/presentationmanager.py'
--- openlp/plugins/songs/lib/importers/presentationmanager.py 2019-05-04 09:13:29 +0000
+++ openlp/plugins/songs/lib/importers/presentationmanager.py 2019-05-23 20:08:25 +0000
@@ -78,7 +78,7 @@
78 def process_song(self, root, file_path):78 def process_song(self, root, file_path):
79 """79 """
80 :param root:80 :param root:
81 :param openlp.core.common.path.Path file_path: Path to the file to process81 :param pathlib.Path file_path: Path to the file to process
82 :rtype: None82 :rtype: None
83 """83 """
84 self.set_defaults()84 self.set_defaults()
8585
=== modified file 'openlp/plugins/songs/lib/importers/propresenter.py'
--- openlp/plugins/songs/lib/importers/propresenter.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/propresenter.py 2019-05-23 20:08:25 +0000
@@ -55,7 +55,7 @@
55 def process_song(self, root, file_path):55 def process_song(self, root, file_path):
56 """56 """
57 :param root:57 :param root:
58 :param openlp.core.common.path.Path file_path: Path to the file thats being imported58 :param pathlib.Path file_path: Path to the file thats being imported
59 :rtype: None59 :rtype: None
60 """60 """
61 self.set_defaults()61 self.set_defaults()
6262
=== modified file 'openlp/plugins/songs/lib/importers/songbeamer.py'
--- openlp/plugins/songs/lib/importers/songbeamer.py 2019-05-04 09:13:29 +0000
+++ openlp/plugins/songs/lib/importers/songbeamer.py 2019-05-23 20:08:25 +0000
@@ -27,9 +27,9 @@
27import math27import math
28import os28import os
29import re29import re
30from pathlib import Path
3031
31from openlp.core.common import get_file_encoding, is_macosx, is_win32from openlp.core.common import get_file_encoding, is_macosx, is_win
32from openlp.core.common.path import Path
33from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
34from openlp.plugins.songs.lib import VerseType34from openlp.plugins.songs.lib import VerseType
35from openlp.plugins.songs.lib.importers.songimport import SongImport35from openlp.plugins.songs.lib.importers.songimport import SongImport
3636
=== modified file 'openlp/plugins/songs/lib/importers/songimport.py'
--- openlp/plugins/songs/lib/importers/songimport.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/songimport.py 2019-05-23 20:08:25 +0000
@@ -22,13 +22,14 @@
2222
23import logging23import logging
24import re24import re
25from shutil import copyfile
2526
26from PyQt5 import QtCore27from PyQt5 import QtCore
2728
28from openlp.core.common import normalize_str29from openlp.core.common import normalize_str
29from openlp.core.common.applocation import AppLocation30from openlp.core.common.applocation import AppLocation
30from openlp.core.common.i18n import translate31from openlp.core.common.i18n import translate
31from openlp.core.common.path import copyfile, create_paths32from openlp.core.common.path import create_paths
32from openlp.core.common.registry import Registry33from openlp.core.common.registry import Registry
33from openlp.core.widgets.wizard import WizardStrings34from openlp.core.widgets.wizard import WizardStrings
34from openlp.plugins.songs.lib import VerseType, clean_song35from openlp.plugins.songs.lib import VerseType, clean_song
@@ -401,9 +402,9 @@
401 the new file location.402 the new file location.
402403
403 :param song_id:404 :param song_id:
404 :param openlp.core.common.path.Path file_path: The file to copy.405 :param pathlib.Path file_path: The file to copy.
405 :return: The new location of the file406 :return: The new location of the file
406 :rtype: openlp.core.common.path.Path407 :rtype: pathlib.Path
407 """408 """
408 if not hasattr(self, 'save_path'):409 if not hasattr(self, 'save_path'):
409 self.save_path = AppLocation.get_section_data_path(self.import_wizard.plugin.name) / 'audio' / str(song_id)410 self.save_path = AppLocation.get_section_data_path(self.import_wizard.plugin.name) / 'audio' / str(song_id)
410411
=== modified file 'openlp/plugins/songs/lib/importers/songpro.py'
--- openlp/plugins/songs/lib/importers/songpro.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/songpro.py 2019-05-23 20:08:25 +0000
@@ -24,8 +24,8 @@
24songs into the OpenLP database.24songs into the OpenLP database.
25"""25"""
26import re26import re
27from pathlib import Path
2728
28from openlp.core.common.path import Path
29from openlp.plugins.songs.lib import strip_rtf29from openlp.plugins.songs.lib import strip_rtf
30from openlp.plugins.songs.lib.importers.songimport import SongImport30from openlp.plugins.songs.lib.importers.songimport import SongImport
3131
3232
=== modified file 'openlp/plugins/songs/lib/importers/sundayplus.py'
--- openlp/plugins/songs/lib/importers/sundayplus.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/sundayplus.py 2019-05-23 20:08:25 +0000
@@ -65,7 +65,7 @@
65 """65 """
66 Process the Sunday Plus song file66 Process the Sunday Plus song file
6767
68 :param openlp.core.common.path.Path file_path: The song file to import68 :param pathlib.Path file_path: The song file to import
69 :rtype: None69 :rtype: None
70 """70 """
71 with file_path.open('rb') as song_file:71 with file_path.open('rb') as song_file:
@@ -180,7 +180,7 @@
180 """180 """
181 Extract the title from the filename181 Extract the title from the filename
182182
183 :param openlp.core.common.path.Path file_path: File being imported183 :param pathlib.Path file_path: File being imported
184 :return: The song title184 :return: The song title
185 :rtype: str185 :rtype: str
186 """186 """
187187
=== modified file 'openlp/plugins/songs/lib/importers/videopsalm.py'
--- openlp/plugins/songs/lib/importers/videopsalm.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/importers/videopsalm.py 2019-05-23 20:08:25 +0000
@@ -25,9 +25,9 @@
25import json25import json
26import logging26import logging
27import re27import re
28from pathlib import Path
2829
29from openlp.core.common.i18n import translate30from openlp.core.common.i18n import translate
30from openlp.core.common.path import Path
31from openlp.core.common.settings import Settings31from openlp.core.common.settings import Settings
32from openlp.plugins.songs.lib.db import AuthorType32from openlp.plugins.songs.lib.db import AuthorType
33from openlp.plugins.songs.lib.importers.songimport import SongImport33from openlp.plugins.songs.lib.importers.songimport import SongImport
3434
=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/mediaitem.py 2019-05-23 20:08:25 +0000
@@ -20,8 +20,9 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import logging22import logging
23import mako
23import os24import os
24import mako25from shutil import copyfile
2526
26from PyQt5 import QtCore, QtWidgets27from PyQt5 import QtCore, QtWidgets
27from sqlalchemy.sql import and_, or_28from sqlalchemy.sql import and_, or_
@@ -29,7 +30,7 @@
29from openlp.core.state import State30from openlp.core.state import State
30from openlp.core.common.applocation import AppLocation31from openlp.core.common.applocation import AppLocation
31from openlp.core.common.i18n import UiStrings, get_natural_key, translate32from openlp.core.common.i18n import UiStrings, get_natural_key, translate
32from openlp.core.common.path import copyfile, create_paths33from openlp.core.common.path import create_paths
33from openlp.core.common.registry import Registry34from openlp.core.common.registry import Registry
34from openlp.core.common.settings import Settings35from openlp.core.common.settings import Settings
35from openlp.core.lib import ServiceItemContext, check_item_selected, create_separated_list36from openlp.core.lib import ServiceItemContext, check_item_selected, create_separated_list
3637
=== modified file 'openlp/plugins/songs/lib/openlyricsexport.py'
--- openlp/plugins/songs/lib/openlyricsexport.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/openlyricsexport.py 2019-05-23 20:08:25 +0000
@@ -45,7 +45,7 @@
45 """45 """
46 Initialise the export.46 Initialise the export.
4747
48 :param openlp.core.common.path.Path save_path: The directory to save the exported songs in48 :param pathlib.Path save_path: The directory to save the exported songs in
49 :rtype: None49 :rtype: None
50 """50 """
51 log.debug('initialise OpenLyricsExport')51 log.debug('initialise OpenLyricsExport')
5252
=== modified file 'openlp/plugins/songs/lib/upgrade.py'
--- openlp/plugins/songs/lib/upgrade.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/lib/upgrade.py 2019-05-23 20:08:25 +0000
@@ -25,14 +25,14 @@
25"""25"""
26import json26import json
27import logging27import logging
28from pathlib import Path
2829
29from sqlalchemy import Column, ForeignKey, Table, types30from sqlalchemy import Column, ForeignKey, Table, types
30from sqlalchemy.sql.expression import false, func, null, text31from sqlalchemy.sql.expression import false, func, null, text
3132
32from openlp.core.common.applocation import AppLocation33from openlp.core.common.applocation import AppLocation
33from openlp.core.common.db import drop_columns34from openlp.core.common.db import drop_columns
34from openlp.core.common.json import OpenLPJsonEncoder35from openlp.core.common.json import OpenLPJSONEncoder
35from openlp.core.common.path import Path
36from openlp.core.lib.db import PathType, get_upgrade_op36from openlp.core.lib.db import PathType, get_upgrade_op
3737
3838
@@ -182,7 +182,7 @@
182 results = conn.execute('SELECT * FROM media_files')182 results = conn.execute('SELECT * FROM media_files')
183 data_path = AppLocation.get_data_path()183 data_path = AppLocation.get_data_path()
184 for row in results.fetchall():184 for row in results.fetchall():
185 file_path_json = json.dumps(Path(row.file_name), cls=OpenLPJsonEncoder, base_path=data_path)185 file_path_json = json.dumps(Path(row.file_name), cls=OpenLPJSONEncoder, base_path=data_path)
186 sql = 'UPDATE media_files SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(186 sql = 'UPDATE media_files SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(
187 file_path_json=file_path_json, id=row.id)187 file_path_json=file_path_json, id=row.id)
188 conn.execute(sql)188 conn.execute(sql)
189189
=== modified file 'openlp/plugins/songs/reporting.py'
--- openlp/plugins/songs/reporting.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/reporting.py 2019-05-23 20:08:25 +0000
@@ -24,9 +24,9 @@
24"""24"""
25import csv25import csv
26import logging26import logging
27from pathlib import Path
2728
28from openlp.core.common.i18n import translate29from openlp.core.common.i18n import translate
29from openlp.core.common.path import Path
30from openlp.core.common.registry import Registry30from openlp.core.common.registry import Registry
31from openlp.core.lib.ui import critical_error_message_box31from openlp.core.lib.ui import critical_error_message_box
32from openlp.core.widgets.dialogs import FileDialog32from openlp.core.widgets.dialogs import FileDialog
3333
=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songs/songsplugin.py 2019-05-23 20:08:25 +0000
@@ -432,7 +432,7 @@
432 """432 """
433 Provide a count of the songs in the database433 Provide a count of the songs in the database
434434
435 :param openlp.core.common.path.Path db_path: The database to use435 :param Path db_path: The database to use
436 :return: The number of songs in the db.436 :return: The number of songs in the db.
437 :rtype: int437 :rtype: int
438 """438 """
439439
=== modified file 'openlp/plugins/songusage/forms/songusagedetailform.py'
--- openlp/plugins/songusage/forms/songusagedetailform.py 2019-04-13 13:00:22 +0000
+++ openlp/plugins/songusage/forms/songusagedetailform.py 2019-05-23 20:08:25 +0000
@@ -70,7 +70,7 @@
70 """70 """
71 Handle the `pathEditChanged` signal from report_path_edit71 Handle the `pathEditChanged` signal from report_path_edit
7272
73 :param openlp.core.common.path.Path file_path: The new path.73 :param pathlib.Path file_path: The new path.
74 :rtype: None74 :rtype: None
75 """75 """
76 Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)76 Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)
7777
=== modified file 'tests/functional/openlp_core/api/test_deploy.py'
--- tests/functional/openlp_core/api/test_deploy.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/api/test_deploy.py 2019-05-23 20:08:25 +0000
@@ -20,12 +20,13 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import os22import os
23import shutil
24from pathlib import Path
23from tempfile import mkdtemp25from tempfile import mkdtemp
24from unittest import TestCase26from unittest import TestCase
25from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2628
27from openlp.core.api.deploy import deploy_zipfile, download_and_check, download_sha25629from openlp.core.api.deploy import deploy_zipfile, download_and_check, download_sha256
28from openlp.core.common.path import Path
2930
3031
31CONFIG_FILE = '2c266badff1e3d140664c50fd1460a2b332b24d5ad8c267fa62e506b5eb6d894 deploy/site.zip\n2017_06_27'32CONFIG_FILE = '2c266badff1e3d140664c50fd1460a2b332b24d5ad8c267fa62e506b5eb6d894 deploy/site.zip\n2017_06_27'
@@ -46,7 +47,7 @@
46 """47 """
47 Clean up after tests48 Clean up after tests
48 """49 """
49 self.app_root_path.rmtree()50 shutil.rmtree(self.app_root_path)
5051
51 @patch('openlp.core.api.deploy.ZipFile')52 @patch('openlp.core.api.deploy.ZipFile')
52 def test_deploy_zipfile(self, MockZipFile):53 def test_deploy_zipfile(self, MockZipFile):
5354
=== modified file 'tests/functional/openlp_core/common/test_applocation.py'
--- tests/functional/openlp_core/common/test_applocation.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/common/test_applocation.py 2019-05-23 20:08:25 +0000
@@ -23,11 +23,11 @@
23Functional tests to test the AppLocation class and related methods.23Functional tests to test the AppLocation class and related methods.
24"""24"""
25import os25import os
26from pathlib import Path
26from unittest.mock import patch27from unittest.mock import patch
2728
28from openlp.core.common import get_frozen_path29from openlp.core.common import get_frozen_path
29from openlp.core.common.applocation import AppLocation30from openlp.core.common.applocation import AppLocation
30from openlp.core.common.path import Path
3131
3232
33FILE_LIST = ['file1', 'file2', 'file3.txt', 'file4.txt', 'file5.mp3', 'file6.mp3']33FILE_LIST = ['file1', 'file2', 'file3.txt', 'file4.txt', 'file5.mp3', 'file6.mp3']
3434
=== modified file 'tests/functional/openlp_core/common/test_common.py'
--- tests/functional/openlp_core/common/test_common.py 2019-05-04 12:05:53 +0000
+++ tests/functional/openlp_core/common/test_common.py 2019-05-23 20:08:25 +0000
@@ -22,12 +22,12 @@
22"""22"""
23Functional tests to test the AppLocation class and related methods.23Functional tests to test the AppLocation class and related methods.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, call, patch27from unittest.mock import MagicMock, call, patch
2728
28from openlp.core.common import clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \29from openlp.core.common import clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
29 normalize_str, path_to_module, trace_error_handler30 normalize_str, path_to_module, trace_error_handler
30from openlp.core.common.path import Path
3131
3232
33class TestCommonFunctions(TestCase):33class TestCommonFunctions(TestCase):
3434
=== modified file 'tests/functional/openlp_core/common/test_httputils.py'
--- tests/functional/openlp_core/common/test_httputils.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/common/test_httputils.py 2019-05-23 20:08:25 +0000
@@ -24,12 +24,12 @@
24"""24"""
25import os25import os
26import tempfile26import tempfile
27from pathlib import Path
27from unittest import TestCase28from unittest import TestCase
28from unittest.mock import MagicMock, patch29from unittest.mock import MagicMock, patch
2930
30from openlp.core.common.httputils import ProxyMode, download_file, get_proxy_settings, get_url_file_size, \31from openlp.core.common.httputils import ProxyMode, download_file, get_proxy_settings, get_url_file_size, \
31 get_user_agent, get_web_page32 get_user_agent, get_web_page
32from openlp.core.common.path import Path
33from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
34from tests.helpers.testmixin import TestMixin34from tests.helpers.testmixin import TestMixin
3535
3636
=== modified file 'tests/functional/openlp_core/common/test_init.py'
--- tests/functional/openlp_core/common/test_init.py 2019-05-04 09:13:29 +0000
+++ tests/functional/openlp_core/common/test_init.py 2019-05-23 20:08:25 +0000
@@ -23,12 +23,12 @@
23Functional tests to test the AppLocation class and related methods.23Functional tests to test the AppLocation class and related methods.
24"""24"""
25from io import BytesIO25from io import BytesIO
26from pathlib import Path
26from unittest import TestCase27from unittest import TestCase
27from unittest.mock import MagicMock, PropertyMock, call, patch28from unittest.mock import MagicMock, PropertyMock, call, patch
2829
29from openlp.core.common import add_actions, clean_filename, delete_file, get_file_encoding, get_filesystem_encoding, \30from openlp.core.common import add_actions, clean_filename, delete_file, get_file_encoding, get_filesystem_encoding, \
30 get_uno_command, get_uno_instance31 get_uno_command, get_uno_instance
31from openlp.core.common.path import Path
32from tests.helpers.testmixin import TestMixin32from tests.helpers.testmixin import TestMixin
3333
3434
3535
=== modified file 'tests/functional/openlp_core/common/test_json.py'
--- tests/functional/openlp_core/common/test_json.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/common/test_json.py 2019-05-23 20:08:25 +0000
@@ -23,14 +23,134 @@
23Package to test the openlp.core.common.json package.23Package to test the openlp.core.common.json package.
24"""24"""
25import json25import json
26import os
27from pathlib import Path
26from unittest import TestCase28from unittest import TestCase
27from unittest.mock import patch29from unittest.mock import patch
2830
29from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder31from openlp.core.common.json import JSONMixin, OpenLPJSONDecoder, OpenLPJSONEncoder, PathSerializer, _registered_classes
30from openlp.core.common.path import Path32
3133
3234class TestClassBase(object):
33class TestOpenLPJsonDecoder(TestCase):35 """
36 Simple class to avoid repetition
37 """
38 def __init__(self, a=None, b=None, c=None):
39 self.a = a
40 self.b = b
41 self.c = c
42
43
44class TestJSONMixin(TestCase):
45 """
46 Test the JSONMixin class
47 """
48 def setUp(self):
49 self._registered_classes_patcher = patch.dict(_registered_classes, clear=True)
50 self.addCleanup(self._registered_classes_patcher.stop)
51 self._registered_classes_patcher.start()
52
53 def test_subclass_json_mixin(self):
54 """
55 Test that a class is `registered` when subclassing JSONMixin
56 """
57 # GIVEN: The JSONMixin class
58 # WHEN: Subclassing it
59 class TestClass(JSONMixin):
60 pass
61
62 # THEN: The TestClass should have been `registered`
63 assert _registered_classes['TestClass'] == TestClass
64
65 def test_subclass_json_mixin_alt_names(self):
66 """
67 Test that a class is `registered` using the specified names when subclassing JSONMixin
68 """
69 # GIVEN: The JSONMixin class
70 # WHEN: Subclassing it with custom names
71 class TestClass(JSONMixin, register_names=('AltName1', 'AltName2')):
72 pass
73
74 # THEN: The TestClass should have been registered with only those names
75 assert 'TestClass' not in _registered_classes
76 assert _registered_classes['AltName1'] == TestClass
77 assert _registered_classes['AltName2'] == TestClass
78
79 def test_encoding_json_mixin_subclass(self):
80 """
81 Test that an instance of a JSONMixin subclass is properly serialized to a JSON string
82 """
83 # GIVEN: A instance of a subclass of the JSONMixin class
84 class TestClass(TestClassBase, JSONMixin):
85 _json_keys = ['a', 'b']
86
87 instance = TestClass(a=1, c=2)
88
89 # WHEN: Serializing the instance
90 json_string = json.dumps(instance, cls=OpenLPJSONEncoder)
91
92 # THEN: Only the attributes specified by `_json_keys` should be serialized, and only if they have been set
93 assert json_string == '{"a": 1, "json_meta": {"class": "TestClass", "version": 1}}'
94
95 def test_decoding_json_mixin_subclass(self):
96 """
97 Test that an instance of a JSONMixin subclass is properly deserialized from a JSON string
98 """
99 # GIVEN: A subclass of the JSONMixin class
100 class TestClass(TestClassBase, JSONMixin):
101 _json_keys = ['a', 'b']
102
103 # WHEN: Deserializing a JSON representation of the TestClass
104 instance = json.loads(
105 '{"a": 1, "c": 2, "json_meta": {"class": "TestClass", "version": 1}}', cls=OpenLPJSONDecoder)
106
107 # THEN: Only the attributes specified by `_json_keys` should have been set
108 assert instance.__class__ == TestClass
109 assert instance.a == 1
110 assert instance.b is None
111 assert instance.c is None
112
113 def test_encoding_json_mixin_subclass_custom_name(self):
114 """
115 Test that an instance of a JSONMixin subclass is properly serialized to a JSON string when using a custom name
116 """
117 # GIVEN: A instance of a subclass of the JSONMixin class with a custom name
118 class TestClass(TestClassBase, JSONMixin, register_names=('AltName', )):
119 _json_keys = ['a', 'b']
120 _name = 'AltName'
121 _version = 2
122
123 instance = TestClass(a=1, c=2)
124
125 # WHEN: Serializing the instance
126 json_string = json.dumps(instance, cls=OpenLPJSONEncoder)
127
128 # THEN: Only the attributes specified by `_json_keys` should be serialized, and only if they have been set
129 assert json_string == '{"a": 1, "json_meta": {"class": "AltName", "version": 2}}'
130
131 def test_decoding_json_mixin_subclass_custom_name(self):
132 """
133 Test that an instance of a JSONMixin subclass is properly deserialized from a JSON string when using a custom
134 name
135 """
136 # GIVEN: A instance of a subclass of the JSONMixin class with a custom name
137 class TestClass(TestClassBase, JSONMixin, register_names=('AltName', )):
138 _json_keys = ['a', 'b']
139 _name = 'AltName'
140 _version = 2
141
142 # WHEN: Deserializing a JSON representation of the TestClass
143 instance = json.loads(
144 '{"a": 1, "c": 2, "json_meta": {"class": "AltName", "version": 2}}', cls=OpenLPJSONDecoder)
145
146 # THEN: Only the attributes specified by `_json_keys` should have been set
147 assert instance.__class__ == TestClass
148 assert instance.a == 1
149 assert instance.b is None
150 assert instance.c is None
151
152
153class TestOpenLPJSONDecoder(TestCase):
34 """154 """
35 Test the OpenLPJsonDecoder class155 Test the OpenLPJsonDecoder class
36 """156 """
@@ -39,10 +159,10 @@
39 Test the object_hook method when called with a decoded Path JSON object159 Test the object_hook method when called with a decoded Path JSON object
40 """160 """
41 # GIVEN: An instance of OpenLPJsonDecoder161 # GIVEN: An instance of OpenLPJsonDecoder
42 instance = OpenLPJsonDecoder()162 instance = OpenLPJSONDecoder()
43163
44 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path164 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
45 result = instance.object_hook({'__Path__': ['test', 'path']})165 result = instance.object_hook({'parts': ['test', 'path'], "json_meta": {"class": "Path", "version": 1}})
46166
47 # THEN: A Path object should be returned167 # THEN: A Path object should be returned
48 assert result == Path('test', 'path')168 assert result == Path('test', 'path')
@@ -52,7 +172,7 @@
52 Test the object_hook method when called with a decoded JSON object172 Test the object_hook method when called with a decoded JSON object
53 """173 """
54 # GIVEN: An instance of OpenLPJsonDecoder174 # GIVEN: An instance of OpenLPJsonDecoder
55 instance = OpenLPJsonDecoder()175 instance = OpenLPJSONDecoder()
56176
57 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path177 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
58 with patch('openlp.core.common.json.Path') as mocked_path:178 with patch('openlp.core.common.json.Path') as mocked_path:
@@ -67,31 +187,32 @@
67 Test the OpenLPJsonDecoder when decoding a JSON string187 Test the OpenLPJsonDecoder when decoding a JSON string
68 """188 """
69 # GIVEN: A JSON encoded string189 # GIVEN: A JSON encoded string
70 json_string = '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'190 json_string = '[{"parts": ["test", "path1"], "json_meta": {"class": "Path", "version": 1}}, ' \
191 '{"parts": ["test", "path2"], "json_meta": {"class": "Path", "version": 1}}]'
71192
72 # WHEN: Decoding the string using the OpenLPJsonDecoder class193 # WHEN: Decoding the string using the OpenLPJsonDecoder class
73 obj = json.loads(json_string, cls=OpenLPJsonDecoder)194 obj = json.loads(json_string, cls=OpenLPJSONDecoder)
74195
75 # THEN: The object returned should be a python version of the JSON string196 # THEN: The object returned should be a python version of the JSON string
76 assert obj == [Path('test', 'path1'), Path('test', 'path2')]197 assert obj == [Path('test', 'path1'), Path('test', 'path2')]
77198
78199
79class TestOpenLPJsonEncoder(TestCase):200class TestOpenLPJSONEncoder(TestCase):
80 """201 """
81 Test the OpenLPJsonEncoder class202 Test the OpenLPJSONEncoder class
82 """203 """
83 def test_default_path_object(self):204 def test_default_path_object(self):
84 """205 """
85 Test the default method when called with a Path object206 Test the default method when called with a Path object
86 """207 """
87 # GIVEN: An instance of OpenLPJsonEncoder208 # GIVEN: An instance of OpenLPJSONEncoder
88 instance = OpenLPJsonEncoder()209 instance = OpenLPJSONEncoder()
89210
90 # WHEN: Calling the default method with a Path object211 # WHEN: Calling the default method with a Path object
91 result = instance.default(Path('test', 'path'))212 result = instance.default(Path('test', 'path'))
92213
93 # THEN: A dictionary object that can be JSON encoded should be returned214 # THEN: A dictionary object that can be JSON encoded should be returned
94 assert result == {'__Path__': ('test', 'path')}215 assert result == {'parts': ('test', 'path'), "json_meta": {"class": "Path", "version": 1}}
95216
96 def test_default_non_path_object(self):217 def test_default_non_path_object(self):
97 """218 """
@@ -99,8 +220,8 @@
99 """220 """
100 with patch('openlp.core.common.json.JSONEncoder.default') as mocked_super_default:221 with patch('openlp.core.common.json.JSONEncoder.default') as mocked_super_default:
101222
102 # GIVEN: An instance of OpenLPJsonEncoder223 # GIVEN: An instance of OpenLPJSONEncoder
103 instance = OpenLPJsonEncoder()224 instance = OpenLPJSONEncoder()
104225
105 # WHEN: Calling the default method with a object other than a Path object226 # WHEN: Calling the default method with a object other than a Path object
106 instance.default('invalid object')227 instance.default('invalid object')
@@ -115,8 +236,65 @@
115 # GIVEN: A list of Path objects236 # GIVEN: A list of Path objects
116 obj = [Path('test', 'path1'), Path('test', 'path2')]237 obj = [Path('test', 'path1'), Path('test', 'path2')]
117238
118 # WHEN: Encoding the object using the OpenLPJsonEncoder class239 # WHEN: Encoding the object using the OpenLPJSONEncoder class
119 json_string = json.dumps(obj, cls=OpenLPJsonEncoder)240 json_string = json.dumps(obj, cls=OpenLPJSONEncoder)
120241
121 # THEN: The JSON string return should be a representation of the object encoded242 # THEN: The JSON string return should be a representation of the object encoded
122 assert json_string == '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'243 assert json_string == '[{"parts": ["test", "path1"], "json_meta": {"class": "Path", "version": 1}}, ' \
244 '{"parts": ["test", "path2"], "json_meta": {"class": "Path", "version": 1}}]'
245
246
247class TestPathSerializer(TestCase):
248
249 def test_path_encode_json(self):
250 """
251 Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
252 from JSON
253 """
254 # GIVEN: A Path object from openlp.core.common.path
255 # WHEN: Calling encode_json, with a dictionary representation
256 path = PathSerializer.encode_json(
257 {'parts': ['path', 'to', 'fi.le'], "json_meta": {"class": "Path", "version": 1}}, extra=1, args=2)
258
259 # THEN: A Path object should have been returned
260 assert path == Path('path', 'to', 'fi.le')
261
262 def test_path_encode_json_base_path(self):
263 """
264 Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
265 from JSON when the base_path arg is supplied.
266 """
267 # GIVEN: A Path object from openlp.core.common.path
268 # WHEN: Calling encode_json, with a dictionary representation
269 path = PathSerializer.encode_json(
270 {'parts': ['path', 'to', 'fi.le'], "json_meta": {"class": "Path", "version": 1}}, base_path=Path('/base'))
271
272 # THEN: A Path object should have been returned with an absolute path
273 assert path == Path('/', 'base', 'path', 'to', 'fi.le')
274
275 def test_path_json_object(self):
276 """
277 Test that `Path.json_object` creates a JSON decode-able object from a Path object
278 """
279 # GIVEN: A Path object from openlp.core.common.path
280 path = Path('/base', 'path', 'to', 'fi.le')
281
282 # WHEN: Calling json_object
283 obj = PathSerializer().json_object(path, extra=1, args=2)
284
285 # THEN: A JSON decodeable object should have been returned.
286 assert obj == {'parts': (os.sep, 'base', 'path', 'to', 'fi.le'), "json_meta": {"class": "Path", "version": 1}}
287
288 def test_path_json_object_base_path(self):
289 """
290 Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
291 base_path
292 """
293 # GIVEN: A Path object from openlp.core.common.path
294 path = Path('/base', 'path', 'to', 'fi.le')
295
296 # WHEN: Calling json_object with a base_path
297 obj = PathSerializer().json_object(path, base_path=Path('/', 'base'))
298
299 # THEN: A JSON decodable object should have been returned.
300 assert obj == {'parts': ('path', 'to', 'fi.le'), "json_meta": {"class": "Path", "version": 1}}
123301
=== modified file 'tests/functional/openlp_core/common/test_path.py'
--- tests/functional/openlp_core/common/test_path.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/common/test_path.py 2019-05-23 20:08:25 +0000
@@ -22,12 +22,13 @@
22"""22"""
23Package to test the openlp.core.common.path package.23Package to test the openlp.core.common.path package.
24"""24"""
25# TODO: fix patches
25import os26import os
27from pathlib import Path
26from unittest import TestCase28from unittest import TestCase
27from unittest.mock import ANY, MagicMock, patch29from unittest.mock import MagicMock, patch
2830
29from openlp.core.common.path import Path, copy, copyfile, copytree, create_paths, files_to_paths, path_to_str, \31from openlp.core.common.path import create_paths, files_to_paths, path_to_str, replace_params, str_to_path, which
30 replace_params, str_to_path, which
3132
3233
33class TestShutil(TestCase):34class TestShutil(TestCase):
@@ -66,139 +67,6 @@
66 assert result_args == (1, '2')67 assert result_args == (1, '2')
67 assert result_kwargs == {'arg3': '3', 'arg4': 4}68 assert result_kwargs == {'arg3': '3', 'arg4': 4}
6869
69 def test_copy(self):
70 """
71 Test :func:`openlp.core.common.path.copy`
72 """
73 # GIVEN: A mocked `shutil.copy` which returns a test path as a string
74 with patch('openlp.core.common.path.shutil.copy', return_value=os.path.join('destination', 'test', 'path')) \
75 as mocked_shutil_copy:
76
77 # WHEN: Calling :func:`openlp.core.common.path.copy` with the src and dst parameters as Path object types
78 result = copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
79
80 # THEN: :func:`shutil.copy` should have been called with the str equivalents of the Path objects.
81 # :func:`openlp.core.common.path.copy` should return the str type result of calling
82 # :func:`shutil.copy` as a Path object.
83 mocked_shutil_copy.assert_called_once_with(os.path.join('source', 'test', 'path'),
84 os.path.join('destination', 'test', 'path'))
85 assert result == Path('destination', 'test', 'path')
86
87 def test_copy_follow_optional_params(self):
88 """
89 Test :func:`openlp.core.common.path.copy` when follow_symlinks is set to false
90 """
91 # GIVEN: A mocked `shutil.copy`
92 with patch('openlp.core.common.path.shutil.copy', return_value='') as mocked_shutil_copy:
93
94 # WHEN: Calling :func:`openlp.core.common.path.copy` with :param:`follow_symlinks` set to False
95 copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False)
96
97 # THEN: :func:`shutil.copy` should have been called with :param:`follow_symlinks` set to false
98 mocked_shutil_copy.assert_called_once_with(ANY, ANY, follow_symlinks=False)
99
100 def test_copyfile(self):
101 """
102 Test :func:`openlp.core.common.path.copyfile`
103 """
104 # GIVEN: A mocked :func:`shutil.copyfile` which returns a test path as a string
105 with patch('openlp.core.common.path.shutil.copyfile',
106 return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copyfile:
107
108 # WHEN: Calling :func:`openlp.core.common.path.copyfile` with the src and dst parameters as Path object
109 # types
110 result = copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
111
112 # THEN: :func:`shutil.copyfile` should have been called with the str equivalents of the Path objects.
113 # :func:`openlp.core.common.path.copyfile` should return the str type result of calling
114 # :func:`shutil.copyfile` as a Path object.
115 mocked_shutil_copyfile.assert_called_once_with(os.path.join('source', 'test', 'path'),
116 os.path.join('destination', 'test', 'path'))
117 assert result == Path('destination', 'test', 'path')
118
119 def test_copyfile_optional_params(self):
120 """
121 Test :func:`openlp.core.common.path.copyfile` when follow_symlinks is set to false
122 """
123 # GIVEN: A mocked :func:`shutil.copyfile`
124 with patch('openlp.core.common.path.shutil.copyfile', return_value='') as mocked_shutil_copyfile:
125
126 # WHEN: Calling :func:`openlp.core.common.path.copyfile` with :param:`follow_symlinks` set to False
127 copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False)
128
129 # THEN: :func:`shutil.copyfile` should have been called with the optional parameters, with out any of the
130 # values being modified
131 mocked_shutil_copyfile.assert_called_once_with(ANY, ANY, follow_symlinks=False)
132
133 def test_copytree(self):
134 """
135 Test :func:`openlp.core.common.path.copytree`
136 """
137 # GIVEN: A mocked :func:`shutil.copytree` which returns a test path as a string
138 with patch('openlp.core.common.path.shutil.copytree',
139 return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copytree:
140
141 # WHEN: Calling :func:`openlp.core.common.path.copytree` with the src and dst parameters as Path object
142 # types
143 result = copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
144
145 # THEN: :func:`shutil.copytree` should have been called with the str equivalents of the Path objects.
146 # :func:`openlp.core.common.path.copytree` should return the str type result of calling
147 # :func:`shutil.copytree` as a Path object.
148 mocked_shutil_copytree.assert_called_once_with(os.path.join('source', 'test', 'path'),
149 os.path.join('destination', 'test', 'path'))
150 assert result == Path('destination', 'test', 'path')
151
152 def test_copytree_optional_params(self):
153 """
154 Test :func:`openlp.core.common.path.copytree` when optional parameters are passed
155 """
156 # GIVEN: A mocked :func:`shutil.copytree`
157 with patch('openlp.core.common.path.shutil.copytree', return_value='') as mocked_shutil_copytree:
158 mocked_ignore = MagicMock()
159 mocked_copy_function = MagicMock()
160
161 # WHEN: Calling :func:`openlp.core.common.path.copytree` with the optional parameters set
162 copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), symlinks=True,
163 ignore=mocked_ignore, copy_function=mocked_copy_function, ignore_dangling_symlinks=True)
164
165 # THEN: :func:`shutil.copytree` should have been called with the optional parameters, with out any of the
166 # values being modified
167 mocked_shutil_copytree.assert_called_once_with(ANY, ANY, symlinks=True, ignore=mocked_ignore,
168 copy_function=mocked_copy_function,
169 ignore_dangling_symlinks=True)
170
171 def test_rmtree(self):
172 """
173 Test :func:`rmtree`
174 """
175 # GIVEN: A mocked :func:`shutil.rmtree` and a test Path object
176 with patch('openlp.core.common.path.shutil.rmtree', return_value=None) as mocked_shutil_rmtree:
177 path = Path('test', 'path')
178
179 # WHEN: Calling :func:`openlp.core.common.path.rmtree` with the path parameter as Path object type
180 path.rmtree()
181
182 # THEN: :func:`shutil.rmtree` should have been called with the the Path object.
183 mocked_shutil_rmtree.assert_called_once_with(Path('test', 'path'), False, None)
184
185 def test_rmtree_optional_params(self):
186 """
187 Test :func:`openlp.core.common.path.rmtree` when optional parameters are passed
188 """
189 # GIVEN: A mocked :func:`shutil.rmtree` and a test Path object.
190 with patch('openlp.core.common.path.shutil.rmtree', return_value=None) as mocked_shutil_rmtree:
191 path = Path('test', 'path')
192 mocked_on_error = MagicMock()
193
194 # WHEN: Calling :func:`openlp.core.common.path.rmtree` with :param:`ignore_errors` set to True and
195 # :param:`onerror` set to a mocked object
196 path.rmtree(ignore_errors=True, onerror=mocked_on_error)
197
198 # THEN: :func:`shutil.rmtree` should have been called with the optional parameters, with out any of the
199 # values being modified
200 mocked_shutil_rmtree.assert_called_once_with(path, True, mocked_on_error)
201
202 def test_which_no_command(self):70 def test_which_no_command(self):
203 """71 """
204 Test :func:`openlp.core.common.path.which` when the command is not found.72 Test :func:`openlp.core.common.path.which` when the command is not found.
@@ -287,57 +155,6 @@
287 # THEN: `path_to_str` should return None155 # THEN: `path_to_str` should return None
288 assert result is None156 assert result is None
289157
290 def test_path_encode_json(self):
291 """
292 Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
293 from JSON
294 """
295 # GIVEN: A Path object from openlp.core.common.path
296 # WHEN: Calling encode_json, with a dictionary representation
297 path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, extra=1, args=2)
298
299 # THEN: A Path object should have been returned
300 assert path == Path('path', 'to', 'fi.le')
301
302 def test_path_encode_json_base_path(self):
303 """
304 Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
305 from JSON when the base_path arg is supplied.
306 """
307 # GIVEN: A Path object from openlp.core.common.path
308 # WHEN: Calling encode_json, with a dictionary representation
309 path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, base_path=Path('/base'))
310
311 # THEN: A Path object should have been returned with an absolute path
312 assert path == Path('/', 'base', 'path', 'to', 'fi.le')
313
314 def test_path_json_object(self):
315 """
316 Test that `Path.json_object` creates a JSON decode-able object from a Path object
317 """
318 # GIVEN: A Path object from openlp.core.common.path
319 path = Path('/base', 'path', 'to', 'fi.le')
320
321 # WHEN: Calling json_object
322 obj = path.json_object(extra=1, args=2)
323
324 # THEN: A JSON decodable object should have been returned.
325 assert obj == {'__Path__': (os.sep, 'base', 'path', 'to', 'fi.le')}
326
327 def test_path_json_object_base_path(self):
328 """
329 Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
330 base_path
331 """
332 # GIVEN: A Path object from openlp.core.common.path
333 path = Path('/base', 'path', 'to', 'fi.le')
334
335 # WHEN: Calling json_object with a base_path
336 obj = path.json_object(base_path=Path('/', 'base'))
337
338 # THEN: A JSON decodable object should have been returned.
339 assert obj == {'__Path__': ('path', 'to', 'fi.le')}
340
341 def test_create_paths_dir_exists(self):158 def test_create_paths_dir_exists(self):
342 """159 """
343 Test the create_paths() function when the path already exists160 Test the create_paths() function when the path already exists
344161
=== modified file 'tests/functional/openlp_core/common/test_settings.py'
--- tests/functional/openlp_core/common/test_settings.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/common/test_settings.py 2019-05-23 20:08:25 +0000
@@ -277,7 +277,8 @@
277 """Test the Settings._convert_value() method when a setting is JSON and represents a Path object"""277 """Test the Settings._convert_value() method when a setting is JSON and represents a Path object"""
278 # GIVEN: A settings object278 # GIVEN: A settings object
279 # WHEN: _convert_value() is run279 # WHEN: _convert_value() is run
280 result = Settings()._convert_value('{"__Path__": ["openlp", "core"]}', None)280 result = Settings()._convert_value(
281 '{"parts": ["openlp", "core"], "json_meta": {"class": "Path", "version": 1}}', None)
281282
282 # THEN: The result should be a Path object283 # THEN: The result should be a Path object
283 assert isinstance(result, Path), 'The result should be a Path object'284 assert isinstance(result, Path), 'The result should be a Path object'
284285
=== modified file 'tests/functional/openlp_core/lib/test_db.py'
--- tests/functional/openlp_core/lib/test_db.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/lib/test_db.py 2019-05-23 20:08:25 +0000
@@ -23,6 +23,7 @@
23Package to test the openlp.core.lib package.23Package to test the openlp.core.lib package.
24"""24"""
25import shutil25import shutil
26from pathlib import Path
26from tempfile import mkdtemp27from tempfile import mkdtemp
27from unittest import TestCase28from unittest import TestCase
28from unittest.mock import MagicMock, patch29from unittest.mock import MagicMock, patch
@@ -31,7 +32,6 @@
31from sqlalchemy.orm.scoping import ScopedSession32from sqlalchemy.orm.scoping import ScopedSession
32from sqlalchemy.pool import NullPool33from sqlalchemy.pool import NullPool
3334
34from openlp.core.common.path import Path
35from openlp.core.lib.db import delete_database, get_upgrade_op, init_db, upgrade_db35from openlp.core.lib.db import delete_database, get_upgrade_op, init_db, upgrade_db
3636
3737
3838
=== modified file 'tests/functional/openlp_core/lib/test_lib.py'
--- tests/functional/openlp_core/lib/test_lib.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/lib/test_lib.py 2019-05-23 20:08:25 +0000
@@ -22,12 +22,12 @@
22"""22"""
23Package to test the openlp.core.lib package.23Package to test the openlp.core.lib package.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2728
28from PyQt5 import QtCore, QtGui29from PyQt5 import QtCore, QtGui
2930
30from openlp.core.common.path import Path
31from openlp.core.lib import build_icon, check_item_selected, create_separated_list, create_thumb, \31from openlp.core.lib import build_icon, check_item_selected, create_separated_list, create_thumb, \
32 get_text_file_string, image_to_byte, resize_image, str_to_bool, validate_thumb32 get_text_file_string, image_to_byte, resize_image, str_to_bool, validate_thumb
33from tests.utils.constants import RESOURCE_PATH33from tests.utils.constants import RESOURCE_PATH
3434
=== modified file 'tests/functional/openlp_core/lib/test_serviceitem.py'
--- tests/functional/openlp_core/lib/test_serviceitem.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/lib/test_serviceitem.py 2019-05-23 20:08:25 +0000
@@ -23,12 +23,12 @@
23Package to test the openlp.core.lib package.23Package to test the openlp.core.lib package.
24"""24"""
25import os25import os
26from pathlib import Path
26from unittest import TestCase27from unittest import TestCase
27from unittest.mock import MagicMock, patch28from unittest.mock import MagicMock, patch
2829
29from openlp.core.state import State30from openlp.core.state import State
30from openlp.core.common import md5_hash31from openlp.core.common import md5_hash
31from openlp.core.common.path import Path
32from openlp.core.common.registry import Registry32from openlp.core.common.registry import Registry
33from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
34from openlp.core.lib.formattingtags import FormattingTags34from openlp.core.lib.formattingtags import FormattingTags
3535
=== modified file 'tests/functional/openlp_core/test_server.py'
--- tests/functional/openlp_core/test_server.py 2019-05-04 18:13:57 +0000
+++ tests/functional/openlp_core/test_server.py 2019-05-23 20:08:25 +0000
@@ -19,10 +19,10 @@
19# You should have received a copy of the GNU General Public License #19# You should have received a copy of the GNU General Public License #
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22from pathlib import Path
22from unittest import TestCase23from unittest import TestCase
23from unittest.mock import MagicMock, patch24from unittest.mock import MagicMock, patch
2425
25from openlp.core.common.path import Path
26from openlp.core.common.registry import Registry26from openlp.core.common.registry import Registry
27from openlp.core.server import Server27from openlp.core.server import Server
28from tests.helpers.testmixin import TestMixin28from tests.helpers.testmixin import TestMixin
2929
=== modified file 'tests/functional/openlp_core/ui/test_exceptionform.py'
--- tests/functional/openlp_core/ui/test_exceptionform.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/ui/test_exceptionform.py 2019-05-23 20:08:25 +0000
@@ -25,10 +25,10 @@
25import os25import os
26import tempfile26import tempfile
27from collections import OrderedDict27from collections import OrderedDict
28from pathlib import Path
28from unittest import TestCase29from unittest import TestCase
29from unittest.mock import call, patch30from unittest.mock import call, patch
3031
31from openlp.core.common.path import Path
32from openlp.core.common.registry import Registry32from openlp.core.common.registry import Registry
33from openlp.core.ui import exceptionform33from openlp.core.ui import exceptionform
34from tests.helpers.testmixin import TestMixin34from tests.helpers.testmixin import TestMixin
3535
=== modified file 'tests/functional/openlp_core/ui/test_firsttimeform.py'
--- tests/functional/openlp_core/ui/test_firsttimeform.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/ui/test_firsttimeform.py 2019-05-23 20:08:25 +0000
@@ -24,12 +24,12 @@
24"""24"""
25import os25import os
26import tempfile26import tempfile
27from pathlib import Path
27from unittest import TestCase28from unittest import TestCase
28from unittest.mock import MagicMock, call, patch, DEFAULT29from unittest.mock import MagicMock, call, patch, DEFAULT
2930
30from PyQt5 import QtWidgets31from PyQt5 import QtWidgets
3132
32from openlp.core.common.path import Path
33from openlp.core.common.registry import Registry33from openlp.core.common.registry import Registry
34from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem34from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem
35from tests.helpers.testmixin import TestMixin35from tests.helpers.testmixin import TestMixin
3636
=== modified file 'tests/functional/openlp_core/ui/test_themeform.py'
--- tests/functional/openlp_core/ui/test_themeform.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/ui/test_themeform.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23Package to test the openlp.core.ui.themeform package.23Package to test the openlp.core.ui.themeform package.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2728
28from openlp.core.common.path import Path
29from openlp.core.ui.themeform import ThemeForm29from openlp.core.ui.themeform import ThemeForm
3030
3131
3232
=== modified file 'tests/functional/openlp_core/ui/test_thememanager.py'
--- tests/functional/openlp_core/ui/test_thememanager.py 2019-05-04 11:49:20 +0000
+++ tests/functional/openlp_core/ui/test_thememanager.py 2019-05-23 20:08:25 +0000
@@ -24,13 +24,13 @@
24"""24"""
25import os25import os
26import shutil26import shutil
27from pathlib import Path
27from tempfile import mkdtemp28from tempfile import mkdtemp
28from unittest import TestCase29from unittest import TestCase
29from unittest.mock import ANY, MagicMock, patch30from unittest.mock import ANY, MagicMock, patch
3031
31from PyQt5 import QtWidgets32from PyQt5 import QtWidgets
3233
33from openlp.core.common.path import Path
34from openlp.core.common.registry import Registry34from openlp.core.common.registry import Registry
35from openlp.core.ui.thememanager import ThemeManager35from openlp.core.ui.thememanager import ThemeManager
36from tests.utils.constants import RESOURCE_PATH36from tests.utils.constants import RESOURCE_PATH
@@ -81,9 +81,9 @@
81 # THEN: The the controller should be registered in the registry.81 # THEN: The the controller should be registered in the registry.
82 assert Registry().get('theme_manager') is not None, 'The base theme manager should be registered'82 assert Registry().get('theme_manager') is not None, 'The base theme manager should be registered'
8383
84 @patch('openlp.core.ui.thememanager.copyfile')84 @patch('openlp.core.ui.thememanager.shutil')
85 @patch('openlp.core.ui.thememanager.create_paths')85 @patch('openlp.core.ui.thememanager.create_paths')
86 def test_write_theme_same_image(self, mocked_create_paths, mocked_copyfile):86 def test_write_theme_same_image(self, mocked_create_paths, mocked_shutil):
87 """87 """
88 Test that we don't try to overwrite a theme background image with itself88 Test that we don't try to overwrite a theme background image with itself
89 """89 """
@@ -103,11 +103,11 @@
103 theme_manager._write_theme(mocked_theme, file_path_1, file_path_1)103 theme_manager._write_theme(mocked_theme, file_path_1, file_path_1)
104104
105 # THEN: The mocked_copyfile should not have been called105 # THEN: The mocked_copyfile should not have been called
106 assert mocked_copyfile.called is False, 'copyfile should not be called'106 assert mocked_shutil.copyfile.called is False, 'copyfile should not be called'
107107
108 @patch('openlp.core.ui.thememanager.copyfile')108 @patch('openlp.core.ui.thememanager.shutil')
109 @patch('openlp.core.ui.thememanager.create_paths')109 @patch('openlp.core.ui.thememanager.create_paths')
110 def test_write_theme_diff_images(self, mocked_create_paths, mocked_copyfile):110 def test_write_theme_diff_images(self, mocked_create_paths, mocked_shutil):
111 """111 """
112 Test that we do overwrite a theme background image when a new is submitted112 Test that we do overwrite a theme background image when a new is submitted
113 """113 """
@@ -127,7 +127,7 @@
127 theme_manager._write_theme(mocked_theme, file_path_1, file_path_2)127 theme_manager._write_theme(mocked_theme, file_path_1, file_path_2)
128128
129 # THEN: The mocked_copyfile should not have been called129 # THEN: The mocked_copyfile should not have been called
130 assert mocked_copyfile.called is True, 'copyfile should be called'130 assert mocked_shutil.copyfile.called is True, 'copyfile should be called'
131131
132 def test_write_theme_special_char_name(self):132 def test_write_theme_special_char_name(self):
133 """133 """
@@ -207,7 +207,7 @@
207 # THEN: Files should be unpacked207 # THEN: Files should be unpacked
208 assert (folder_path / 'Moss on tree' / 'Moss on tree.xml').exists() is True208 assert (folder_path / 'Moss on tree' / 'Moss on tree.xml').exists() is True
209 assert mocked_critical_error_message_box.call_count == 0, 'No errors should have happened'209 assert mocked_critical_error_message_box.call_count == 0, 'No errors should have happened'
210 folder_path.rmtree()210 shutil.rmtree(folder_path)
211211
212 def test_unzip_theme_invalid_version(self):212 def test_unzip_theme_invalid_version(self):
213 """213 """
214214
=== modified file 'tests/functional/openlp_core/widgets/test_dialogs.py'
--- tests/functional/openlp_core/widgets/test_dialogs.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/widgets/test_dialogs.py 2019-05-23 20:08:25 +0000
@@ -20,12 +20,12 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import os22import os
23from pathlib import Path
23from unittest import TestCase24from unittest import TestCase
24from unittest.mock import patch25from unittest.mock import patch
2526
26from PyQt5 import QtWidgets27from PyQt5 import QtWidgets
2728
28from openlp.core.common.path import Path
29from openlp.core.widgets.dialogs import FileDialog29from openlp.core.widgets.dialogs import FileDialog
3030
3131
3232
=== modified file 'tests/functional/openlp_core/widgets/test_edits.py'
--- tests/functional/openlp_core/widgets/test_edits.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_core/widgets/test_edits.py 2019-05-23 20:08:25 +0000
@@ -23,10 +23,10 @@
23This module contains tests for the openlp.core.widgets.edits module23This module contains tests for the openlp.core.widgets.edits module
24"""24"""
25import os25import os
26from pathlib import Path
26from unittest import TestCase27from unittest import TestCase
27from unittest.mock import MagicMock, PropertyMock, patch28from unittest.mock import MagicMock, PropertyMock, patch
2829
29from openlp.core.common.path import Path
30from openlp.core.widgets.dialogs import FileDialog30from openlp.core.widgets.dialogs import FileDialog
31from openlp.core.widgets.edits import PathEdit31from openlp.core.widgets.edits import PathEdit
32from openlp.core.widgets.enums import PathEditType32from openlp.core.widgets.enums import PathEditType
3333
=== modified file 'tests/functional/openlp_plugins/bibles/test_bibleimport.py'
--- tests/functional/openlp_plugins/bibles/test_bibleimport.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/bibles/test_bibleimport.py 2019-05-23 20:08:25 +0000
@@ -23,6 +23,7 @@
23This module contains tests for the bibleimport module.23This module contains tests for the bibleimport module.
24"""24"""
25from io import BytesIO25from io import BytesIO
26from pathlib import Path
26from unittest import TestCase27from unittest import TestCase
27from unittest.mock import MagicMock, patch28from unittest.mock import MagicMock, patch
2829
@@ -30,7 +31,6 @@
30from PyQt5.QtWidgets import QDialog31from PyQt5.QtWidgets import QDialog
3132
32from openlp.core.common.i18n import Language33from openlp.core.common.i18n import Language
33from openlp.core.common.path import Path
34from openlp.core.lib.exceptions import ValidationError34from openlp.core.lib.exceptions import ValidationError
35from openlp.plugins.bibles.lib.bibleimport import BibleImport35from openlp.plugins.bibles.lib.bibleimport import BibleImport
36from openlp.plugins.bibles.lib.db import BibleDB36from openlp.plugins.bibles.lib.db import BibleDB
3737
=== modified file 'tests/functional/openlp_plugins/bibles/test_csvimport.py'
--- tests/functional/openlp_plugins/bibles/test_csvimport.py 2019-05-04 12:05:53 +0000
+++ tests/functional/openlp_plugins/bibles/test_csvimport.py 2019-05-23 20:08:25 +0000
@@ -24,10 +24,10 @@
24"""24"""
25import csv25import csv
26from collections import namedtuple26from collections import namedtuple
27from pathlib import Path
27from unittest import TestCase28from unittest import TestCase
28from unittest.mock import MagicMock, PropertyMock, call, patch29from unittest.mock import MagicMock, PropertyMock, call, patch
2930
30from openlp.core.common.path import Path
31from openlp.core.lib.exceptions import ValidationError31from openlp.core.lib.exceptions import ValidationError
32from openlp.plugins.bibles.lib.bibleimport import BibleImport32from openlp.plugins.bibles.lib.bibleimport import BibleImport
33from openlp.plugins.bibles.lib.importers.csvbible import Book, CSVBible, Verse33from openlp.plugins.bibles.lib.importers.csvbible import Book, CSVBible, Verse
3434
=== modified file 'tests/functional/openlp_plugins/bibles/test_manager.py'
--- tests/functional/openlp_plugins/bibles/test_manager.py 2019-04-28 19:21:23 +0000
+++ tests/functional/openlp_plugins/bibles/test_manager.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23This module contains tests for the manager submodule of the Bibles plugin.23This module contains tests for the manager submodule of the Bibles plugin.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2728
28from openlp.core.common.path import Path
29from openlp.plugins.bibles.lib.manager import BibleManager29from openlp.plugins.bibles.lib.manager import BibleManager
3030
3131
3232
=== modified file 'tests/functional/openlp_plugins/bibles/test_wordprojectimport.py'
--- tests/functional/openlp_plugins/bibles/test_wordprojectimport.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/bibles/test_wordprojectimport.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23This module contains tests for the WordProject Bible importer.23This module contains tests for the WordProject Bible importer.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, call, patch27from unittest.mock import MagicMock, call, patch
2728
28from openlp.core.common.path import Path
29from openlp.plugins.bibles.lib.importers.wordproject import WordProjectBible29from openlp.plugins.bibles.lib.importers.wordproject import WordProjectBible
30from tests.utils.constants import RESOURCE_PATH30from tests.utils.constants import RESOURCE_PATH
3131
3232
=== modified file 'tests/functional/openlp_plugins/images/test_lib.py'
--- tests/functional/openlp_plugins/images/test_lib.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/images/test_lib.py 2019-05-23 20:08:25 +0000
@@ -22,12 +22,12 @@
22"""22"""
23This module contains tests for the lib submodule of the Images plugin.23This module contains tests for the lib submodule of the Images plugin.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import ANY, MagicMock, patch27from unittest.mock import ANY, MagicMock, patch
2728
28from PyQt5 import QtCore, QtWidgets29from PyQt5 import QtCore, QtWidgets
2930
30from openlp.core.common.path import Path
31from openlp.core.common.registry import Registry31from openlp.core.common.registry import Registry
32from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups32from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
33from openlp.plugins.images.lib.mediaitem import ImageMediaItem33from openlp.plugins.images.lib.mediaitem import ImageMediaItem
3434
=== modified file 'tests/functional/openlp_plugins/images/test_upgrade.py'
--- tests/functional/openlp_plugins/images/test_upgrade.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/images/test_upgrade.py 2019-05-23 20:08:25 +0000
@@ -24,12 +24,12 @@
24"""24"""
25import os25import os
26import shutil26import shutil
27from pathlib import Path
27from tempfile import mkdtemp28from tempfile import mkdtemp
28from unittest import TestCase, skip29from unittest import TestCase, skip
29from unittest.mock import patch30from unittest.mock import patch
3031
31from openlp.core.common.applocation import AppLocation32from openlp.core.common.applocation import AppLocation
32from openlp.core.common.path import Path
33from openlp.core.common.settings import Settings33from openlp.core.common.settings import Settings
34from openlp.core.lib.db import Manager34from openlp.core.lib.db import Manager
35from openlp.plugins.images.lib import upgrade35from openlp.plugins.images.lib import upgrade
3636
=== modified file 'tests/functional/openlp_plugins/media/test_mediaitem.py'
--- tests/functional/openlp_plugins/media/test_mediaitem.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/media/test_mediaitem.py 2019-05-23 20:08:25 +0000
@@ -22,12 +22,12 @@
22"""22"""
23Test the media plugin23Test the media plugin
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2728
28from PyQt5 import QtCore29from PyQt5 import QtCore
2930
30from openlp.core.common.path import Path
31from openlp.core.common.settings import Settings31from openlp.core.common.settings import Settings
32from openlp.plugins.media.lib.mediaitem import MediaMediaItem32from openlp.plugins.media.lib.mediaitem import MediaMediaItem
33from tests.helpers.testmixin import TestMixin33from tests.helpers.testmixin import TestMixin
3434
=== modified file 'tests/functional/openlp_plugins/presentations/test_mediaitem.py'
--- tests/functional/openlp_plugins/presentations/test_mediaitem.py 2019-05-02 13:45:07 +0000
+++ tests/functional/openlp_plugins/presentations/test_mediaitem.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23This module contains tests for the lib submodule of the Presentations plugin.23This module contains tests for the lib submodule of the Presentations plugin.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, call, patch27from unittest.mock import MagicMock, call, patch
2728
28from openlp.core.common.path import Path
29from openlp.core.common.registry import Registry29from openlp.core.common.registry import Registry
30from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem30from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem
31from tests.helpers.testmixin import TestMixin31from tests.helpers.testmixin import TestMixin
3232
=== modified file 'tests/functional/openlp_plugins/presentations/test_pdfcontroller.py'
--- tests/functional/openlp_plugins/presentations/test_pdfcontroller.py 2019-05-02 17:11:55 +0000
+++ tests/functional/openlp_plugins/presentations/test_pdfcontroller.py 2019-05-23 20:08:25 +0000
@@ -23,7 +23,8 @@
23This module contains tests for the PdfController23This module contains tests for the PdfController
24"""24"""
25import os25import os
26from shutil import which26from pathlib import Path
27from shutil import rmtree, which
27from tempfile import mkdtemp28from tempfile import mkdtemp
28from unittest import TestCase29from unittest import TestCase
29from unittest.mock import MagicMock, patch30from unittest.mock import MagicMock, patch
@@ -31,7 +32,6 @@
31from PyQt5 import QtCore, QtGui32from PyQt5 import QtCore, QtGui
3233
33from openlp.core.common import is_macosx, is_linux, is_win34from openlp.core.common import is_macosx, is_linux, is_win
34from openlp.core.common.path import Path
35from openlp.core.common.settings import Settings35from openlp.core.common.settings import Settings
36from openlp.core.display.screens import ScreenList36from openlp.core.display.screens import ScreenList
37from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument37from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
@@ -99,8 +99,8 @@
99 """99 """
100 del self.screens100 del self.screens
101 self.destroy_settings()101 self.destroy_settings()
102 self.thumbnail_folder_path.rmtree()102 rmtree(self.thumbnail_folder_path)
103 self.temp_folder_path.rmtree()103 rmtree(self.temp_folder_path)
104104
105 def test_constructor(self):105 def test_constructor(self):
106 """106 """
107107
=== modified file 'tests/functional/openlp_plugins/presentations/test_presentationcontroller.py'
--- tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2019-05-23 20:08:25 +0000
@@ -23,10 +23,10 @@
23Functional tests to test the PresentationController and PresentationDocument23Functional tests to test the PresentationController and PresentationDocument
24classes and related methods.24classes and related methods.
25"""25"""
26from pathlib import Path
26from unittest import TestCase27from unittest import TestCase
27from unittest.mock import MagicMock, call, patch28from unittest.mock import MagicMock, call, patch
2829
29from openlp.core.common.path import Path
30from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument30from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
3131
3232
3333
=== modified file 'tests/functional/openlp_plugins/songs/test_openlyricsexport.py'
--- tests/functional/openlp_plugins/songs/test_openlyricsexport.py 2019-04-13 13:00:22 +0000
+++ tests/functional/openlp_plugins/songs/test_openlyricsexport.py 2019-05-23 20:08:25 +0000
@@ -22,11 +22,12 @@
22"""22"""
23This module contains tests for the OpenLyrics song importer.23This module contains tests for the OpenLyrics song importer.
24"""24"""
25import shutil
26from pathlib import Path
25from tempfile import mkdtemp27from tempfile import mkdtemp
26from unittest import TestCase28from unittest import TestCase
27from unittest.mock import MagicMock, patch29from unittest.mock import MagicMock, patch
2830
29from openlp.core.common.path import Path
30from openlp.core.common.registry import Registry31from openlp.core.common.registry import Registry
31from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport32from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport
32from tests.helpers.testmixin import TestMixin33from tests.helpers.testmixin import TestMixin
@@ -47,7 +48,7 @@
47 """48 """
48 Cleanup49 Cleanup
49 """50 """
50 self.temp_folder.rmtree()51 shutil.rmtree(self.temp_folder)
5152
52 def test_export_same_filename(self):53 def test_export_same_filename(self):
53 """54 """
5455
=== modified file 'tests/helpers/songfileimport.py'
--- tests/helpers/songfileimport.py 2019-04-13 13:00:22 +0000
+++ tests/helpers/songfileimport.py 2019-05-23 20:08:25 +0000
@@ -82,7 +82,7 @@
82 """82 """
83 A method to load and return an object containing the song data from an external file.83 A method to load and return an object containing the song data from an external file.
8484
85 :param openlp.core.common.path.Path file_path: The path of the file to load85 :param pathlib.Path file_path: The path of the file to load
86 """86 """
87 return json.loads(file_path.read_bytes().decode())87 return json.loads(file_path.read_bytes().decode())
8888
8989
=== modified file 'tests/interfaces/openlp_core/lib/test_pluginmanager.py'
--- tests/interfaces/openlp_core/lib/test_pluginmanager.py 2019-04-13 13:00:22 +0000
+++ tests/interfaces/openlp_core/lib/test_pluginmanager.py 2019-05-23 20:08:25 +0000
@@ -22,7 +22,9 @@
22"""22"""
23Package to test the openlp.core.lib.pluginmanager package.23Package to test the openlp.core.lib.pluginmanager package.
24"""24"""
25import shutil
25import sys26import sys
27from pathlib import Path
26from tempfile import mkdtemp28from tempfile import mkdtemp
27from unittest import TestCase, skip29from unittest import TestCase, skip
28from unittest.mock import MagicMock, patch30from unittest.mock import MagicMock, patch
@@ -30,7 +32,6 @@
30from PyQt5 import QtWidgets32from PyQt5 import QtWidgets
3133
32from openlp.core.common import is_win34from openlp.core.common import is_win
33from openlp.core.common.path import Path
34from openlp.core.common.registry import Registry35from openlp.core.common.registry import Registry
35from openlp.core.common.settings import Settings36from openlp.core.common.settings import Settings
36from openlp.core.state import State37from openlp.core.state import State
@@ -65,7 +66,7 @@
65 if is_win():66 if is_win():
66 import gc67 import gc
67 gc.collect()68 gc.collect()
68 self.temp_dir_path.rmtree()69 shutil.rmtree(self.temp_dir_path)
6970
70 @skip71 @skip
71 # This test is broken but totally unable to debug it.72 # This test is broken but totally unable to debug it.
7273
=== modified file 'tests/interfaces/openlp_core/ui/test_firsttimeform.py'
--- tests/interfaces/openlp_core/ui/test_firsttimeform.py 2019-04-13 13:00:22 +0000
+++ tests/interfaces/openlp_core/ui/test_firsttimeform.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23Package to test the openlp.core.ui.firsttimeform package.23Package to test the openlp.core.ui.firsttimeform package.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, call, patch27from unittest.mock import MagicMock, call, patch
2728
28from openlp.core.common.path import Path
29from openlp.core.common.registry import Registry29from openlp.core.common.registry import Registry
30from openlp.core.ui.firsttimeform import ThemeListWidgetItem30from openlp.core.ui.firsttimeform import ThemeListWidgetItem
31from openlp.core.ui.icons import UiIcons31from openlp.core.ui.icons import UiIcons
3232
=== modified file 'tests/interfaces/openlp_core/ui/test_thememanager.py'
--- tests/interfaces/openlp_core/ui/test_thememanager.py 2019-04-13 13:00:22 +0000
+++ tests/interfaces/openlp_core/ui/test_thememanager.py 2019-05-23 20:08:25 +0000
@@ -22,10 +22,10 @@
22"""22"""
23Interface tests to test the themeManager class and related methods.23Interface tests to test the themeManager class and related methods.
24"""24"""
25from pathlib import Path
25from unittest import TestCase26from unittest import TestCase
26from unittest.mock import MagicMock, patch27from unittest.mock import MagicMock, patch
2728
28from openlp.core.common.path import Path
29from openlp.core.common.registry import Registry29from openlp.core.common.registry import Registry
30from openlp.core.common.settings import Settings30from openlp.core.common.settings import Settings
31from openlp.core.ui.thememanager import ThemeManager31from openlp.core.ui.thememanager import ThemeManager
3232
=== modified file 'tests/utils/__init__.py'
--- tests/utils/__init__.py 2019-04-13 13:00:22 +0000
+++ tests/utils/__init__.py 2019-05-23 20:08:25 +0000
@@ -44,6 +44,6 @@
44 """44 """
45 A method to load and return an object containing the song data from an external file.45 A method to load and return an object containing the song data from an external file.
4646
47 :param openlp.core.common.path.Path file_path: The path of the file to load47 :param pathlib.Path file_path: The path of the file to load
48 """48 """
49 return json.loads(file_path.read_bytes().decode())49 return json.loads(file_path.read_bytes().decode())
5050
=== modified file 'tests/utils/constants.py'
--- tests/utils/constants.py 2019-04-13 13:00:22 +0000
+++ tests/utils/constants.py 2019-05-23 20:08:25 +0000
@@ -20,8 +20,7 @@
20# along with this program. If not, see <https://www.gnu.org/licenses/>. #20# along with this program. If not, see <https://www.gnu.org/licenses/>. #
21##########################################################################21##########################################################################
22import os22import os
2323from pathlib import Path
24from openlp.core.common.path import Path
2524
2625
27OPENLP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))26OPENLP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))