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
1=== modified file 'openlp/core/api/deploy.py'
2--- openlp/core/api/deploy.py 2019-04-13 13:00:22 +0000
3+++ openlp/core/api/deploy.py 2019-05-23 20:08:25 +0000
4@@ -34,7 +34,7 @@
5 Process the downloaded zip file and add to the correct directory
6
7 :param str zip_name: the zip file name to be processed
8- :param openlp.core.common.path.Path app_root_path: The directory to expand the zip to
9+ :param pathlib.Path app_root_path: The directory to expand the zip to
10
11 :return: None
12 """
13
14=== modified file 'openlp/core/api/endpoint/controller.py'
15--- openlp/core/api/endpoint/controller.py 2019-04-13 13:00:22 +0000
16+++ openlp/core/api/endpoint/controller.py 2019-05-23 20:08:25 +0000
17@@ -24,11 +24,11 @@
18 import os
19 import urllib.error
20 import urllib.request
21+from pathlib import Path
22
23 from openlp.core.api.http import requires_auth
24 from openlp.core.api.http.endpoint import Endpoint
25 from openlp.core.common.applocation import AppLocation
26-from openlp.core.common.path import Path
27 from openlp.core.common.registry import Registry
28 from openlp.core.common.settings import Settings
29 from openlp.core.lib import create_thumb
30
31=== modified file 'openlp/core/app.py'
32--- openlp/core/app.py 2019-05-04 09:13:29 +0000
33+++ openlp/core/app.py 2019-05-23 20:08:25 +0000
34@@ -32,6 +32,8 @@
35 import time
36 import os
37 from datetime import datetime
38+from pathlib import Path
39+from shutil import copytree
40 from traceback import format_exception
41
42 from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets # noqa
43@@ -41,7 +43,7 @@
44 from openlp.core.common.applocation import AppLocation
45 from openlp.core.loader import loader
46 from openlp.core.common.i18n import LanguageManager, UiStrings, translate
47-from openlp.core.common.path import copytree, create_paths, Path
48+from openlp.core.common.path import create_paths
49 from openlp.core.common.registry import Registry
50 from openlp.core.common.settings import Settings
51 from openlp.core.display.screens import ScreenList
52@@ -316,7 +318,7 @@
53 """
54 Setup our logging using log_path
55
56- :param openlp.core.common.path.Path log_path: The file to save the log to.
57+ :param Path log_path: The file to save the log to.
58 :rtype: None
59 """
60 create_paths(log_path, do_not_log=True)
61
62=== modified file 'openlp/core/common/__init__.py'
63--- openlp/core/common/__init__.py 2019-05-04 11:49:20 +0000
64+++ openlp/core/common/__init__.py 2019-05-23 20:08:25 +0000
65@@ -142,7 +142,7 @@
66 """
67 Convert a path to a module name (i.e openlp.core.common)
68
69- :param openlp.core.common.path.Path path: The path to convert to a module name.
70+ :param pathlib.Path path: The path to convert to a module name.
71 :return: The module name.
72 :rtype: str
73 """
74@@ -371,7 +371,7 @@
75 """
76 Deletes a file from the system.
77
78- :param openlp.core.common.path.Path file_path: The file, including path, to delete.
79+ :param pathlib.Path file_path: The file, including path, to delete.
80 :return: True if the deletion was successful, or the file never existed. False otherwise.
81 :rtype: bool
82 """
83@@ -407,7 +407,7 @@
84 """
85 Validate that the file is not an image file.
86
87- :param openlp.core.common.path.Path file_path: The file to be checked.
88+ :param pathlib.Path file_path: The file to be checked.
89 :return: If the file is not an image
90 :rtype: bool
91 """
92@@ -435,7 +435,7 @@
93 """
94 Function that checks whether a binary exists.
95
96- :param openlp.core.common.path.Path program_path: The full path to the binary to check.
97+ :param pathlib.Path program_path: The full path to the binary to check.
98 :return: program output to be parsed
99 :rtype: bytes
100 """
101@@ -462,7 +462,7 @@
102 """
103 Utility function to incrementally detect the file encoding.
104
105- :param openlp.core.common.path.Path file_path: Filename for the file to determine the encoding for.
106+ :param pathlib.Path file_path: Filename for the file to determine the encoding for.
107 :return: The name of the encoding detected
108 :rtype: str
109 """
110
111=== modified file 'openlp/core/common/applocation.py'
112--- openlp/core/common/applocation.py 2019-04-13 13:00:22 +0000
113+++ openlp/core/common/applocation.py 2019-05-23 20:08:25 +0000
114@@ -25,12 +25,13 @@
115 import logging
116 import os
117 import sys
118+from pathlib import Path
119
120 import appdirs
121
122 import openlp
123 from openlp.core.common import get_frozen_path, is_macosx, is_win
124-from openlp.core.common.path import Path, create_paths
125+from openlp.core.common.path import create_paths
126 from openlp.core.common.settings import Settings
127
128
129@@ -58,7 +59,7 @@
130
131 :param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*
132 :return: The requested path
133- :rtype: openlp.core.common.path.Path
134+ :rtype: Path
135 """
136 if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:
137 return get_frozen_path(FROZEN_APP_PATH, APP_PATH)
138@@ -75,7 +76,7 @@
139 Return the path OpenLP stores all its data under.
140
141 :return: The data path to use.
142- :rtype: openlp.core.common.path.Path
143+ :rtype: Path
144 """
145 # Check if we have a different data location.
146 if Settings().contains('advanced/data path'):
147@@ -95,7 +96,7 @@
148 :param str extension: Defaults to ''. The extension to search for. For example::
149 '.png'
150 :return: List of files found.
151- :rtype: list[openlp.core.common.path.Path]
152+ :rtype: list[Path]
153 """
154 path = AppLocation.get_data_path()
155 if section:
156@@ -112,7 +113,7 @@
157 Return the path a particular module stores its data under.
158
159 :param str section:
160- :rtype: openlp.core.common.path.Path
161+ :rtype: Path
162 """
163 path = AppLocation.get_data_path() / section
164 create_paths(path)
165@@ -125,7 +126,7 @@
166
167 :param dir_type: AppLocation Enum of the requested path type
168 :return: The requested path
169- :rtype: openlp.core.common.path.Path
170+ :rtype: Path
171 """
172 # If running from source, return the language directory from the source directory
173 if dir_type == AppLocation.LanguageDir:
174
175=== modified file 'openlp/core/common/httputils.py'
176--- openlp/core/common/httputils.py 2019-04-13 13:00:22 +0000
177+++ openlp/core/common/httputils.py 2019-05-23 20:08:25 +0000
178@@ -26,6 +26,7 @@
179 import logging
180 import sys
181 import time
182+from pathlib import Path
183 from random import randint
184 from tempfile import gettempdir
185
186@@ -33,7 +34,6 @@
187 from PyQt5 import QtCore
188
189 from openlp.core.common import trace_error_handler
190-from openlp.core.common.path import Path
191 from openlp.core.common.registry import Registry
192 from openlp.core.common.settings import ProxyMode, Settings
193 from openlp.core.threading import ThreadWorker
194
195=== modified file 'openlp/core/common/json.py'
196--- openlp/core/common/json.py 2019-04-13 13:00:22 +0000
197+++ openlp/core/common/json.py 2019-05-23 20:08:25 +0000
198@@ -19,14 +19,76 @@
199 # You should have received a copy of the GNU General Public License #
200 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
201 ##########################################################################
202+from contextlib import suppress
203 from json import JSONDecoder, JSONEncoder
204-
205-from openlp.core.common.path import Path
206-
207-
208-class OpenLPJsonDecoder(JSONDecoder):
209- """
210- Implement a custom JSONDecoder to handle Path objects
211+from pathlib import Path
212+
213+
214+_registered_classes = {}
215+
216+
217+class JSONMixin(object):
218+ """
219+ :class:`JSONMixin` is a mixin class to simplify the serialization of a subclass to JSON.
220+
221+ :cvar:`_json_keys` is used to specify the attributes of the subclass that you wish to serialize.
222+ :vartype _json_keys: list[str]
223+ :cvar:`_name` set to override the the subclass name, useful if using a `proxy` class
224+ :vartype _name: str
225+ """
226+ _json_keys = []
227+ _name = None
228+ _version = 1
229+
230+ def __init_subclass__(cls, register_names=None, **kwargs):
231+ """
232+ Register the subclass.
233+
234+ :param collections.Iterable[str] register_names: Alternative names to register instead of the class name
235+ :param kwargs: Other args to pass to the super method
236+ :return None:
237+ """
238+ super().__init_subclass__(**kwargs)
239+ for key in register_names or [cls.__name__]:
240+ _registered_classes[key] = cls
241+
242+ @classmethod
243+ def encode_json(cls, obj, **kwargs):
244+ """
245+ Create a instance of the subclass from the dictionary that has been constructed by the JSON representation.
246+ Only use the keys specified in :cvar:`_json_keys`.
247+
248+ :param dict[str] obj: The dictionary representation of the subclass (deserailized from the JSON)
249+ :param kwargs: Contains any extra parameters. Not used!
250+ :return: The desrialized object
251+ """
252+ return cls(**{key: obj[key] for key in cls._json_keys if obj.get(key) is not None})
253+
254+ @classmethod
255+ def attach_meta(cls, j_dict):
256+ """
257+ Attach meta data to the serialized dictionary.
258+
259+ :param dict[str] j_dict: The dictionary to update with the meta data
260+ :return None:
261+ """
262+ j_dict.update({'json_meta': {'class': cls._name or cls.__name__, 'version': cls._version}})
263+
264+ def json_object(self, **kwargs):
265+ """
266+ Create a dictionary that can be JSON decoded.
267+
268+ :param kwargs: Contains any extra parameters. Not used!
269+ :return dict[str]: The dictionary representation of this Path object.
270+ """
271+ j_dict = {key: self.__dict__[key] for key in self._json_keys if self.__dict__.get(key) is not None}
272+ self.attach_meta(j_dict)
273+ return j_dict
274+
275+
276+class OpenLPJSONDecoder(JSONDecoder):
277+ """
278+ Implement a custom JSONDecoder to extend compatibility to custom objects
279
280 Example Usage:
281 object = json.loads(json_string, cls=OpenLPJsonDecoder)
282@@ -45,23 +107,26 @@
283
284 def custom_object_hook(self, obj):
285 """
286- Implement a custom Path object decoder.
287+ Implement a custom object decoder.
288
289 :param dict obj: A decoded JSON object
290- :return: The original object literal, or a Path object if the object literal contains a key '__Path__'
291- :rtype: dict | openlp.core.common.path.Path
292+ :return: The custom object from the serialized data if the custom object is registered, else obj
293 """
294- if '__Path__' in obj:
295- obj = Path.encode_json(obj, **self.kwargs)
296+ try:
297+ key = obj['json_meta']['class']
298+ except KeyError:
299+ return obj
300+ if key in _registered_classes:
301+ return _registered_classes[key].encode_json(obj, **self.kwargs)
302 return obj
303
304
305-class OpenLPJsonEncoder(JSONEncoder):
306+class OpenLPJSONEncoder(JSONEncoder):
307 """
308- Implement a custom JSONEncoder to handle Path objects
309+ Implement a custom JSONEncoder to handle to extend compatibility to custom objects
310
311 Example Usage:
312- json_string = json.dumps(object, cls=OpenLPJsonEncoder)
313+ json_string = json.dumps(object, cls=OpenLPJSONEncoder)
314 """
315 def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
316 indent=None, separators=None, default=None, **kwargs):
317@@ -78,12 +143,57 @@
318
319 def custom_default(self, obj):
320 """
321- Convert any Path objects into a dictionary object which can be serialized.
322+ Convert any registered objects into a dictionary object which can be serialized.
323
324 :param object obj: The object to convert
325- :return: The serializable object
326- :rtype: dict
327+ :return dict: The serializable object
328 """
329- if isinstance(obj, Path):
330- return obj.json_object(**self.kwargs)
331+ if isinstance(obj, JSONMixin):
332+ return obj.json_object()
333+ elif obj.__class__.__name__ in _registered_classes:
334+ return _registered_classes[obj.__class__.__name__].json_object(obj)
335 return super().default(obj)
336+
337+
338+def is_serializable(obj):
339+ return obj.__class__.__name__ in _registered_classes
340+
341+
342+class PathSerializer(JSONMixin, register_names=('Path', 'PosixPath', 'WindowsPath')):
343+ """
344+ Implement a de/serializer for pathlib.Path objects
345+ """
346+ _name = 'Path'
347+
348+ @staticmethod
349+ def encode_json(obj, base_path=None, **kwargs):
350+ """
351+ Reimplement encode_json to create a Path object from a dictionary representation.
352+
353+ :param dict[str] obj: The dictionary representation
354+ :param Path base_path: If specified, an absolute path to base the relative path off of.
355+ :param kwargs: Contains any extra parameters. Not used!
356+ :return Path: The deserialized Path object
357+ """
358+ path = Path(*obj['parts'])
359+ if base_path and not path.is_absolute():
360+ return base_path / path
361+ return path
362+
363+ @classmethod
364+ def json_object(cls, obj, base_path=None, **kwargs):
365+ """
366+ Create a dictionary that can be JSON decoded.
367+
368+ :param Path base_path: If specified, an absolute path to make a relative path from.
369+ :param kwargs: Contains any extra parameters. Not used!
370+ :return: The dictionary representation of this Path object.
371+ :rtype: dict[tuple]
372+ """
373+ path = obj
374+ if base_path:
375+ with suppress(ValueError):
376+ path = path.relative_to(base_path)
377+ json_dict = {'parts': path.parts}
378+ cls.attach_meta(json_dict)
379+ return json_dict
380
381=== modified file 'openlp/core/common/path.py'
382--- openlp/core/common/path.py 2019-04-13 13:00:22 +0000
383+++ openlp/core/common/path.py 2019-05-23 20:08:25 +0000
384@@ -21,66 +21,11 @@
385 ##########################################################################
386 import logging
387 import shutil
388-from contextlib import suppress
389-
390-from openlp.core.common import is_win
391-
392-
393-if is_win():
394- from pathlib import WindowsPath as PathVariant # pragma: nocover
395-else:
396- from pathlib import PosixPath as PathVariant # pragma: nocover
397+from pathlib import Path
398
399 log = logging.getLogger(__name__)
400
401
402-class Path(PathVariant):
403- """
404- Subclass pathlib.Path, so we can add json conversion methods
405- """
406- @staticmethod
407- def encode_json(obj, base_path=None, **kwargs):
408- """
409- Create a Path object from a dictionary representation. The dictionary has been constructed by JSON encoding of
410- a JSON reprensation of a Path object.
411-
412- :param dict[str] obj: The dictionary representation
413- :param openlp.core.common.path.Path base_path: If specified, an absolute path to base the relative path off of.
414- :param kwargs: Contains any extra parameters. Not used!
415- :return: The reconstructed Path object
416- :rtype: openlp.core.common.path.Path
417- """
418- path = Path(*obj['__Path__'])
419- if base_path and not path.is_absolute():
420- return base_path / path
421- return path
422-
423- def json_object(self, base_path=None, **kwargs):
424- """
425- Create a dictionary that can be JSON decoded.
426-
427- :param openlp.core.common.path.Path base_path: If specified, an absolute path to make a relative path from.
428- :param kwargs: Contains any extra parameters. Not used!
429- :return: The dictionary representation of this Path object.
430- :rtype: dict[tuple]
431- """
432- path = self
433- if base_path:
434- with suppress(ValueError):
435- path = path.relative_to(base_path)
436- return {'__Path__': path.parts}
437-
438- def rmtree(self, ignore_errors=False, onerror=None):
439- """
440- Provide an interface to :func:`shutil.rmtree`
441-
442- :param bool ignore_errors: Ignore errors
443- :param onerror: Handler function to handle any errors
444- :rtype: None
445- """
446- shutil.rmtree(self, ignore_errors, onerror)
447-
448-
449 def replace_params(args, kwargs, params):
450 """
451 Apply a transformation function to the specified args or kwargs
452@@ -110,65 +55,11 @@
453 return tuple(args), kwargs
454
455
456-def copy(*args, **kwargs):
457- """
458- Wraps :func:`shutil.copy` so that we can accept Path objects.
459-
460- :param src openlp.core.common.path.Path: Takes a Path object which is then converted to a str object
461- :param dst openlp.core.common.path.Path: Takes a Path object which is then converted to a str object
462- :return: Converts the str object received from :func:`shutil.copy` to a Path or NoneType object
463- :rtype: openlp.core.common.path.Path | None
464-
465- See the following link for more information on the other parameters:
466- https://docs.python.org/3/library/shutil.html#shutil.copy
467- """
468-
469- args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
470-
471- return str_to_path(shutil.copy(*args, **kwargs))
472-
473-
474-def copyfile(*args, **kwargs):
475- """
476- Wraps :func:`shutil.copyfile` so that we can accept Path objects.
477-
478- :param openlp.core.common.path.Path src: Takes a Path object which is then converted to a str object
479- :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object
480- :return: Converts the str object received from :func:`shutil.copyfile` to a Path or NoneType object
481- :rtype: openlp.core.common.path.Path | None
482-
483- See the following link for more information on the other parameters:
484- https://docs.python.org/3/library/shutil.html#shutil.copyfile
485- """
486-
487- args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
488-
489- return str_to_path(shutil.copyfile(*args, **kwargs))
490-
491-
492-def copytree(*args, **kwargs):
493- """
494- Wraps :func:shutil.copytree` so that we can accept Path objects.
495-
496- :param openlp.core.common.path.Path src : Takes a Path object which is then converted to a str object
497- :param openlp.core.common.path.Path dst: Takes a Path object which is then converted to a str object
498- :return: Converts the str object received from :func:`shutil.copytree` to a Path or NoneType object
499- :rtype: openlp.core.common.path.Path | None
500-
501- See the following link for more information on the other parameters:
502- https://docs.python.org/3/library/shutil.html#shutil.copytree
503- """
504-
505- args, kwargs = replace_params(args, kwargs, ((0, 'src', path_to_str), (1, 'dst', path_to_str)))
506-
507- return str_to_path(shutil.copytree(*args, **kwargs))
508-
509-
510 def which(*args, **kwargs):
511 """
512 Wraps :func:shutil.which` so that it return a Path objects.
513
514- :rtype: openlp.core.common.Path
515+ :rtype: Path
516
517 See the following link for more information on the other parameters:
518 https://docs.python.org/3/library/shutil.html#shutil.which
519@@ -183,7 +74,7 @@
520 """
521 A utility function to convert a Path object or NoneType to a string equivalent.
522
523- :param openlp.core.common.path.Path | None path: The value to convert to a string
524+ :param Path | None path: The value to convert to a string
525 :return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
526 :rtype: str
527 """
528@@ -204,7 +95,7 @@
529
530 :param str string: The string to convert
531 :return: None if :param:`string` is empty, or a Path object representation of :param:`string`
532- :rtype: openlp.core.common.path.Path | None
533+ :rtype: Path | None
534 """
535 if not isinstance(string, str):
536 log.error('parameter \'string\' must be of type str, got {} which is a {} instead'.format(string, type(string)))
537@@ -218,7 +109,7 @@
538 """
539 Create one or more paths
540
541- :param openlp.core.common.path.Path paths: The paths to create
542+ :param Path paths: The paths to create
543 :param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready.
544 :rtype: None
545 """
546@@ -239,7 +130,7 @@
547
548 :param list[str] file_names: The list of file names to convert.
549 :return: The list converted to file paths
550- :rtype: openlp.core.common.path.Path
551+ :rtype: Path
552 """
553 if file_names:
554 return [str_to_path(file_name) for file_name in file_names]
555
556=== modified file 'openlp/core/common/settings.py'
557--- openlp/core/common/settings.py 2019-05-04 19:47:06 +0000
558+++ openlp/core/common/settings.py 2019-05-23 20:08:25 +0000
559@@ -27,13 +27,14 @@
560 import logging
561 import os
562 from enum import IntEnum
563+from pathlib import Path
564 from tempfile import gettempdir
565
566 from PyQt5 import QtCore, QtGui
567
568 from openlp.core.common import SlideLimits, ThemeLevel, is_linux, is_win
569-from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
570-from openlp.core.common.path import Path, files_to_paths, str_to_path
571+from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder, is_serializable
572+from openlp.core.common.path import files_to_paths, str_to_path
573
574
575 log = logging.getLogger(__name__)
576@@ -337,7 +338,7 @@
577
578 Does not affect existing Settings objects.
579
580- :param openlp.core.common.path.Path ini_path: ini file path
581+ :param Path ini_path: ini file path
582 :rtype: None
583 """
584 Settings.__file_path__ = str(ini_path)
585@@ -584,8 +585,9 @@
586 :param value: The value to save
587 :rtype: None
588 """
589- if isinstance(value, (Path, dict)) or (isinstance(value, list) and value and isinstance(value[0], Path)):
590- value = json.dumps(value, cls=OpenLPJsonEncoder)
591+ if is_serializable(value) or isinstance(value, dict) or \
592+ (isinstance(value, list) and value and is_serializable(value[0])):
593+ value = json.dumps(value, cls=OpenLPJSONEncoder)
594 super().setValue(key, value)
595
596 def _convert_value(self, setting, default_value):
597@@ -611,8 +613,8 @@
598 elif isinstance(default_value, dict):
599 return {}
600 elif isinstance(setting, str):
601- if '__Path__' in setting or setting.startswith('{'):
602- return json.loads(setting, cls=OpenLPJsonDecoder)
603+ if 'json_meta' in setting or setting.startswith('{'):
604+ return json.loads(setting, cls=OpenLPJSONDecoder)
605 # Convert the setting to the correct type.
606 if isinstance(default_value, bool):
607 if isinstance(setting, bool):
608@@ -629,7 +631,7 @@
609 """
610 Export the settings to file.
611
612- :param openlp.core.common.path.Path dest_path: The file path to create the export file.
613+ :param Path dest_path: The file path to create the export file.
614 :return: Success
615 :rtype: bool
616 """
617
618=== modified file 'openlp/core/display/window.py'
619--- openlp/core/display/window.py 2019-05-04 09:13:29 +0000
620+++ openlp/core/display/window.py 2019-05-23 20:08:25 +0000
621@@ -249,18 +249,18 @@
622 """
623 Set images in the display
624 """
625- for image in images:
626- if not image['path'].startswith('file://'):
627- image['path'] = 'file://' + image['path']
628- json_images = json.dumps(images)
629+ imagesr = copy.deepcopy(images)
630+ for image in imagesr:
631+ image['path'] = image['path'].as_uri()
632+ json_images = json.dumps(imagesr)
633 self.run_javascript('Display.setImageSlides({images});'.format(images=json_images))
634
635 def load_video(self, video):
636 """
637 Load video in the display
638 """
639- if not video['path'].startswith('file://'):
640- video['path'] = 'file://' + video['path']
641+ video = copy.deepcopy(video)
642+ video['path'] = video['path'].as_uri()
643 json_video = json.dumps(video)
644 self.run_javascript('Display.setVideo({video});'.format(video=json_video))
645
646
647=== modified file 'openlp/core/lib/__init__.py'
648--- openlp/core/lib/__init__.py 2019-04-13 13:00:22 +0000
649+++ openlp/core/lib/__init__.py 2019-05-23 20:08:25 +0000
650@@ -24,11 +24,11 @@
651 OpenLP work.
652 """
653 import logging
654+from pathlib import Path
655
656 from PyQt5 import QtCore, QtGui, QtWidgets
657
658 from openlp.core.common.i18n import translate
659-from openlp.core.common.path import Path
660
661 log = logging.getLogger(__name__ + '.__init__')
662
663@@ -181,7 +181,7 @@
664 returns False. If there is an error loading the file or the content can't be decoded then the function will return
665 None.
666
667- :param openlp.core.common.path.Path text_file_path: The path to the file.
668+ :param Path text_file_path: The path to the file.
669 :return: The contents of the file, False if the file does not exist, or None if there is an Error reading or
670 decoding the file.
671 :rtype: str | False | None
672@@ -263,8 +263,8 @@
673 """
674 Create a thumbnail from the given image path and depending on ``return_icon`` it returns an icon from this thumb.
675
676- :param openlp.core.common.path.Path image_path: The image file to create the icon from.
677- :param openlp.core.common.path.Path thumb_path: The filename to save the thumbnail to.
678+ :param Path image_path: The image file to create the icon from.
679+ :param Path thumb_path: The filename to save the thumbnail to.
680 :param return_icon: States if an icon should be build and returned from the thumb. Defaults to ``True``.
681 :param size: Allows to state a own size (QtCore.QSize) to use. Defaults to ``None``, which means that a default
682 height of 88 is used.
683@@ -311,8 +311,8 @@
684 Validates whether an file's thumb still exists and if is up to date. **Note**, you must **not** call this function,
685 before checking the existence of the file.
686
687- :param openlp.core.common.path.Path file_path: The path to the file. The file **must** exist!
688- :param openlp.core.common.path.Path thumb_path: The path to the thumb.
689+ :param Path file_path: The path to the file. The file **must** exist!
690+ :param Path thumb_path: The path to the thumb.
691 :return: Has the image changed since the thumb was created?
692 :rtype: bool
693 """
694
695=== modified file 'openlp/core/lib/db.py'
696--- openlp/core/lib/db.py 2019-04-13 13:00:22 +0000
697+++ openlp/core/lib/db.py 2019-05-23 20:08:25 +0000
698@@ -40,7 +40,7 @@
699 from openlp.core.common import delete_file
700 from openlp.core.common.applocation import AppLocation
701 from openlp.core.common.i18n import translate
702-from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
703+from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
704 from openlp.core.common.settings import Settings
705 from openlp.core.lib.ui import critical_error_message_box
706
707@@ -132,7 +132,7 @@
708 Create a path to a database from the plugin name and database name
709
710 :param plugin_name: Name of plugin
711- :param openlp.core.common.path.Path | str | None db_file_name: File name of database
712+ :param pathlib.Path | str | None db_file_name: File name of database
713 :return: The path to the database
714 :rtype: str
715 """
716@@ -150,7 +150,7 @@
717 Log and report to the user that a database cannot be loaded
718
719 :param plugin_name: Name of plugin
720- :param openlp.core.common.path.Path db_file_path: File name of database
721+ :param pathlib.Path db_file_path: File name of database
722 :return: None
723 """
724 db_path = get_db_path(plugin_name, db_file_path)
725@@ -165,8 +165,8 @@
726 Construct the connection string for a database.
727
728 :param plugin_name: The name of the plugin for the database creation.
729- :param openlp.core.common.path.Path | str | None db_file_name: The database file name. Defaults to None resulting
730- in the plugin_name being used.
731+ :param pathlib.Path | str | None db_file_name: The database file name. Defaults to None resulting in the plugin_name
732+ being used.
733 :return: The database URL
734 :rtype: str
735 """
736@@ -215,7 +215,7 @@
737 Create a PathType for storing Path objects with SQLAlchemy. Behind the scenes we convert the Path object to a JSON
738 representation and store it as a Unicode type
739 """
740- impl = types.UnicodeText
741+ impl = types.Unicode
742
743 def coerce_compared_value(self, op, value):
744 """
745@@ -224,10 +224,8 @@
746
747 :param op: The operation being carried out. Not used, as we only care about the type that is being used with the
748 operation.
749- :param openlp.core.common.path.Path | str value: The value being used for the comparison. Most likely a Path
750- Object or str.
751- :return: The coerced value stored in the db
752- :rtype: PathType or UnicodeText
753+ :param pathlib.Path | str value: The value being used for the comparison. Most likely a Path Object or str.
754+ :return PathType | UnicodeText: The coerced value stored in the db
755 """
756 if isinstance(value, str):
757 return UnicodeText()
758@@ -238,13 +236,12 @@
759 """
760 Convert the Path object to a JSON representation
761
762- :param openlp.core.common.path.Path value: The value to convert
763+ :param pathlib.Path value: The value to convert
764 :param dialect: Not used
765- :return: The Path object as a JSON string
766- :rtype: str
767+ :return str: The Path object as a JSON string
768 """
769 data_path = AppLocation.get_data_path()
770- return json.dumps(value, cls=OpenLPJsonEncoder, base_path=data_path)
771+ return json.dumps(value, cls=OpenLPJSONEncoder, base_path=data_path)
772
773 def process_result_value(self, value, dialect):
774 """
775@@ -253,10 +250,10 @@
776 :param types.UnicodeText value: The value to convert
777 :param dialect: Not used
778 :return: The JSON object converted Python object (in this case it should be a Path object)
779- :rtype: openlp.core.common.path.Path
780+ :rtype: pathlib.Path
781 """
782 data_path = AppLocation.get_data_path()
783- return json.loads(value, cls=OpenLPJsonDecoder, base_path=data_path)
784+ return json.loads(value, cls=OpenLPJSONDecoder, base_path=data_path)
785
786
787 def upgrade_db(url, upgrade):
788@@ -351,8 +348,8 @@
789
790 :param plugin_name: The name to setup paths and settings section names
791 :param init_schema: The init_schema function for this database
792- :param openlp.core.common.path.Path db_file_path: The file name to use for this database. Defaults to None
793- resulting in the plugin_name being used.
794+ :param pathlib.Path | None db_file_path: The file name to use for this database. Defaults to None resulting in
795+ the plugin_name being used.
796 :param upgrade_mod: The upgrade_schema function for this database
797 """
798 super().__init__()
799
800=== modified file 'openlp/core/lib/mediamanageritem.py'
801--- openlp/core/lib/mediamanageritem.py 2019-05-04 18:25:59 +0000
802+++ openlp/core/lib/mediamanageritem.py 2019-05-23 20:08:25 +0000
803@@ -369,7 +369,7 @@
804 Process a list for files either from the File Dialog or from Drag and
805 Drop
806
807- :param list[openlp.core.common.path.Path] file_paths: The files to be loaded.
808+ :param list[pathlib.Path] file_paths: The files to be loaded.
809 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
810 """
811 full_list = []
812@@ -410,7 +410,7 @@
813 """
814 Return the current list of files
815
816- :rtype: list[openlp.core.common.path.Path]
817+ :rtype: list[pathlib.Path]
818 """
819 file_paths = []
820 for index in range(self.list_view.count()):
821@@ -462,7 +462,7 @@
822 :param item: The database item to be used to build the service item
823 :param remote: Was this remote triggered (False)
824 :param context: The service context
825- :param openlp.core.common.path.Path file_path:
826+ :param pathlib.Path file_path:
827 """
828 raise NotImplementedError('MediaManagerItem.generate_slide_data needs to be defined by the plugin')
829
830
831=== modified file 'openlp/core/lib/serviceitem.py'
832--- openlp/core/lib/serviceitem.py 2019-04-13 13:00:22 +0000
833+++ openlp/core/lib/serviceitem.py 2019-05-23 20:08:25 +0000
834@@ -29,6 +29,7 @@
835 import os
836 import uuid
837 from copy import deepcopy
838+from pathlib import Path
839
840 from PyQt5 import QtGui
841
842@@ -37,7 +38,6 @@
843 from openlp.core.common.applocation import AppLocation
844 from openlp.core.common.i18n import translate
845 from openlp.core.common.mixins import RegistryProperties
846-from openlp.core.common.path import Path
847 from openlp.core.common.settings import Settings
848 from openlp.core.display.render import remove_tags, render_tags
849 from openlp.core.lib import ItemCapabilities
850@@ -264,8 +264,8 @@
851 if image and not self.has_original_files and self.name == 'presentations':
852 file_location = os.path.join(path, file_name)
853 file_location_hash = md5_hash(file_location.encode('utf-8'))
854- image = os.path.join(str(AppLocation.get_section_data_path(self.name)), 'thumbnails',
855- file_location_hash, ntpath.basename(image)) # TODO: Pathlib
856+ image = os.path.join(AppLocation.get_section_data_path(self.name), 'thumbnails', file_location_hash,
857+ ntpath.basename(image)) # TODO: Pathlib
858 self.slides.append({'title': file_name, 'image': image, 'path': path, 'display_title': display_title,
859 'notes': notes, 'thumbnail': image})
860 # if self.is_capable(ItemCapabilities.HasThumbnails):
861
862=== modified file 'openlp/core/lib/theme.py'
863--- openlp/core/lib/theme.py 2019-05-04 09:13:29 +0000
864+++ openlp/core/lib/theme.py 2019-05-23 20:08:25 +0000
865@@ -29,7 +29,7 @@
866
867 from openlp.core.common import de_hump
868 from openlp.core.common.applocation import AppLocation
869-from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
870+from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
871 from openlp.core.display.screens import ScreenList
872 from openlp.core.lib import get_text_file_string, str_to_bool
873
874@@ -190,7 +190,7 @@
875 """
876 Add the path name to the image name so the background can be rendered.
877
878- :param openlp.core.common.path.Path path: The path name to be added.
879+ :param pathlib.Path path: The path name to be added.
880 :rtype: None
881 """
882 if self.background_type == 'image' or self.background_type == 'video':
883@@ -216,13 +216,13 @@
884 Convert the JSON file and expand it.
885
886 :param theme: the theme string
887- :param openlp.core.common.path.Path theme_path: The path to the theme
888+ :param pathlib.Path theme_path: The path to the theme
889 :rtype: None
890 """
891 if theme_path:
892- jsn = json.loads(theme, cls=OpenLPJsonDecoder, base_path=theme_path)
893+ jsn = json.loads(theme, cls=OpenLPJSONDecoder, base_path=theme_path)
894 else:
895- jsn = json.loads(theme, cls=OpenLPJsonDecoder)
896+ jsn = json.loads(theme, cls=OpenLPJSONDecoder)
897 self.expand_json(jsn)
898
899 def export_theme(self, theme_path=None):
900@@ -234,8 +234,8 @@
901 for attr, value in self.__dict__.items():
902 theme_data["{attr}".format(attr=attr)] = value
903 if theme_path:
904- return json.dumps(theme_data, cls=OpenLPJsonEncoder, base_path=theme_path)
905- return json.dumps(theme_data, cls=OpenLPJsonEncoder)
906+ return json.dumps(theme_data, cls=OpenLPJSONEncoder, base_path=theme_path)
907+ return json.dumps(theme_data, cls=OpenLPJSONEncoder)
908
909 def parse(self, xml):
910 """
911
912=== modified file 'openlp/core/server.py'
913--- openlp/core/server.py 2019-05-04 09:13:29 +0000
914+++ openlp/core/server.py 2019-05-23 20:08:25 +0000
915@@ -19,10 +19,11 @@
916 # You should have received a copy of the GNU General Public License #
917 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
918 ##########################################################################
919+from pathlib import Path
920+
921 from PyQt5 import QtCore, QtNetwork
922
923 from openlp.core.common.mixins import LogMixin
924-from openlp.core.common.path import Path
925 from openlp.core.common.registry import Registry
926
927
928
929=== modified file 'openlp/core/ui/advancedtab.py'
930--- openlp/core/ui/advancedtab.py 2019-05-03 17:26:37 +0000
931+++ openlp/core/ui/advancedtab.py 2019-05-23 20:08:25 +0000
932@@ -518,7 +518,7 @@
933 """
934 Handle the `editPathChanged` signal of the data_directory_path_edit
935
936- :param openlp.core.common.path.Path new_path: The new path
937+ :param pathlib.Path new_path: The new path
938 :rtype: None
939 """
940 # Make sure they want to change the data.
941@@ -552,7 +552,7 @@
942 """
943 Check if there's already data in the target directory.
944
945- :param openlp.core.common.path.Path data_path: The target directory to check
946+ :param pathlib.Path data_path: The target directory to check
947 """
948 if (data_path / 'songs').exists():
949 self.data_exists = True
950
951=== modified file 'openlp/core/ui/firsttimeform.py'
952--- openlp/core/ui/firsttimeform.py 2019-04-13 13:00:22 +0000
953+++ openlp/core/ui/firsttimeform.py 2019-05-23 20:08:25 +0000
954@@ -28,6 +28,7 @@
955 import urllib.error
956 import urllib.parse
957 import urllib.request
958+from pathlib import Path
959 from tempfile import gettempdir
960
961 from PyQt5 import QtCore, QtWidgets
962@@ -37,7 +38,7 @@
963 from openlp.core.common.httputils import DownloadWorker, download_file, get_url_file_size, get_web_page
964 from openlp.core.common.i18n import translate
965 from openlp.core.common.mixins import RegistryProperties
966-from openlp.core.common.path import Path, create_paths
967+from openlp.core.common.path import create_paths
968 from openlp.core.common.registry import Registry
969 from openlp.core.common.settings import Settings
970 from openlp.core.lib import build_icon
971
972=== modified file 'openlp/core/ui/generaltab.py'
973--- openlp/core/ui/generaltab.py 2019-05-03 17:26:37 +0000
974+++ openlp/core/ui/generaltab.py 2019-05-23 20:08:25 +0000
975@@ -23,12 +23,12 @@
976 The general tab of the configuration dialog.
977 """
978 import logging
979+from pathlib import Path
980
981 from PyQt5 import QtGui, QtWidgets
982
983 from openlp.core.common import get_images_filter
984 from openlp.core.common.i18n import UiStrings, translate
985-from openlp.core.common.path import Path
986 from openlp.core.common.settings import Settings
987 from openlp.core.display.screens import ScreenList
988 from openlp.core.lib.settingstab import SettingsTab
989
990=== modified file 'openlp/core/ui/mainwindow.py'
991--- openlp/core/ui/mainwindow.py 2019-05-04 12:05:53 +0000
992+++ openlp/core/ui/mainwindow.py 2019-05-23 20:08:25 +0000
993@@ -23,9 +23,11 @@
994 This is the main window, where all the action happens.
995 """
996 import os
997+import shutil
998 from datetime import datetime
999 from distutils import dir_util
1000 from distutils.errors import DistutilsFileError
1001+from pathlib import Path
1002 from tempfile import gettempdir
1003
1004 from PyQt5 import QtCore, QtGui, QtWidgets
1005@@ -38,7 +40,7 @@
1006 from openlp.core.common.applocation import AppLocation
1007 from openlp.core.common.i18n import LanguageManager, UiStrings, translate
1008 from openlp.core.common.mixins import LogMixin, RegistryProperties
1009-from openlp.core.common.path import Path, copyfile, create_paths
1010+from openlp.core.common.path import create_paths
1011 from openlp.core.common.registry import Registry
1012 from openlp.core.common.settings import Settings
1013 from openlp.core.display.screens import ScreenList
1014@@ -658,7 +660,7 @@
1015 plugin.first_time()
1016 self.application.process_events()
1017 temp_path = Path(gettempdir(), 'openlp')
1018- temp_path.rmtree(True)
1019+ shutil.rmtree(temp_path, True)
1020
1021 def on_first_time_wizard_clicked(self):
1022 """
1023@@ -861,7 +863,7 @@
1024 temp_dir_path = Path(gettempdir(), 'openlp')
1025 create_paths(temp_dir_path)
1026 temp_config_path = temp_dir_path / import_file_path.name
1027- copyfile(import_file_path, temp_config_path)
1028+ shutil.copyfile(import_file_path, temp_config_path)
1029 settings = Settings()
1030 import_settings = Settings(str(temp_config_path), Settings.IniFormat)
1031
1032
1033=== modified file 'openlp/core/ui/servicemanager.py'
1034--- openlp/core/ui/servicemanager.py 2019-05-04 18:25:59 +0000
1035+++ openlp/core/ui/servicemanager.py 2019-05-23 20:08:25 +0000
1036@@ -24,10 +24,12 @@
1037 """
1038 import html
1039 import json
1040+import shutil
1041 import os
1042 import zipfile
1043 from contextlib import suppress
1044 from datetime import datetime, timedelta
1045+from pathlib import Path
1046 from tempfile import NamedTemporaryFile
1047
1048 from PyQt5 import QtCore, QtGui, QtWidgets
1049@@ -36,9 +38,8 @@
1050 from openlp.core.common.actions import ActionList, CategoryOrder
1051 from openlp.core.common.applocation import AppLocation
1052 from openlp.core.common.i18n import UiStrings, format_time, translate
1053-from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
1054+from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
1055 from openlp.core.common.mixins import LogMixin, RegistryProperties
1056-from openlp.core.common.path import Path
1057 from openlp.core.common.registry import Registry, RegistryBase
1058 from openlp.core.common.settings import Settings
1059 from openlp.core.lib import build_icon
1060@@ -371,7 +372,7 @@
1061 """
1062 Setter for service file.
1063
1064- :param openlp.core.common.path.Path file_path: The service file name
1065+ :param Path file_path: The service file name
1066 :rtype: None
1067 """
1068 self._service_path = file_path
1069@@ -386,7 +387,7 @@
1070 """
1071 Return the current file name including path.
1072
1073- :rtype: openlp.core.common.path.Path
1074+ :rtype: Path
1075 """
1076 return self._service_path
1077
1078@@ -443,7 +444,7 @@
1079 """
1080 Loads the service file and saves the existing one it there is one unchanged.
1081
1082- :param openlp.core.common.path.Path | None file_path: The service file to the loaded.
1083+ :param Path | None file_path: The service file to the loaded.
1084 """
1085 if self.is_modified():
1086 result = self.save_modified_service()
1087@@ -518,7 +519,7 @@
1088 Get a list of files used in the service and files that are missing.
1089
1090 :return: A list of files used in the service that exist, and a list of files that don't.
1091- :rtype: (list[openlp.core.common.path.Path], list[openlp.core.common.path.Path])
1092+ :rtype: (list[Path], list[Path])
1093 """
1094 write_list = []
1095 missing_list = []
1096@@ -581,7 +582,7 @@
1097 # Add the service item to the service.
1098 service.append({'serviceitem': service_item})
1099 self.repaint_service_list(-1, -1)
1100- service_content = json.dumps(service, cls=OpenLPJsonEncoder)
1101+ service_content = json.dumps(service, cls=OpenLPJSONEncoder)
1102 service_content_size = len(bytes(service_content, encoding='utf-8'))
1103 total_size = service_content_size
1104 for file_item in write_list:
1105@@ -679,7 +680,7 @@
1106 """
1107 Load an existing service file.
1108
1109- :param openlp.core.common.path.Path file_path: The service file to load.
1110+ :param Path file_path: The service file to load.
1111 """
1112 if not file_path.exists():
1113 return False
1114@@ -702,7 +703,7 @@
1115 zip_file.extract(zip_info, self.service_path)
1116 self.main_window.increment_progress_bar(zip_info.compress_size)
1117 if service_data:
1118- items = json.loads(service_data, cls=OpenLPJsonDecoder)
1119+ items = json.loads(service_data, cls=OpenLPJSONDecoder)
1120 self.new_file()
1121 self.process_service_items(items)
1122 self.set_file_name(file_path)
1123@@ -1250,7 +1251,7 @@
1124 delete_file(file_path)
1125 audio_path = self.service_path / 'audio'
1126 if audio_path.exists():
1127- audio_path.rmtree(True)
1128+ shutil.rmtree(audio_path, True)
1129
1130 def on_theme_combo_box_selected(self, current_index):
1131 """
1132
1133=== modified file 'openlp/core/ui/slidecontroller.py'
1134--- openlp/core/ui/slidecontroller.py 2019-05-07 16:56:21 +0000
1135+++ openlp/core/ui/slidecontroller.py 2019-05-23 20:08:25 +0000
1136@@ -25,6 +25,7 @@
1137 import copy
1138 import datetime
1139 from collections import deque
1140+from pathlib import Path
1141 from threading import Lock
1142
1143 from PyQt5 import QtCore, QtGui, QtWidgets
1144@@ -33,7 +34,6 @@
1145 from openlp.core.common.actions import ActionList, CategoryOrder
1146 from openlp.core.common.i18n import UiStrings, translate
1147 from openlp.core.common.mixins import LogMixin, RegistryProperties
1148-from openlp.core.common.path import Path
1149 from openlp.core.common.registry import Registry, RegistryBase
1150 from openlp.core.common.settings import Settings
1151 from openlp.core.display.screens import ScreenList
1152
1153=== modified file 'openlp/core/ui/themeform.py'
1154--- openlp/core/ui/themeform.py 2019-04-13 13:00:22 +0000
1155+++ openlp/core/ui/themeform.py 2019-05-23 20:08:25 +0000
1156@@ -462,7 +462,7 @@
1157 """
1158 Handle the `pathEditChanged` signal from image_path_edit
1159
1160- :param openlp.core.common.path.Path new_path: Path to the new image
1161+ :param pathlib.Path new_path: Path to the new image
1162 :rtype: None
1163 """
1164 self.theme.background_filename = new_path
1165@@ -472,7 +472,7 @@
1166 """
1167 Handle the `pathEditChanged` signal from video_path_edit
1168
1169- :param openlp.core.common.path.Path new_path: Path to the new video
1170+ :param pathlib.Path new_path: Path to the new video
1171 :rtype: None
1172 """
1173 self.theme.background_filename = new_path
1174
1175=== modified file 'openlp/core/ui/thememanager.py'
1176--- openlp/core/ui/thememanager.py 2019-05-03 17:26:37 +0000
1177+++ openlp/core/ui/thememanager.py 2019-05-23 20:08:25 +0000
1178@@ -23,7 +23,9 @@
1179 The Theme Manager manages adding, deleteing and modifying of themes.
1180 """
1181 import os
1182+import shutil
1183 import zipfile
1184+from pathlib import Path
1185 from xml.etree.ElementTree import XML, ElementTree
1186
1187 from PyQt5 import QtCore, QtWidgets
1188@@ -32,7 +34,7 @@
1189 from openlp.core.common.applocation import AppLocation
1190 from openlp.core.common.i18n import UiStrings, get_locale_key, translate
1191 from openlp.core.common.mixins import LogMixin, RegistryProperties
1192-from openlp.core.common.path import Path, copyfile, create_paths
1193+from openlp.core.common.path import create_paths
1194 from openlp.core.common.registry import Registry, RegistryBase
1195 from openlp.core.common.settings import Settings
1196 from openlp.core.lib import build_icon, check_item_selected, create_thumb, get_text_file_string, validate_thumb
1197@@ -378,7 +380,7 @@
1198 delete_file(self.theme_path / thumb)
1199 delete_file(self.thumb_path / thumb)
1200 try:
1201- (self.theme_path / theme).rmtree()
1202+ shutil.rmtree(self.theme_path / theme)
1203 except OSError:
1204 self.log_exception('Error deleting theme {name}'.format(name=theme))
1205
1206@@ -415,7 +417,7 @@
1207 """
1208 Create the zipfile with the theme contents.
1209
1210- :param openlp.core.common.path.Path theme_path: Location where the zip file will be placed
1211+ :param Path theme_path: Location where the zip file will be placed
1212 :param str theme_name: The name of the theme to be exported
1213 :return: The success of creating the zip file
1214 :rtype: bool
1215@@ -433,7 +435,7 @@
1216 'The {theme_name} export failed because this error occurred: {err}')
1217 .format(theme_name=theme_name, err=ose.strerror))
1218 if theme_path.exists():
1219- theme_path.rmtree(ignore_errors=True)
1220+ shutil.rmtree(theme_path, ignore_errors=True)
1221 return False
1222
1223 def on_import_theme(self, checked=None):
1224@@ -557,8 +559,8 @@
1225 """
1226 Unzip the theme, remove the preview file if stored. Generate a new preview file. Check the XML theme version
1227 and upgrade if necessary.
1228- :param openlp.core.common.path.Path file_path:
1229- :param openlp.core.common.path.Path directory_path:
1230+ :param Path file_path:
1231+ :param Path directory_path:
1232 """
1233 self.log_debug('Unzipping theme {name}'.format(name=file_path))
1234 file_xml = None
1235@@ -642,8 +644,8 @@
1236 Called by theme maintenance Dialog to save the theme and to trigger the reload of the theme list
1237
1238 :param Theme theme: The theme data object.
1239- :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.
1240- :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to
1241+ :param Path image_source_path: Where the theme image is currently located.
1242+ :param Path image_destination_path: Where the Theme Image is to be saved to
1243 :rtype: None
1244 """
1245 self._write_theme(theme, image_source_path, image_destination_path)
1246@@ -653,8 +655,8 @@
1247 Writes the theme to the disk and handles the background image if necessary
1248
1249 :param Theme theme: The theme data object.
1250- :param openlp.core.common.path.Path image_source_path: Where the theme image is currently located.
1251- :param openlp.core.common.path.Path image_destination_path: Where the Theme Image is to be saved to
1252+ :param Path image_source_path: Where the theme image is currently located.
1253+ :param Path image_destination_path: Where the Theme Image is to be saved to
1254 :rtype: None
1255 """
1256 name = theme.theme_name
1257@@ -671,7 +673,7 @@
1258 delete_file(self.old_background_image_path)
1259 if image_source_path != image_destination_path:
1260 try:
1261- copyfile(image_source_path, image_destination_path)
1262+ shutil.copyfile(image_source_path, image_destination_path)
1263 except OSError:
1264 self.log_exception('Failed to save theme image')
1265 self.generate_and_save_image(name, theme)
1266@@ -718,7 +720,7 @@
1267 Return a theme object using information parsed from XML
1268
1269 :param theme_xml: The Theme data object.
1270- :param openlp.core.common.path.Path image_path: Where the theme image is stored
1271+ :param Path image_path: Where the theme image is stored
1272 :return: Theme data.
1273 :rtype: Theme
1274 """
1275@@ -732,7 +734,7 @@
1276 Return a theme object using information parsed from JSON
1277
1278 :param theme_json: The Theme data object.
1279- :param openlp.core.common.path.Path image_path: Where the theme image is stored
1280+ :param Path image_path: Where the theme image is stored
1281 :return: Theme data.
1282 :rtype: Theme
1283 """
1284
1285=== modified file 'openlp/core/widgets/dialogs.py'
1286--- openlp/core/widgets/dialogs.py 2019-05-04 09:13:29 +0000
1287+++ openlp/core/widgets/dialogs.py 2019-05-23 20:08:25 +0000
1288@@ -33,9 +33,9 @@
1289
1290 :type parent: QtWidgets.QWidget | None
1291 :type caption: str
1292- :type directory: openlp.core.common.path.Path
1293+ :type directory: pathlib.Path
1294 :type options: QtWidgets.QFileDialog.Options
1295- :rtype: openlp.core.common.path.Path
1296+ :rtype: pathlib.Path
1297 """
1298 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
1299
1300@@ -52,11 +52,11 @@
1301
1302 :type parent: QtWidgets.QWidget | None
1303 :type caption: str
1304- :type directory: openlp.core.common.path.Path
1305+ :type directory: pathlib.Path
1306 :type filter: str
1307 :type initialFilter: str
1308 :type options: QtWidgets.QFileDialog.Options
1309- :rtype: tuple[openlp.core.common.path.Path, str]
1310+ :rtype: tuple[pathlib.Path, str]
1311 """
1312 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
1313
1314@@ -73,11 +73,11 @@
1315
1316 :type parent: QtWidgets.QWidget | None
1317 :type caption: str
1318- :type directory: openlp.core.common.path.Path
1319+ :type directory: pathlib.Path
1320 :type filter: str
1321 :type initialFilter: str
1322 :type options: QtWidgets.QFileDialog.Options
1323- :rtype: tuple[list[openlp.core.common.path.Path], str]
1324+ :rtype: tuple[list[pathlib.Path], str]
1325 """
1326 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
1327
1328@@ -95,11 +95,11 @@
1329
1330 :type parent: QtWidgets.QWidget | None
1331 :type caption: str
1332- :type directory: openlp.core.common.path.Path
1333+ :type directory: pathlib.Path
1334 :type filter: str
1335 :type initialFilter: str
1336 :type options: QtWidgets.QFileDialog.Options
1337- :rtype: tuple[openlp.core.common.path.Path | None, str]
1338+ :rtype: tuple[pathlib.Path | None, str]
1339 """
1340 args, kwargs = replace_params(args, kwargs, ((2, 'directory', path_to_str),))
1341
1342
1343=== modified file 'openlp/core/widgets/edits.py'
1344--- openlp/core/widgets/edits.py 2019-04-28 19:21:23 +0000
1345+++ openlp/core/widgets/edits.py 2019-05-23 20:08:25 +0000
1346@@ -24,12 +24,13 @@
1347 """
1348 import logging
1349 import re
1350+from pathlib import Path
1351
1352 from PyQt5 import QtCore, QtGui, QtWidgets
1353
1354 from openlp.core.common import CONTROL_CHARS
1355 from openlp.core.common.i18n import UiStrings, translate
1356-from openlp.core.common.path import Path, path_to_str, str_to_path
1357+from openlp.core.common.path import path_to_str, str_to_path
1358 from openlp.core.common.settings import Settings
1359 from openlp.core.lib.formattingtags import FormattingTags
1360 from openlp.core.lib.ui import create_action, create_widget_action
1361@@ -207,7 +208,7 @@
1362
1363 :param QtWidget.QWidget | None: The parent of the widget. This is just passed to the super method.
1364 :param str dialog_caption: Used to customise the caption in the QFileDialog.
1365- :param openlp.core.common.path.Path default_path: The default path. This is set as the path when the revert
1366+ :param Path default_path: The default path. This is set as the path when the revert
1367 button is clicked
1368 :param bool show_revert: Used to determine if the 'revert button' should be visible.
1369 :rtype: None
1370@@ -250,7 +251,7 @@
1371 A property getter method to return the selected path.
1372
1373 :return: The selected path
1374- :rtype: openlp.core.common.path.Path
1375+ :rtype: Path
1376 """
1377 return self._path
1378
1379@@ -259,7 +260,7 @@
1380 """
1381 A Property setter method to set the selected path
1382
1383- :param openlp.core.common.path.Path path: The path to set the widget to
1384+ :param Path path: The path to set the widget to
1385 :rtype: None
1386 """
1387 self._path = path
1388@@ -348,7 +349,7 @@
1389
1390 Emits the pathChanged Signal
1391
1392- :param openlp.core.common.path.Path path: The new path
1393+ :param Path path: The new path
1394 :rtype: None
1395 """
1396 if self._path != path:
1397
1398=== modified file 'openlp/core/widgets/views.py'
1399--- openlp/core/widgets/views.py 2019-05-04 09:13:29 +0000
1400+++ openlp/core/widgets/views.py 2019-05-23 20:08:25 +0000
1401@@ -23,12 +23,13 @@
1402 The :mod:`listpreviewwidget` is a widget that lists the slides in the slide controller.
1403 It is based on a QTableWidget but represents its contents in list form.
1404 """
1405+from pathlib import Path
1406+
1407 from PyQt5 import QtCore, QtGui, QtWidgets
1408
1409 from openlp.core.common import is_win
1410 from openlp.core.common.i18n import UiStrings
1411 from openlp.core.common.mixins import RegistryProperties
1412-from openlp.core.common.path import Path
1413 from openlp.core.common.registry import Registry
1414 from openlp.core.common.settings import Settings
1415 from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
1416@@ -41,7 +42,7 @@
1417
1418 :param QtCore.QMimeData mime_data: The mime data from the drag and drop opperation.
1419 :return: A list of file paths that were dropped
1420- :rtype: list[openlp.core.common.path.Path]
1421+ :rtype: list[Path]
1422 """
1423 file_paths = []
1424 for url in mime_data.urls():
1425@@ -201,14 +202,14 @@
1426 label.setScaledContents(True)
1427 if self.service_item.is_command():
1428 if self.service_item.is_capable(ItemCapabilities.HasThumbnails):
1429- pixmap = QtGui.QPixmap(remove_url_prefix(slide['thumbnail']))
1430+ pixmap = QtGui.QPixmap(str(slide['thumbnail']))
1431 else:
1432 if isinstance(slide['image'], QtGui.QIcon):
1433 pixmap = slide['image'].pixmap(QtCore.QSize(32, 32))
1434 else:
1435- pixmap = QtGui.QPixmap(remove_url_prefix(slide['image']))
1436+ pixmap = QtGui.QPixmap(str(slide['image']))
1437 else:
1438- pixmap = QtGui.QPixmap(remove_url_prefix(slide['path']))
1439+ pixmap = QtGui.QPixmap(str(slide['path']))
1440 label.setPixmap(pixmap)
1441 container = QtWidgets.QWidget()
1442 layout = AspectRatioLayout(container, self.screen_ratio)
1443
1444=== modified file 'openlp/plugins/bibles/lib/bibleimport.py'
1445--- openlp/plugins/bibles/lib/bibleimport.py 2019-04-13 13:00:22 +0000
1446+++ openlp/plugins/bibles/lib/bibleimport.py 2019-05-23 20:08:25 +0000
1447@@ -48,7 +48,7 @@
1448 """
1449 Check if the supplied file is compressed
1450
1451- :param openlp.core.common.path.Path file_path: A path to the file to check
1452+ :param pathlib.Path file_path: A path to the file to check
1453 """
1454 if is_zipfile(file_path):
1455 critical_error_message_box(
1456
1457=== modified file 'openlp/plugins/bibles/lib/db.py'
1458--- openlp/plugins/bibles/lib/db.py 2019-04-13 13:00:22 +0000
1459+++ openlp/plugins/bibles/lib/db.py 2019-05-23 20:08:25 +0000
1460@@ -24,6 +24,7 @@
1461 import re
1462 import sqlite3
1463 import time
1464+from pathlib import Path
1465
1466 import chardet
1467 from PyQt5 import QtCore
1468@@ -35,7 +36,6 @@
1469 from openlp.core.common import clean_filename
1470 from openlp.core.common.applocation import AppLocation
1471 from openlp.core.common.i18n import translate
1472-from openlp.core.common.path import Path
1473 from openlp.core.lib.db import BaseModel, Manager, init_db
1474 from openlp.core.lib.ui import critical_error_message_box
1475 from openlp.plugins.bibles.lib import BibleStrings, LanguageSelection, upgrade
1476@@ -130,13 +130,13 @@
1477 :param parent:
1478 :param kwargs:
1479 ``path``
1480- The path to the bible database file. Type: openlp.core.common.path.Path
1481+ The path to the bible database file. Type: Path
1482
1483 ``name``
1484 The name of the database. This is also used as the file name for SQLite databases.
1485
1486 ``file``
1487- Type: openlp.core.common.path.Path
1488+ Type: Path
1489
1490 :rtype: None
1491 """
1492
1493=== modified file 'openlp/plugins/bibles/lib/importers/csvbible.py'
1494--- openlp/plugins/bibles/lib/importers/csvbible.py 2019-05-04 09:13:29 +0000
1495+++ openlp/plugins/bibles/lib/importers/csvbible.py 2019-05-23 20:08:25 +0000
1496@@ -96,7 +96,7 @@
1497 """
1498 Parse the supplied CSV file.
1499
1500- :param openlp.core.common.path.Path file_path: The name of the file to parse.
1501+ :param pathlib.Path file_path: The name of the file to parse.
1502 :param namedtuple results_tuple: The namedtuple to use to store the results.
1503 :return: An list of namedtuples of type results_tuple
1504 :rtype: list[namedtuple]
1505
1506=== modified file 'openlp/plugins/bibles/lib/importers/wordproject.py'
1507--- openlp/plugins/bibles/lib/importers/wordproject.py 2019-04-13 13:00:22 +0000
1508+++ openlp/plugins/bibles/lib/importers/wordproject.py 2019-05-23 20:08:25 +0000
1509@@ -21,12 +21,12 @@
1510 ##########################################################################
1511 import logging
1512 import re
1513+from pathlib import Path
1514 from tempfile import TemporaryDirectory
1515 from zipfile import ZipFile
1516
1517 from bs4 import BeautifulSoup, NavigableString, Tag
1518
1519-from openlp.core.common.path import Path
1520 from openlp.plugins.bibles.lib.bibleimport import BibleImport
1521
1522
1523
1524=== modified file 'openlp/plugins/bibles/lib/manager.py'
1525--- openlp/plugins/bibles/lib/manager.py 2019-04-28 19:21:23 +0000
1526+++ openlp/plugins/bibles/lib/manager.py 2019-05-23 20:08:25 +0000
1527@@ -20,12 +20,12 @@
1528 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
1529 ##########################################################################
1530 import logging
1531+from pathlib import Path
1532
1533 from openlp.core.common import delete_file
1534 from openlp.core.common.applocation import AppLocation
1535 from openlp.core.common.i18n import UiStrings, translate
1536 from openlp.core.common.mixins import LogMixin, RegistryProperties
1537-from openlp.core.common.path import Path
1538 from openlp.core.common.settings import Settings
1539 from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
1540 from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
1541
1542=== modified file 'openlp/plugins/images/lib/mediaitem.py'
1543--- openlp/plugins/images/lib/mediaitem.py 2019-05-04 09:13:29 +0000
1544+++ openlp/plugins/images/lib/mediaitem.py 2019-05-23 20:08:25 +0000
1545@@ -21,13 +21,14 @@
1546 ##########################################################################
1547
1548 import logging
1549+from pathlib import Path
1550
1551 from PyQt5 import QtCore, QtGui, QtWidgets
1552
1553 from openlp.core.common import delete_file, get_images_filter
1554 from openlp.core.common.applocation import AppLocation
1555 from openlp.core.common.i18n import UiStrings, get_natural_key, translate
1556-from openlp.core.common.path import Path, create_paths
1557+from openlp.core.common.path import create_paths
1558 from openlp.core.common.registry import Registry
1559 from openlp.core.common.settings import Settings
1560 from openlp.core.lib import ServiceItemContext, build_icon, check_item_selected, create_thumb, validate_thumb
1561@@ -343,7 +344,7 @@
1562
1563 :param openlp.plugins.images.lib.db.ImageFilenames image: The image to generate the thumbnail path for.
1564 :return: A path to the thumbnail
1565- :rtype: openlp.core.common.path.Path
1566+ :rtype: Path
1567 """
1568 ext = image.file_path.suffix.lower()
1569 return self.service_path / '{name:d}{ext}'.format(name=image.id, ext=ext)
1570@@ -401,7 +402,7 @@
1571 Process a list for files either from the File Dialog or from Drag and Drop.
1572 This method is overloaded from MediaManagerItem.
1573
1574- :param list[openlp.core.common.path.Path] file_paths: A List of paths to be loaded
1575+ :param list[Path] file_paths: A List of paths to be loaded
1576 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
1577 """
1578 self.application.set_normal_cursor()
1579@@ -413,7 +414,7 @@
1580 """
1581 Add new images to the database. This method is called when adding images using the Add button or DnD.
1582
1583- :param list[openlp.core.common.Path] image_paths: A list of file paths to the images to be loaded
1584+ :param list[Path] image_paths: A list of file paths to the images to be loaded
1585 :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files
1586 :param initial_load: When set to False, the busy cursor and progressbar will be shown while loading images
1587 """
1588@@ -610,7 +611,7 @@
1589 for image in images:
1590 name = image.file_path.name
1591 thumbnail_path = self.generate_thumbnail_path(image)
1592- service_item.add_from_image(str(image.file_path), name, background, str(thumbnail_path))
1593+ service_item.add_from_image(image.file_path, name, background, str(thumbnail_path))
1594 return True
1595
1596 def check_group_exists(self, new_group):
1597
1598=== modified file 'openlp/plugins/images/lib/upgrade.py'
1599--- openlp/plugins/images/lib/upgrade.py 2019-04-13 13:00:22 +0000
1600+++ openlp/plugins/images/lib/upgrade.py 2019-05-23 20:08:25 +0000
1601@@ -24,13 +24,13 @@
1602 """
1603 import json
1604 import logging
1605+from pathlib import Path
1606
1607 from sqlalchemy import Column, Table
1608
1609 from openlp.core.common.applocation import AppLocation
1610 from openlp.core.common.db import drop_columns
1611-from openlp.core.common.json import OpenLPJsonEncoder
1612-from openlp.core.common.path import Path
1613+from openlp.core.common.json import OpenLPJSONEncoder
1614 from openlp.core.lib.db import PathType, get_upgrade_op
1615
1616
1617@@ -58,7 +58,7 @@
1618 results = conn.execute('SELECT * FROM image_filenames')
1619 data_path = AppLocation.get_data_path()
1620 for row in results.fetchall():
1621- file_path_json = json.dumps(Path(row.filename), cls=OpenLPJsonEncoder, base_path=data_path)
1622+ file_path_json = json.dumps(Path(row.filename), cls=OpenLPJSONEncoder, base_path=data_path)
1623 sql = 'UPDATE image_filenames SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(
1624 file_path_json=file_path_json, id=row.id)
1625 conn.execute(sql)
1626
1627=== modified file 'openlp/plugins/media/forms/mediaclipselectorform.py'
1628--- openlp/plugins/media/forms/mediaclipselectorform.py 2019-04-13 13:00:22 +0000
1629+++ openlp/plugins/media/forms/mediaclipselectorform.py 2019-05-23 20:08:25 +0000
1630@@ -23,6 +23,7 @@
1631 import os
1632 import re
1633 from datetime import datetime
1634+from pathlib import Path
1635 from time import sleep
1636
1637 from PyQt5 import QtCore, QtWidgets
1638@@ -30,7 +31,6 @@
1639 from openlp.core.common import is_linux, is_macosx, is_win
1640 from openlp.core.common.i18n import translate
1641 from openlp.core.common.mixins import RegistryProperties
1642-from openlp.core.common.path import Path
1643 from openlp.core.lib.ui import critical_error_message_box
1644 from openlp.core.ui.icons import UiIcons
1645 from openlp.core.ui.media.vlcplayer import get_vlc
1646
1647=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
1648--- openlp/plugins/presentations/lib/impresscontroller.py 2019-04-13 13:00:22 +0000
1649+++ openlp/plugins/presentations/lib/impresscontroller.py 2019-05-23 20:08:25 +0000
1650@@ -205,7 +205,7 @@
1651 """
1652 Constructor, store information about the file and initialise.
1653
1654- :param openlp.core.common.path.Path document_path: File path for the document to load
1655+ :param pathlib.Path document_path: File path for the document to load
1656 :rtype: None
1657 """
1658 log.debug('Init Presentation OpenOffice')
1659
1660=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
1661--- openlp/plugins/presentations/lib/mediaitem.py 2019-05-04 11:49:20 +0000
1662+++ openlp/plugins/presentations/lib/mediaitem.py 2019-05-23 20:08:25 +0000
1663@@ -156,7 +156,7 @@
1664 Add presentations into the media manager. This is called both on initial load of the plugin to populate with
1665 existing files, and when the user adds new files via the media manager.
1666
1667- :param list[openlp.core.common.path.Path] file_paths: List of file paths to add to the media manager.
1668+ :param list[pathlib.Path] file_paths: List of file paths to add to the media manager.
1669 """
1670 current_paths = self.get_file_list()
1671 titles = [file_path.name for file_path in current_paths]
1672@@ -241,7 +241,7 @@
1673 """
1674 Clean up the files created such as thumbnails
1675
1676- :param openlp.core.common.path.Path file_path: File path of the presentation to clean up after
1677+ :param pathlib.Path file_path: File path of the presentation to clean up after
1678 :param bool clean_for_update: Only clean thumbnails if update is needed
1679 :rtype: None
1680 """
1681@@ -385,7 +385,7 @@
1682 set as the preferred controller. Find the first (alphabetic) enabled controller which "supports" the extension.
1683 If none found, then look for a controller which "also supports" it instead.
1684
1685- :param openlp.core.common.path.Path file_path: The file path
1686+ :param pathlib.Path file_path: The file path
1687 :return: The default application controller for this file type, or None if not supported
1688 :rtype: PresentationController
1689 """
1690
1691=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
1692--- openlp/plugins/presentations/lib/messagelistener.py 2019-05-02 17:11:55 +0000
1693+++ openlp/plugins/presentations/lib/messagelistener.py 2019-05-23 20:08:25 +0000
1694@@ -21,10 +21,10 @@
1695 ##########################################################################
1696 import copy
1697 import logging
1698+from pathlib import Path
1699
1700 from PyQt5 import QtCore
1701
1702-from openlp.core.common.path import Path
1703 from openlp.core.common.registry import Registry
1704 from openlp.core.common.settings import Settings
1705 from openlp.core.lib import ServiceItemContext
1706
1707=== modified file 'openlp/plugins/presentations/lib/pdfcontroller.py'
1708--- openlp/plugins/presentations/lib/pdfcontroller.py 2019-05-02 13:45:07 +0000
1709+++ openlp/plugins/presentations/lib/pdfcontroller.py 2019-05-23 20:08:25 +0000
1710@@ -21,11 +21,11 @@
1711 ##########################################################################
1712 import logging
1713 import re
1714+from shutil import which
1715 from subprocess import CalledProcessError, check_output
1716
1717 from openlp.core.common import check_binary_exists, is_win
1718 from openlp.core.common.applocation import AppLocation
1719-from openlp.core.common.path import which
1720 from openlp.core.common.settings import Settings
1721 from openlp.core.display.screens import ScreenList
1722 from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
1723@@ -71,7 +71,7 @@
1724 Function that checks whether a binary is either ghostscript or mudraw or neither.
1725 Is also used from presentationtab.py
1726
1727- :param openlp.core.common.path.Path program_path: The full path to the binary to check.
1728+ :param pathlib.Path program_path: The full path to the binary to check.
1729 :return: Type of the binary, 'gs' if ghostscript, 'mudraw' if mudraw, None if invalid.
1730 :rtype: str | None
1731 """
1732@@ -182,7 +182,7 @@
1733 """
1734 Constructor, store information about the file and initialise.
1735
1736- :param openlp.core.common.path.Path document_path: Path to the document to load
1737+ :param pathlib.Path document_path: Path to the document to load
1738 :rtype: None
1739 """
1740 log.debug('Init Presentation Pdf')
1741
1742=== modified file 'openlp/plugins/presentations/lib/powerpointcontroller.py'
1743--- openlp/plugins/presentations/lib/powerpointcontroller.py 2019-04-13 13:00:22 +0000
1744+++ openlp/plugins/presentations/lib/powerpointcontroller.py 2019-05-23 20:08:25 +0000
1745@@ -124,7 +124,7 @@
1746 Constructor, store information about the file and initialise.
1747
1748 :param controller:
1749- :param openlp.core.common.path.Path document_path: Path to the document to load
1750+ :param pathlib.Path document_path: Path to the document to load
1751 :rtype: None
1752 """
1753 log.debug('Init Presentation Powerpoint')
1754
1755=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
1756--- openlp/plugins/presentations/lib/presentationcontroller.py 2019-04-13 13:00:22 +0000
1757+++ openlp/plugins/presentations/lib/presentationcontroller.py 2019-05-23 20:08:25 +0000
1758@@ -20,12 +20,14 @@
1759 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
1760 ##########################################################################
1761 import logging
1762+import shutil
1763+from pathlib import Path
1764
1765 from PyQt5 import QtCore
1766
1767 from openlp.core.common import md5_hash
1768 from openlp.core.common.applocation import AppLocation
1769-from openlp.core.common.path import Path, create_paths
1770+from openlp.core.common.path import create_paths
1771 from openlp.core.common.registry import Registry
1772 from openlp.core.common.settings import Settings
1773 from openlp.core.lib import create_thumb, validate_thumb
1774@@ -92,7 +94,7 @@
1775 Constructor for the PresentationController class
1776
1777 :param controller:
1778- :param openlp.core.common.path.Path document_path: Path to the document to load.
1779+ :param Path document_path: Path to the document to load.
1780 :rtype: None
1781 """
1782 self.controller = controller
1783@@ -102,7 +104,7 @@
1784 """
1785 Run some initial setup. This method is separate from __init__ in order to mock it out in tests.
1786
1787- :param openlp.core.common.path.Path document_path: Path to the document to load.
1788+ :param Path document_path: Path to the document to load.
1789 :rtype: None
1790 """
1791 self.slide_number = 0
1792@@ -129,7 +131,7 @@
1793 if thumbnail_folder_path.exists():
1794 thumbnail_folder_path.rmtree()
1795 if temp_folder_path.exists():
1796- temp_folder_path.rmtree()
1797+ shutil.rmtree(temp_folder_path)
1798 except OSError:
1799 log.exception('Failed to delete presentation controller files')
1800
1801@@ -138,7 +140,7 @@
1802 The location where thumbnail images will be stored
1803
1804 :return: The path to the thumbnail
1805- :rtype: openlp.core.common.path.Path
1806+ :rtype: Path
1807 """
1808 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in
1809 # get_temp_folder and PresentationPluginapp_startup is removed
1810@@ -153,7 +155,7 @@
1811 The location where thumbnail images will be stored
1812
1813 :return: The path to the temporary file folder
1814- :rtype: openlp.core.common.path.Path
1815+ :rtype: Path
1816 """
1817 # TODO: Can be removed when the upgrade path to OpenLP 3.0 is no longer needed, also ensure code in
1818 # get_thumbnail_folder and PresentationPluginapp_startup is removed
1819@@ -260,7 +262,7 @@
1820 """
1821 Convert the slide image the application made to a scaled 360px height .png image.
1822
1823- :param openlp.core.common.path.Path image_path: Path to the image to create a thumb nail of
1824+ :param Path image_path: Path to the image to create a thumbnail of
1825 :param int index: The index of the slide to create the thumbnail for.
1826 :rtype: None
1827 """
1828@@ -277,7 +279,7 @@
1829 :param int slide_no: The slide an image is required for, starting at 1
1830 :param bool check_exists: Check if the generated path exists
1831 :return: The path, or None if the :param:`check_exists` is True and the file does not exist
1832- :rtype: openlp.core.common.path.Path | None
1833+ :rtype: Path | None
1834 """
1835 path = self.get_thumbnail_folder() / (self.controller.thumbnail_prefix + str(slide_no) + '.png')
1836 if path.is_file() or not check_exists:
1837@@ -473,7 +475,7 @@
1838 """
1839 Called when a new presentation document is opened.
1840
1841- :param openlp.core.common.path.Path document_path: Path to the document to load
1842+ :param Path document_path: Path to the document to load
1843 :return: The document
1844 :rtype: PresentationDocument
1845 """
1846
1847=== modified file 'openlp/plugins/presentations/lib/presentationtab.py'
1848--- openlp/plugins/presentations/lib/presentationtab.py 2019-04-13 13:00:22 +0000
1849+++ openlp/plugins/presentations/lib/presentationtab.py 2019-05-23 20:08:25 +0000
1850@@ -221,7 +221,7 @@
1851 """
1852 Handle the `pathEditChanged` signal from program_path_edit
1853
1854- :param openlp.core.common.path.Path new_path: File path to the new program
1855+ :param pathlib.Path new_path: File path to the new program
1856 :rtype: None
1857 """
1858 if new_path:
1859
1860=== modified file 'openlp/plugins/songs/forms/editsongform.py'
1861--- openlp/plugins/songs/forms/editsongform.py 2019-04-13 13:00:22 +0000
1862+++ openlp/plugins/songs/forms/editsongform.py 2019-05-23 20:08:25 +0000
1863@@ -25,13 +25,14 @@
1864 """
1865 import logging
1866 import re
1867+from shutil import copyfile
1868
1869 from PyQt5 import QtCore, QtWidgets
1870
1871 from openlp.core.common.applocation import AppLocation
1872 from openlp.core.common.i18n import UiStrings, get_natural_key, translate
1873 from openlp.core.common.mixins import RegistryProperties
1874-from openlp.core.common.path import copyfile, create_paths
1875+from openlp.core.common.path import create_paths
1876 from openlp.core.common.registry import Registry
1877 from openlp.core.lib import MediaType, create_separated_list
1878 from openlp.core.lib.plugin import PluginStatus
1879
1880=== modified file 'openlp/plugins/songs/forms/mediafilesform.py'
1881--- openlp/plugins/songs/forms/mediafilesform.py 2019-04-13 13:00:22 +0000
1882+++ openlp/plugins/songs/forms/mediafilesform.py 2019-05-23 20:08:25 +0000
1883@@ -43,7 +43,7 @@
1884
1885 def populate_files(self, file_paths):
1886 """
1887- :param list[openlp.core.common.path.Path] file_paths:
1888+ :param list[pathlib.Path] file_paths:
1889 :return:
1890 """
1891 self.file_list_widget.clear()
1892@@ -54,6 +54,6 @@
1893
1894 def get_selected_files(self):
1895 """
1896- :rtype: list[openlp.core.common.path.Path]
1897+ :rtype: list[pathlib.Path]
1898 """
1899 return [item.data(QtCore.Qt.UserRole) for item in self.file_list_widget.selectedItems()]
1900
1901=== modified file 'openlp/plugins/songs/lib/importers/easyworship.py'
1902--- openlp/plugins/songs/lib/importers/easyworship.py 2019-04-13 13:00:22 +0000
1903+++ openlp/plugins/songs/lib/importers/easyworship.py 2019-05-23 20:08:25 +0000
1904@@ -28,9 +28,9 @@
1905 import sqlite3
1906 import struct
1907 import zlib
1908+from pathlib import Path
1909
1910 from openlp.core.common.i18n import translate
1911-from openlp.core.common.path import Path
1912 from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding, strip_rtf
1913
1914 from .songimport import SongImport
1915
1916=== modified file 'openlp/plugins/songs/lib/importers/powersong.py'
1917--- openlp/plugins/songs/lib/importers/powersong.py 2019-04-13 13:00:22 +0000
1918+++ openlp/plugins/songs/lib/importers/powersong.py 2019-05-23 20:08:25 +0000
1919@@ -24,9 +24,9 @@
1920 PowerSong songs into the OpenLP database.
1921 """
1922 import logging
1923+from pathlib import Path
1924
1925 from openlp.core.common.i18n import translate
1926-from openlp.core.common.path import Path
1927 from openlp.plugins.songs.lib.importers.songimport import SongImport
1928
1929
1930@@ -73,7 +73,7 @@
1931 * is a directory
1932 * contains at least one * .song file
1933
1934- :param openlp.core.common.path.Path import_source: Should be a Path object that fulfills the above criteria
1935+ :param Path import_source: Should be a Path object that fulfills the above criteria
1936 :return: If the source is valid
1937 :rtype: bool
1938 """
1939
1940=== modified file 'openlp/plugins/songs/lib/importers/presentationmanager.py'
1941--- openlp/plugins/songs/lib/importers/presentationmanager.py 2019-05-04 09:13:29 +0000
1942+++ openlp/plugins/songs/lib/importers/presentationmanager.py 2019-05-23 20:08:25 +0000
1943@@ -78,7 +78,7 @@
1944 def process_song(self, root, file_path):
1945 """
1946 :param root:
1947- :param openlp.core.common.path.Path file_path: Path to the file to process
1948+ :param pathlib.Path file_path: Path to the file to process
1949 :rtype: None
1950 """
1951 self.set_defaults()
1952
1953=== modified file 'openlp/plugins/songs/lib/importers/propresenter.py'
1954--- openlp/plugins/songs/lib/importers/propresenter.py 2019-04-13 13:00:22 +0000
1955+++ openlp/plugins/songs/lib/importers/propresenter.py 2019-05-23 20:08:25 +0000
1956@@ -55,7 +55,7 @@
1957 def process_song(self, root, file_path):
1958 """
1959 :param root:
1960- :param openlp.core.common.path.Path file_path: Path to the file thats being imported
1961+ :param pathlib.Path file_path: Path to the file thats being imported
1962 :rtype: None
1963 """
1964 self.set_defaults()
1965
1966=== modified file 'openlp/plugins/songs/lib/importers/songbeamer.py'
1967--- openlp/plugins/songs/lib/importers/songbeamer.py 2019-05-04 09:13:29 +0000
1968+++ openlp/plugins/songs/lib/importers/songbeamer.py 2019-05-23 20:08:25 +0000
1969@@ -27,9 +27,9 @@
1970 import math
1971 import os
1972 import re
1973+from pathlib import Path
1974
1975 from openlp.core.common import get_file_encoding, is_macosx, is_win
1976-from openlp.core.common.path import Path
1977 from openlp.core.common.settings import Settings
1978 from openlp.plugins.songs.lib import VerseType
1979 from openlp.plugins.songs.lib.importers.songimport import SongImport
1980
1981=== modified file 'openlp/plugins/songs/lib/importers/songimport.py'
1982--- openlp/plugins/songs/lib/importers/songimport.py 2019-04-13 13:00:22 +0000
1983+++ openlp/plugins/songs/lib/importers/songimport.py 2019-05-23 20:08:25 +0000
1984@@ -22,13 +22,14 @@
1985
1986 import logging
1987 import re
1988+from shutil import copyfile
1989
1990 from PyQt5 import QtCore
1991
1992 from openlp.core.common import normalize_str
1993 from openlp.core.common.applocation import AppLocation
1994 from openlp.core.common.i18n import translate
1995-from openlp.core.common.path import copyfile, create_paths
1996+from openlp.core.common.path import create_paths
1997 from openlp.core.common.registry import Registry
1998 from openlp.core.widgets.wizard import WizardStrings
1999 from openlp.plugins.songs.lib import VerseType, clean_song
2000@@ -401,9 +402,9 @@
2001 the new file location.
2002
2003 :param song_id:
2004- :param openlp.core.common.path.Path file_path: The file to copy.
2005+ :param pathlib.Path file_path: The file to copy.
2006 :return: The new location of the file
2007- :rtype: openlp.core.common.path.Path
2008+ :rtype: pathlib.Path
2009 """
2010 if not hasattr(self, 'save_path'):
2011 self.save_path = AppLocation.get_section_data_path(self.import_wizard.plugin.name) / 'audio' / str(song_id)
2012
2013=== modified file 'openlp/plugins/songs/lib/importers/songpro.py'
2014--- openlp/plugins/songs/lib/importers/songpro.py 2019-04-13 13:00:22 +0000
2015+++ openlp/plugins/songs/lib/importers/songpro.py 2019-05-23 20:08:25 +0000
2016@@ -24,8 +24,8 @@
2017 songs into the OpenLP database.
2018 """
2019 import re
2020+from pathlib import Path
2021
2022-from openlp.core.common.path import Path
2023 from openlp.plugins.songs.lib import strip_rtf
2024 from openlp.plugins.songs.lib.importers.songimport import SongImport
2025
2026
2027=== modified file 'openlp/plugins/songs/lib/importers/sundayplus.py'
2028--- openlp/plugins/songs/lib/importers/sundayplus.py 2019-04-13 13:00:22 +0000
2029+++ openlp/plugins/songs/lib/importers/sundayplus.py 2019-05-23 20:08:25 +0000
2030@@ -65,7 +65,7 @@
2031 """
2032 Process the Sunday Plus song file
2033
2034- :param openlp.core.common.path.Path file_path: The song file to import
2035+ :param pathlib.Path file_path: The song file to import
2036 :rtype: None
2037 """
2038 with file_path.open('rb') as song_file:
2039@@ -180,7 +180,7 @@
2040 """
2041 Extract the title from the filename
2042
2043- :param openlp.core.common.path.Path file_path: File being imported
2044+ :param pathlib.Path file_path: File being imported
2045 :return: The song title
2046 :rtype: str
2047 """
2048
2049=== modified file 'openlp/plugins/songs/lib/importers/videopsalm.py'
2050--- openlp/plugins/songs/lib/importers/videopsalm.py 2019-04-13 13:00:22 +0000
2051+++ openlp/plugins/songs/lib/importers/videopsalm.py 2019-05-23 20:08:25 +0000
2052@@ -25,9 +25,9 @@
2053 import json
2054 import logging
2055 import re
2056+from pathlib import Path
2057
2058 from openlp.core.common.i18n import translate
2059-from openlp.core.common.path import Path
2060 from openlp.core.common.settings import Settings
2061 from openlp.plugins.songs.lib.db import AuthorType
2062 from openlp.plugins.songs.lib.importers.songimport import SongImport
2063
2064=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
2065--- openlp/plugins/songs/lib/mediaitem.py 2019-04-13 13:00:22 +0000
2066+++ openlp/plugins/songs/lib/mediaitem.py 2019-05-23 20:08:25 +0000
2067@@ -20,8 +20,9 @@
2068 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
2069 ##########################################################################
2070 import logging
2071+import mako
2072 import os
2073-import mako
2074+from shutil import copyfile
2075
2076 from PyQt5 import QtCore, QtWidgets
2077 from sqlalchemy.sql import and_, or_
2078@@ -29,7 +30,7 @@
2079 from openlp.core.state import State
2080 from openlp.core.common.applocation import AppLocation
2081 from openlp.core.common.i18n import UiStrings, get_natural_key, translate
2082-from openlp.core.common.path import copyfile, create_paths
2083+from openlp.core.common.path import create_paths
2084 from openlp.core.common.registry import Registry
2085 from openlp.core.common.settings import Settings
2086 from openlp.core.lib import ServiceItemContext, check_item_selected, create_separated_list
2087
2088=== modified file 'openlp/plugins/songs/lib/openlyricsexport.py'
2089--- openlp/plugins/songs/lib/openlyricsexport.py 2019-04-13 13:00:22 +0000
2090+++ openlp/plugins/songs/lib/openlyricsexport.py 2019-05-23 20:08:25 +0000
2091@@ -45,7 +45,7 @@
2092 """
2093 Initialise the export.
2094
2095- :param openlp.core.common.path.Path save_path: The directory to save the exported songs in
2096+ :param pathlib.Path save_path: The directory to save the exported songs in
2097 :rtype: None
2098 """
2099 log.debug('initialise OpenLyricsExport')
2100
2101=== modified file 'openlp/plugins/songs/lib/upgrade.py'
2102--- openlp/plugins/songs/lib/upgrade.py 2019-04-13 13:00:22 +0000
2103+++ openlp/plugins/songs/lib/upgrade.py 2019-05-23 20:08:25 +0000
2104@@ -25,14 +25,14 @@
2105 """
2106 import json
2107 import logging
2108+from pathlib import Path
2109
2110 from sqlalchemy import Column, ForeignKey, Table, types
2111 from sqlalchemy.sql.expression import false, func, null, text
2112
2113 from openlp.core.common.applocation import AppLocation
2114 from openlp.core.common.db import drop_columns
2115-from openlp.core.common.json import OpenLPJsonEncoder
2116-from openlp.core.common.path import Path
2117+from openlp.core.common.json import OpenLPJSONEncoder
2118 from openlp.core.lib.db import PathType, get_upgrade_op
2119
2120
2121@@ -182,7 +182,7 @@
2122 results = conn.execute('SELECT * FROM media_files')
2123 data_path = AppLocation.get_data_path()
2124 for row in results.fetchall():
2125- file_path_json = json.dumps(Path(row.file_name), cls=OpenLPJsonEncoder, base_path=data_path)
2126+ file_path_json = json.dumps(Path(row.file_name), cls=OpenLPJSONEncoder, base_path=data_path)
2127 sql = 'UPDATE media_files SET file_path = \'{file_path_json}\' WHERE id = {id}'.format(
2128 file_path_json=file_path_json, id=row.id)
2129 conn.execute(sql)
2130
2131=== modified file 'openlp/plugins/songs/reporting.py'
2132--- openlp/plugins/songs/reporting.py 2019-04-13 13:00:22 +0000
2133+++ openlp/plugins/songs/reporting.py 2019-05-23 20:08:25 +0000
2134@@ -24,9 +24,9 @@
2135 """
2136 import csv
2137 import logging
2138+from pathlib import Path
2139
2140 from openlp.core.common.i18n import translate
2141-from openlp.core.common.path import Path
2142 from openlp.core.common.registry import Registry
2143 from openlp.core.lib.ui import critical_error_message_box
2144 from openlp.core.widgets.dialogs import FileDialog
2145
2146=== modified file 'openlp/plugins/songs/songsplugin.py'
2147--- openlp/plugins/songs/songsplugin.py 2019-04-13 13:00:22 +0000
2148+++ openlp/plugins/songs/songsplugin.py 2019-05-23 20:08:25 +0000
2149@@ -432,7 +432,7 @@
2150 """
2151 Provide a count of the songs in the database
2152
2153- :param openlp.core.common.path.Path db_path: The database to use
2154+ :param Path db_path: The database to use
2155 :return: The number of songs in the db.
2156 :rtype: int
2157 """
2158
2159=== modified file 'openlp/plugins/songusage/forms/songusagedetailform.py'
2160--- openlp/plugins/songusage/forms/songusagedetailform.py 2019-04-13 13:00:22 +0000
2161+++ openlp/plugins/songusage/forms/songusagedetailform.py 2019-05-23 20:08:25 +0000
2162@@ -70,7 +70,7 @@
2163 """
2164 Handle the `pathEditChanged` signal from report_path_edit
2165
2166- :param openlp.core.common.path.Path file_path: The new path.
2167+ :param pathlib.Path file_path: The new path.
2168 :rtype: None
2169 """
2170 Settings().setValue(self.plugin.settings_section + '/last directory export', file_path)
2171
2172=== modified file 'tests/functional/openlp_core/api/test_deploy.py'
2173--- tests/functional/openlp_core/api/test_deploy.py 2019-04-13 13:00:22 +0000
2174+++ tests/functional/openlp_core/api/test_deploy.py 2019-05-23 20:08:25 +0000
2175@@ -20,12 +20,13 @@
2176 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
2177 ##########################################################################
2178 import os
2179+import shutil
2180+from pathlib import Path
2181 from tempfile import mkdtemp
2182 from unittest import TestCase
2183 from unittest.mock import MagicMock, patch
2184
2185 from openlp.core.api.deploy import deploy_zipfile, download_and_check, download_sha256
2186-from openlp.core.common.path import Path
2187
2188
2189 CONFIG_FILE = '2c266badff1e3d140664c50fd1460a2b332b24d5ad8c267fa62e506b5eb6d894 deploy/site.zip\n2017_06_27'
2190@@ -46,7 +47,7 @@
2191 """
2192 Clean up after tests
2193 """
2194- self.app_root_path.rmtree()
2195+ shutil.rmtree(self.app_root_path)
2196
2197 @patch('openlp.core.api.deploy.ZipFile')
2198 def test_deploy_zipfile(self, MockZipFile):
2199
2200=== modified file 'tests/functional/openlp_core/common/test_applocation.py'
2201--- tests/functional/openlp_core/common/test_applocation.py 2019-04-13 13:00:22 +0000
2202+++ tests/functional/openlp_core/common/test_applocation.py 2019-05-23 20:08:25 +0000
2203@@ -23,11 +23,11 @@
2204 Functional tests to test the AppLocation class and related methods.
2205 """
2206 import os
2207+from pathlib import Path
2208 from unittest.mock import patch
2209
2210 from openlp.core.common import get_frozen_path
2211 from openlp.core.common.applocation import AppLocation
2212-from openlp.core.common.path import Path
2213
2214
2215 FILE_LIST = ['file1', 'file2', 'file3.txt', 'file4.txt', 'file5.mp3', 'file6.mp3']
2216
2217=== modified file 'tests/functional/openlp_core/common/test_common.py'
2218--- tests/functional/openlp_core/common/test_common.py 2019-05-04 12:05:53 +0000
2219+++ tests/functional/openlp_core/common/test_common.py 2019-05-23 20:08:25 +0000
2220@@ -22,12 +22,12 @@
2221 """
2222 Functional tests to test the AppLocation class and related methods.
2223 """
2224+from pathlib import Path
2225 from unittest import TestCase
2226 from unittest.mock import MagicMock, call, patch
2227
2228 from openlp.core.common import clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
2229 normalize_str, path_to_module, trace_error_handler
2230-from openlp.core.common.path import Path
2231
2232
2233 class TestCommonFunctions(TestCase):
2234
2235=== modified file 'tests/functional/openlp_core/common/test_httputils.py'
2236--- tests/functional/openlp_core/common/test_httputils.py 2019-04-13 13:00:22 +0000
2237+++ tests/functional/openlp_core/common/test_httputils.py 2019-05-23 20:08:25 +0000
2238@@ -24,12 +24,12 @@
2239 """
2240 import os
2241 import tempfile
2242+from pathlib import Path
2243 from unittest import TestCase
2244 from unittest.mock import MagicMock, patch
2245
2246 from openlp.core.common.httputils import ProxyMode, download_file, get_proxy_settings, get_url_file_size, \
2247 get_user_agent, get_web_page
2248-from openlp.core.common.path import Path
2249 from openlp.core.common.settings import Settings
2250 from tests.helpers.testmixin import TestMixin
2251
2252
2253=== modified file 'tests/functional/openlp_core/common/test_init.py'
2254--- tests/functional/openlp_core/common/test_init.py 2019-05-04 09:13:29 +0000
2255+++ tests/functional/openlp_core/common/test_init.py 2019-05-23 20:08:25 +0000
2256@@ -23,12 +23,12 @@
2257 Functional tests to test the AppLocation class and related methods.
2258 """
2259 from io import BytesIO
2260+from pathlib import Path
2261 from unittest import TestCase
2262 from unittest.mock import MagicMock, PropertyMock, call, patch
2263
2264 from openlp.core.common import add_actions, clean_filename, delete_file, get_file_encoding, get_filesystem_encoding, \
2265 get_uno_command, get_uno_instance
2266-from openlp.core.common.path import Path
2267 from tests.helpers.testmixin import TestMixin
2268
2269
2270
2271=== modified file 'tests/functional/openlp_core/common/test_json.py'
2272--- tests/functional/openlp_core/common/test_json.py 2019-04-13 13:00:22 +0000
2273+++ tests/functional/openlp_core/common/test_json.py 2019-05-23 20:08:25 +0000
2274@@ -23,14 +23,134 @@
2275 Package to test the openlp.core.common.json package.
2276 """
2277 import json
2278+import os
2279+from pathlib import Path
2280 from unittest import TestCase
2281 from unittest.mock import patch
2282
2283-from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
2284-from openlp.core.common.path import Path
2285-
2286-
2287-class TestOpenLPJsonDecoder(TestCase):
2288+from openlp.core.common.json import JSONMixin, OpenLPJSONDecoder, OpenLPJSONEncoder, PathSerializer, _registered_classes
2289+
2290+
2291+class TestClassBase(object):
2292+ """
2293+ Simple class to avoid repetition
2294+ """
2295+ def __init__(self, a=None, b=None, c=None):
2296+ self.a = a
2297+ self.b = b
2298+ self.c = c
2299+
2300+
2301+class TestJSONMixin(TestCase):
2302+ """
2303+ Test the JSONMixin class
2304+ """
2305+ def setUp(self):
2306+ self._registered_classes_patcher = patch.dict(_registered_classes, clear=True)
2307+ self.addCleanup(self._registered_classes_patcher.stop)
2308+ self._registered_classes_patcher.start()
2309+
2310+ def test_subclass_json_mixin(self):
2311+ """
2312+ Test that a class is `registered` when subclassing JSONMixin
2313+ """
2314+ # GIVEN: The JSONMixin class
2315+ # WHEN: Subclassing it
2316+ class TestClass(JSONMixin):
2317+ pass
2318+
2319+ # THEN: The TestClass should have been `registered`
2320+ assert _registered_classes['TestClass'] == TestClass
2321+
2322+ def test_subclass_json_mixin_alt_names(self):
2323+ """
2324+ Test that a class is `registered` using the specified names when subclassing JSONMixin
2325+ """
2326+ # GIVEN: The JSONMixin class
2327+ # WHEN: Subclassing it with custom names
2328+ class TestClass(JSONMixin, register_names=('AltName1', 'AltName2')):
2329+ pass
2330+
2331+ # THEN: The TestClass should have been registered with only those names
2332+ assert 'TestClass' not in _registered_classes
2333+ assert _registered_classes['AltName1'] == TestClass
2334+ assert _registered_classes['AltName2'] == TestClass
2335+
2336+ def test_encoding_json_mixin_subclass(self):
2337+ """
2338+ Test that an instance of a JSONMixin subclass is properly serialized to a JSON string
2339+ """
2340+ # GIVEN: A instance of a subclass of the JSONMixin class
2341+ class TestClass(TestClassBase, JSONMixin):
2342+ _json_keys = ['a', 'b']
2343+
2344+ instance = TestClass(a=1, c=2)
2345+
2346+ # WHEN: Serializing the instance
2347+ json_string = json.dumps(instance, cls=OpenLPJSONEncoder)
2348+
2349+ # THEN: Only the attributes specified by `_json_keys` should be serialized, and only if they have been set
2350+ assert json_string == '{"a": 1, "json_meta": {"class": "TestClass", "version": 1}}'
2351+
2352+ def test_decoding_json_mixin_subclass(self):
2353+ """
2354+ Test that an instance of a JSONMixin subclass is properly deserialized from a JSON string
2355+ """
2356+ # GIVEN: A subclass of the JSONMixin class
2357+ class TestClass(TestClassBase, JSONMixin):
2358+ _json_keys = ['a', 'b']
2359+
2360+ # WHEN: Deserializing a JSON representation of the TestClass
2361+ instance = json.loads(
2362+ '{"a": 1, "c": 2, "json_meta": {"class": "TestClass", "version": 1}}', cls=OpenLPJSONDecoder)
2363+
2364+ # THEN: Only the attributes specified by `_json_keys` should have been set
2365+ assert instance.__class__ == TestClass
2366+ assert instance.a == 1
2367+ assert instance.b is None
2368+ assert instance.c is None
2369+
2370+ def test_encoding_json_mixin_subclass_custom_name(self):
2371+ """
2372+ Test that an instance of a JSONMixin subclass is properly serialized to a JSON string when using a custom name
2373+ """
2374+ # GIVEN: A instance of a subclass of the JSONMixin class with a custom name
2375+ class TestClass(TestClassBase, JSONMixin, register_names=('AltName', )):
2376+ _json_keys = ['a', 'b']
2377+ _name = 'AltName'
2378+ _version = 2
2379+
2380+ instance = TestClass(a=1, c=2)
2381+
2382+ # WHEN: Serializing the instance
2383+ json_string = json.dumps(instance, cls=OpenLPJSONEncoder)
2384+
2385+ # THEN: Only the attributes specified by `_json_keys` should be serialized, and only if they have been set
2386+ assert json_string == '{"a": 1, "json_meta": {"class": "AltName", "version": 2}}'
2387+
2388+ def test_decoding_json_mixin_subclass_custom_name(self):
2389+ """
2390+ Test that an instance of a JSONMixin subclass is properly deserialized from a JSON string when using a custom
2391+ name
2392+ """
2393+ # GIVEN: A instance of a subclass of the JSONMixin class with a custom name
2394+ class TestClass(TestClassBase, JSONMixin, register_names=('AltName', )):
2395+ _json_keys = ['a', 'b']
2396+ _name = 'AltName'
2397+ _version = 2
2398+
2399+ # WHEN: Deserializing a JSON representation of the TestClass
2400+ instance = json.loads(
2401+ '{"a": 1, "c": 2, "json_meta": {"class": "AltName", "version": 2}}', cls=OpenLPJSONDecoder)
2402+
2403+ # THEN: Only the attributes specified by `_json_keys` should have been set
2404+ assert instance.__class__ == TestClass
2405+ assert instance.a == 1
2406+ assert instance.b is None
2407+ assert instance.c is None
2408+
2409+
2410+class TestOpenLPJSONDecoder(TestCase):
2411 """
2412 Test the OpenLPJsonDecoder class
2413 """
2414@@ -39,10 +159,10 @@
2415 Test the object_hook method when called with a decoded Path JSON object
2416 """
2417 # GIVEN: An instance of OpenLPJsonDecoder
2418- instance = OpenLPJsonDecoder()
2419+ instance = OpenLPJSONDecoder()
2420
2421 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
2422- result = instance.object_hook({'__Path__': ['test', 'path']})
2423+ result = instance.object_hook({'parts': ['test', 'path'], "json_meta": {"class": "Path", "version": 1}})
2424
2425 # THEN: A Path object should be returned
2426 assert result == Path('test', 'path')
2427@@ -52,7 +172,7 @@
2428 Test the object_hook method when called with a decoded JSON object
2429 """
2430 # GIVEN: An instance of OpenLPJsonDecoder
2431- instance = OpenLPJsonDecoder()
2432+ instance = OpenLPJSONDecoder()
2433
2434 # WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
2435 with patch('openlp.core.common.json.Path') as mocked_path:
2436@@ -67,31 +187,32 @@
2437 Test the OpenLPJsonDecoder when decoding a JSON string
2438 """
2439 # GIVEN: A JSON encoded string
2440- json_string = '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'
2441+ json_string = '[{"parts": ["test", "path1"], "json_meta": {"class": "Path", "version": 1}}, ' \
2442+ '{"parts": ["test", "path2"], "json_meta": {"class": "Path", "version": 1}}]'
2443
2444 # WHEN: Decoding the string using the OpenLPJsonDecoder class
2445- obj = json.loads(json_string, cls=OpenLPJsonDecoder)
2446+ obj = json.loads(json_string, cls=OpenLPJSONDecoder)
2447
2448 # THEN: The object returned should be a python version of the JSON string
2449 assert obj == [Path('test', 'path1'), Path('test', 'path2')]
2450
2451
2452-class TestOpenLPJsonEncoder(TestCase):
2453+class TestOpenLPJSONEncoder(TestCase):
2454 """
2455- Test the OpenLPJsonEncoder class
2456+ Test the OpenLPJSONEncoder class
2457 """
2458 def test_default_path_object(self):
2459 """
2460 Test the default method when called with a Path object
2461 """
2462- # GIVEN: An instance of OpenLPJsonEncoder
2463- instance = OpenLPJsonEncoder()
2464+ # GIVEN: An instance of OpenLPJSONEncoder
2465+ instance = OpenLPJSONEncoder()
2466
2467 # WHEN: Calling the default method with a Path object
2468 result = instance.default(Path('test', 'path'))
2469
2470 # THEN: A dictionary object that can be JSON encoded should be returned
2471- assert result == {'__Path__': ('test', 'path')}
2472+ assert result == {'parts': ('test', 'path'), "json_meta": {"class": "Path", "version": 1}}
2473
2474 def test_default_non_path_object(self):
2475 """
2476@@ -99,8 +220,8 @@
2477 """
2478 with patch('openlp.core.common.json.JSONEncoder.default') as mocked_super_default:
2479
2480- # GIVEN: An instance of OpenLPJsonEncoder
2481- instance = OpenLPJsonEncoder()
2482+ # GIVEN: An instance of OpenLPJSONEncoder
2483+ instance = OpenLPJSONEncoder()
2484
2485 # WHEN: Calling the default method with a object other than a Path object
2486 instance.default('invalid object')
2487@@ -115,8 +236,65 @@
2488 # GIVEN: A list of Path objects
2489 obj = [Path('test', 'path1'), Path('test', 'path2')]
2490
2491- # WHEN: Encoding the object using the OpenLPJsonEncoder class
2492- json_string = json.dumps(obj, cls=OpenLPJsonEncoder)
2493+ # WHEN: Encoding the object using the OpenLPJSONEncoder class
2494+ json_string = json.dumps(obj, cls=OpenLPJSONEncoder)
2495
2496 # THEN: The JSON string return should be a representation of the object encoded
2497- assert json_string == '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'
2498+ assert json_string == '[{"parts": ["test", "path1"], "json_meta": {"class": "Path", "version": 1}}, ' \
2499+ '{"parts": ["test", "path2"], "json_meta": {"class": "Path", "version": 1}}]'
2500+
2501+
2502+class TestPathSerializer(TestCase):
2503+
2504+ def test_path_encode_json(self):
2505+ """
2506+ Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
2507+ from JSON
2508+ """
2509+ # GIVEN: A Path object from openlp.core.common.path
2510+ # WHEN: Calling encode_json, with a dictionary representation
2511+ path = PathSerializer.encode_json(
2512+ {'parts': ['path', 'to', 'fi.le'], "json_meta": {"class": "Path", "version": 1}}, extra=1, args=2)
2513+
2514+ # THEN: A Path object should have been returned
2515+ assert path == Path('path', 'to', 'fi.le')
2516+
2517+ def test_path_encode_json_base_path(self):
2518+ """
2519+ Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
2520+ from JSON when the base_path arg is supplied.
2521+ """
2522+ # GIVEN: A Path object from openlp.core.common.path
2523+ # WHEN: Calling encode_json, with a dictionary representation
2524+ path = PathSerializer.encode_json(
2525+ {'parts': ['path', 'to', 'fi.le'], "json_meta": {"class": "Path", "version": 1}}, base_path=Path('/base'))
2526+
2527+ # THEN: A Path object should have been returned with an absolute path
2528+ assert path == Path('/', 'base', 'path', 'to', 'fi.le')
2529+
2530+ def test_path_json_object(self):
2531+ """
2532+ Test that `Path.json_object` creates a JSON decode-able object from a Path object
2533+ """
2534+ # GIVEN: A Path object from openlp.core.common.path
2535+ path = Path('/base', 'path', 'to', 'fi.le')
2536+
2537+ # WHEN: Calling json_object
2538+ obj = PathSerializer().json_object(path, extra=1, args=2)
2539+
2540+ # THEN: A JSON decodeable object should have been returned.
2541+ assert obj == {'parts': (os.sep, 'base', 'path', 'to', 'fi.le'), "json_meta": {"class": "Path", "version": 1}}
2542+
2543+ def test_path_json_object_base_path(self):
2544+ """
2545+ Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
2546+ base_path
2547+ """
2548+ # GIVEN: A Path object from openlp.core.common.path
2549+ path = Path('/base', 'path', 'to', 'fi.le')
2550+
2551+ # WHEN: Calling json_object with a base_path
2552+ obj = PathSerializer().json_object(path, base_path=Path('/', 'base'))
2553+
2554+ # THEN: A JSON decodable object should have been returned.
2555+ assert obj == {'parts': ('path', 'to', 'fi.le'), "json_meta": {"class": "Path", "version": 1}}
2556
2557=== modified file 'tests/functional/openlp_core/common/test_path.py'
2558--- tests/functional/openlp_core/common/test_path.py 2019-04-13 13:00:22 +0000
2559+++ tests/functional/openlp_core/common/test_path.py 2019-05-23 20:08:25 +0000
2560@@ -22,12 +22,13 @@
2561 """
2562 Package to test the openlp.core.common.path package.
2563 """
2564+# TODO: fix patches
2565 import os
2566+from pathlib import Path
2567 from unittest import TestCase
2568-from unittest.mock import ANY, MagicMock, patch
2569+from unittest.mock import MagicMock, patch
2570
2571-from openlp.core.common.path import Path, copy, copyfile, copytree, create_paths, files_to_paths, path_to_str, \
2572- replace_params, str_to_path, which
2573+from openlp.core.common.path import create_paths, files_to_paths, path_to_str, replace_params, str_to_path, which
2574
2575
2576 class TestShutil(TestCase):
2577@@ -66,139 +67,6 @@
2578 assert result_args == (1, '2')
2579 assert result_kwargs == {'arg3': '3', 'arg4': 4}
2580
2581- def test_copy(self):
2582- """
2583- Test :func:`openlp.core.common.path.copy`
2584- """
2585- # GIVEN: A mocked `shutil.copy` which returns a test path as a string
2586- with patch('openlp.core.common.path.shutil.copy', return_value=os.path.join('destination', 'test', 'path')) \
2587- as mocked_shutil_copy:
2588-
2589- # WHEN: Calling :func:`openlp.core.common.path.copy` with the src and dst parameters as Path object types
2590- result = copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
2591-
2592- # THEN: :func:`shutil.copy` should have been called with the str equivalents of the Path objects.
2593- # :func:`openlp.core.common.path.copy` should return the str type result of calling
2594- # :func:`shutil.copy` as a Path object.
2595- mocked_shutil_copy.assert_called_once_with(os.path.join('source', 'test', 'path'),
2596- os.path.join('destination', 'test', 'path'))
2597- assert result == Path('destination', 'test', 'path')
2598-
2599- def test_copy_follow_optional_params(self):
2600- """
2601- Test :func:`openlp.core.common.path.copy` when follow_symlinks is set to false
2602- """
2603- # GIVEN: A mocked `shutil.copy`
2604- with patch('openlp.core.common.path.shutil.copy', return_value='') as mocked_shutil_copy:
2605-
2606- # WHEN: Calling :func:`openlp.core.common.path.copy` with :param:`follow_symlinks` set to False
2607- copy(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False)
2608-
2609- # THEN: :func:`shutil.copy` should have been called with :param:`follow_symlinks` set to false
2610- mocked_shutil_copy.assert_called_once_with(ANY, ANY, follow_symlinks=False)
2611-
2612- def test_copyfile(self):
2613- """
2614- Test :func:`openlp.core.common.path.copyfile`
2615- """
2616- # GIVEN: A mocked :func:`shutil.copyfile` which returns a test path as a string
2617- with patch('openlp.core.common.path.shutil.copyfile',
2618- return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copyfile:
2619-
2620- # WHEN: Calling :func:`openlp.core.common.path.copyfile` with the src and dst parameters as Path object
2621- # types
2622- result = copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
2623-
2624- # THEN: :func:`shutil.copyfile` should have been called with the str equivalents of the Path objects.
2625- # :func:`openlp.core.common.path.copyfile` should return the str type result of calling
2626- # :func:`shutil.copyfile` as a Path object.
2627- mocked_shutil_copyfile.assert_called_once_with(os.path.join('source', 'test', 'path'),
2628- os.path.join('destination', 'test', 'path'))
2629- assert result == Path('destination', 'test', 'path')
2630-
2631- def test_copyfile_optional_params(self):
2632- """
2633- Test :func:`openlp.core.common.path.copyfile` when follow_symlinks is set to false
2634- """
2635- # GIVEN: A mocked :func:`shutil.copyfile`
2636- with patch('openlp.core.common.path.shutil.copyfile', return_value='') as mocked_shutil_copyfile:
2637-
2638- # WHEN: Calling :func:`openlp.core.common.path.copyfile` with :param:`follow_symlinks` set to False
2639- copyfile(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), follow_symlinks=False)
2640-
2641- # THEN: :func:`shutil.copyfile` should have been called with the optional parameters, with out any of the
2642- # values being modified
2643- mocked_shutil_copyfile.assert_called_once_with(ANY, ANY, follow_symlinks=False)
2644-
2645- def test_copytree(self):
2646- """
2647- Test :func:`openlp.core.common.path.copytree`
2648- """
2649- # GIVEN: A mocked :func:`shutil.copytree` which returns a test path as a string
2650- with patch('openlp.core.common.path.shutil.copytree',
2651- return_value=os.path.join('destination', 'test', 'path')) as mocked_shutil_copytree:
2652-
2653- # WHEN: Calling :func:`openlp.core.common.path.copytree` with the src and dst parameters as Path object
2654- # types
2655- result = copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'))
2656-
2657- # THEN: :func:`shutil.copytree` should have been called with the str equivalents of the Path objects.
2658- # :func:`openlp.core.common.path.copytree` should return the str type result of calling
2659- # :func:`shutil.copytree` as a Path object.
2660- mocked_shutil_copytree.assert_called_once_with(os.path.join('source', 'test', 'path'),
2661- os.path.join('destination', 'test', 'path'))
2662- assert result == Path('destination', 'test', 'path')
2663-
2664- def test_copytree_optional_params(self):
2665- """
2666- Test :func:`openlp.core.common.path.copytree` when optional parameters are passed
2667- """
2668- # GIVEN: A mocked :func:`shutil.copytree`
2669- with patch('openlp.core.common.path.shutil.copytree', return_value='') as mocked_shutil_copytree:
2670- mocked_ignore = MagicMock()
2671- mocked_copy_function = MagicMock()
2672-
2673- # WHEN: Calling :func:`openlp.core.common.path.copytree` with the optional parameters set
2674- copytree(Path('source', 'test', 'path'), Path('destination', 'test', 'path'), symlinks=True,
2675- ignore=mocked_ignore, copy_function=mocked_copy_function, ignore_dangling_symlinks=True)
2676-
2677- # THEN: :func:`shutil.copytree` should have been called with the optional parameters, with out any of the
2678- # values being modified
2679- mocked_shutil_copytree.assert_called_once_with(ANY, ANY, symlinks=True, ignore=mocked_ignore,
2680- copy_function=mocked_copy_function,
2681- ignore_dangling_symlinks=True)
2682-
2683- def test_rmtree(self):
2684- """
2685- Test :func:`rmtree`
2686- """
2687- # GIVEN: A mocked :func:`shutil.rmtree` and a test Path object
2688- with patch('openlp.core.common.path.shutil.rmtree', return_value=None) as mocked_shutil_rmtree:
2689- path = Path('test', 'path')
2690-
2691- # WHEN: Calling :func:`openlp.core.common.path.rmtree` with the path parameter as Path object type
2692- path.rmtree()
2693-
2694- # THEN: :func:`shutil.rmtree` should have been called with the the Path object.
2695- mocked_shutil_rmtree.assert_called_once_with(Path('test', 'path'), False, None)
2696-
2697- def test_rmtree_optional_params(self):
2698- """
2699- Test :func:`openlp.core.common.path.rmtree` when optional parameters are passed
2700- """
2701- # GIVEN: A mocked :func:`shutil.rmtree` and a test Path object.
2702- with patch('openlp.core.common.path.shutil.rmtree', return_value=None) as mocked_shutil_rmtree:
2703- path = Path('test', 'path')
2704- mocked_on_error = MagicMock()
2705-
2706- # WHEN: Calling :func:`openlp.core.common.path.rmtree` with :param:`ignore_errors` set to True and
2707- # :param:`onerror` set to a mocked object
2708- path.rmtree(ignore_errors=True, onerror=mocked_on_error)
2709-
2710- # THEN: :func:`shutil.rmtree` should have been called with the optional parameters, with out any of the
2711- # values being modified
2712- mocked_shutil_rmtree.assert_called_once_with(path, True, mocked_on_error)
2713-
2714 def test_which_no_command(self):
2715 """
2716 Test :func:`openlp.core.common.path.which` when the command is not found.
2717@@ -287,57 +155,6 @@
2718 # THEN: `path_to_str` should return None
2719 assert result is None
2720
2721- def test_path_encode_json(self):
2722- """
2723- Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
2724- from JSON
2725- """
2726- # GIVEN: A Path object from openlp.core.common.path
2727- # WHEN: Calling encode_json, with a dictionary representation
2728- path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, extra=1, args=2)
2729-
2730- # THEN: A Path object should have been returned
2731- assert path == Path('path', 'to', 'fi.le')
2732-
2733- def test_path_encode_json_base_path(self):
2734- """
2735- Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
2736- from JSON when the base_path arg is supplied.
2737- """
2738- # GIVEN: A Path object from openlp.core.common.path
2739- # WHEN: Calling encode_json, with a dictionary representation
2740- path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, base_path=Path('/base'))
2741-
2742- # THEN: A Path object should have been returned with an absolute path
2743- assert path == Path('/', 'base', 'path', 'to', 'fi.le')
2744-
2745- def test_path_json_object(self):
2746- """
2747- Test that `Path.json_object` creates a JSON decode-able object from a Path object
2748- """
2749- # GIVEN: A Path object from openlp.core.common.path
2750- path = Path('/base', 'path', 'to', 'fi.le')
2751-
2752- # WHEN: Calling json_object
2753- obj = path.json_object(extra=1, args=2)
2754-
2755- # THEN: A JSON decodable object should have been returned.
2756- assert obj == {'__Path__': (os.sep, 'base', 'path', 'to', 'fi.le')}
2757-
2758- def test_path_json_object_base_path(self):
2759- """
2760- Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
2761- base_path
2762- """
2763- # GIVEN: A Path object from openlp.core.common.path
2764- path = Path('/base', 'path', 'to', 'fi.le')
2765-
2766- # WHEN: Calling json_object with a base_path
2767- obj = path.json_object(base_path=Path('/', 'base'))
2768-
2769- # THEN: A JSON decodable object should have been returned.
2770- assert obj == {'__Path__': ('path', 'to', 'fi.le')}
2771-
2772 def test_create_paths_dir_exists(self):
2773 """
2774 Test the create_paths() function when the path already exists
2775
2776=== modified file 'tests/functional/openlp_core/common/test_settings.py'
2777--- tests/functional/openlp_core/common/test_settings.py 2019-04-13 13:00:22 +0000
2778+++ tests/functional/openlp_core/common/test_settings.py 2019-05-23 20:08:25 +0000
2779@@ -277,7 +277,8 @@
2780 """Test the Settings._convert_value() method when a setting is JSON and represents a Path object"""
2781 # GIVEN: A settings object
2782 # WHEN: _convert_value() is run
2783- result = Settings()._convert_value('{"__Path__": ["openlp", "core"]}', None)
2784+ result = Settings()._convert_value(
2785+ '{"parts": ["openlp", "core"], "json_meta": {"class": "Path", "version": 1}}', None)
2786
2787 # THEN: The result should be a Path object
2788 assert isinstance(result, Path), 'The result should be a Path object'
2789
2790=== modified file 'tests/functional/openlp_core/lib/test_db.py'
2791--- tests/functional/openlp_core/lib/test_db.py 2019-04-13 13:00:22 +0000
2792+++ tests/functional/openlp_core/lib/test_db.py 2019-05-23 20:08:25 +0000
2793@@ -23,6 +23,7 @@
2794 Package to test the openlp.core.lib package.
2795 """
2796 import shutil
2797+from pathlib import Path
2798 from tempfile import mkdtemp
2799 from unittest import TestCase
2800 from unittest.mock import MagicMock, patch
2801@@ -31,7 +32,6 @@
2802 from sqlalchemy.orm.scoping import ScopedSession
2803 from sqlalchemy.pool import NullPool
2804
2805-from openlp.core.common.path import Path
2806 from openlp.core.lib.db import delete_database, get_upgrade_op, init_db, upgrade_db
2807
2808
2809
2810=== modified file 'tests/functional/openlp_core/lib/test_lib.py'
2811--- tests/functional/openlp_core/lib/test_lib.py 2019-04-13 13:00:22 +0000
2812+++ tests/functional/openlp_core/lib/test_lib.py 2019-05-23 20:08:25 +0000
2813@@ -22,12 +22,12 @@
2814 """
2815 Package to test the openlp.core.lib package.
2816 """
2817+from pathlib import Path
2818 from unittest import TestCase
2819 from unittest.mock import MagicMock, patch
2820
2821 from PyQt5 import QtCore, QtGui
2822
2823-from openlp.core.common.path import Path
2824 from openlp.core.lib import build_icon, check_item_selected, create_separated_list, create_thumb, \
2825 get_text_file_string, image_to_byte, resize_image, str_to_bool, validate_thumb
2826 from tests.utils.constants import RESOURCE_PATH
2827
2828=== modified file 'tests/functional/openlp_core/lib/test_serviceitem.py'
2829--- tests/functional/openlp_core/lib/test_serviceitem.py 2019-04-13 13:00:22 +0000
2830+++ tests/functional/openlp_core/lib/test_serviceitem.py 2019-05-23 20:08:25 +0000
2831@@ -23,12 +23,12 @@
2832 Package to test the openlp.core.lib package.
2833 """
2834 import os
2835+from pathlib import Path
2836 from unittest import TestCase
2837 from unittest.mock import MagicMock, patch
2838
2839 from openlp.core.state import State
2840 from openlp.core.common import md5_hash
2841-from openlp.core.common.path import Path
2842 from openlp.core.common.registry import Registry
2843 from openlp.core.common.settings import Settings
2844 from openlp.core.lib.formattingtags import FormattingTags
2845
2846=== modified file 'tests/functional/openlp_core/test_server.py'
2847--- tests/functional/openlp_core/test_server.py 2019-05-04 18:13:57 +0000
2848+++ tests/functional/openlp_core/test_server.py 2019-05-23 20:08:25 +0000
2849@@ -19,10 +19,10 @@
2850 # You should have received a copy of the GNU General Public License #
2851 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
2852 ##########################################################################
2853+from pathlib import Path
2854 from unittest import TestCase
2855 from unittest.mock import MagicMock, patch
2856
2857-from openlp.core.common.path import Path
2858 from openlp.core.common.registry import Registry
2859 from openlp.core.server import Server
2860 from tests.helpers.testmixin import TestMixin
2861
2862=== modified file 'tests/functional/openlp_core/ui/test_exceptionform.py'
2863--- tests/functional/openlp_core/ui/test_exceptionform.py 2019-04-13 13:00:22 +0000
2864+++ tests/functional/openlp_core/ui/test_exceptionform.py 2019-05-23 20:08:25 +0000
2865@@ -25,10 +25,10 @@
2866 import os
2867 import tempfile
2868 from collections import OrderedDict
2869+from pathlib import Path
2870 from unittest import TestCase
2871 from unittest.mock import call, patch
2872
2873-from openlp.core.common.path import Path
2874 from openlp.core.common.registry import Registry
2875 from openlp.core.ui import exceptionform
2876 from tests.helpers.testmixin import TestMixin
2877
2878=== modified file 'tests/functional/openlp_core/ui/test_firsttimeform.py'
2879--- tests/functional/openlp_core/ui/test_firsttimeform.py 2019-04-13 13:00:22 +0000
2880+++ tests/functional/openlp_core/ui/test_firsttimeform.py 2019-05-23 20:08:25 +0000
2881@@ -24,12 +24,12 @@
2882 """
2883 import os
2884 import tempfile
2885+from pathlib import Path
2886 from unittest import TestCase
2887 from unittest.mock import MagicMock, call, patch, DEFAULT
2888
2889 from PyQt5 import QtWidgets
2890
2891-from openlp.core.common.path import Path
2892 from openlp.core.common.registry import Registry
2893 from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem
2894 from tests.helpers.testmixin import TestMixin
2895
2896=== modified file 'tests/functional/openlp_core/ui/test_themeform.py'
2897--- tests/functional/openlp_core/ui/test_themeform.py 2019-04-13 13:00:22 +0000
2898+++ tests/functional/openlp_core/ui/test_themeform.py 2019-05-23 20:08:25 +0000
2899@@ -22,10 +22,10 @@
2900 """
2901 Package to test the openlp.core.ui.themeform package.
2902 """
2903+from pathlib import Path
2904 from unittest import TestCase
2905 from unittest.mock import MagicMock, patch
2906
2907-from openlp.core.common.path import Path
2908 from openlp.core.ui.themeform import ThemeForm
2909
2910
2911
2912=== modified file 'tests/functional/openlp_core/ui/test_thememanager.py'
2913--- tests/functional/openlp_core/ui/test_thememanager.py 2019-05-04 11:49:20 +0000
2914+++ tests/functional/openlp_core/ui/test_thememanager.py 2019-05-23 20:08:25 +0000
2915@@ -24,13 +24,13 @@
2916 """
2917 import os
2918 import shutil
2919+from pathlib import Path
2920 from tempfile import mkdtemp
2921 from unittest import TestCase
2922 from unittest.mock import ANY, MagicMock, patch
2923
2924 from PyQt5 import QtWidgets
2925
2926-from openlp.core.common.path import Path
2927 from openlp.core.common.registry import Registry
2928 from openlp.core.ui.thememanager import ThemeManager
2929 from tests.utils.constants import RESOURCE_PATH
2930@@ -81,9 +81,9 @@
2931 # THEN: The the controller should be registered in the registry.
2932 assert Registry().get('theme_manager') is not None, 'The base theme manager should be registered'
2933
2934- @patch('openlp.core.ui.thememanager.copyfile')
2935+ @patch('openlp.core.ui.thememanager.shutil')
2936 @patch('openlp.core.ui.thememanager.create_paths')
2937- def test_write_theme_same_image(self, mocked_create_paths, mocked_copyfile):
2938+ def test_write_theme_same_image(self, mocked_create_paths, mocked_shutil):
2939 """
2940 Test that we don't try to overwrite a theme background image with itself
2941 """
2942@@ -103,11 +103,11 @@
2943 theme_manager._write_theme(mocked_theme, file_path_1, file_path_1)
2944
2945 # THEN: The mocked_copyfile should not have been called
2946- assert mocked_copyfile.called is False, 'copyfile should not be called'
2947+ assert mocked_shutil.copyfile.called is False, 'copyfile should not be called'
2948
2949- @patch('openlp.core.ui.thememanager.copyfile')
2950+ @patch('openlp.core.ui.thememanager.shutil')
2951 @patch('openlp.core.ui.thememanager.create_paths')
2952- def test_write_theme_diff_images(self, mocked_create_paths, mocked_copyfile):
2953+ def test_write_theme_diff_images(self, mocked_create_paths, mocked_shutil):
2954 """
2955 Test that we do overwrite a theme background image when a new is submitted
2956 """
2957@@ -127,7 +127,7 @@
2958 theme_manager._write_theme(mocked_theme, file_path_1, file_path_2)
2959
2960 # THEN: The mocked_copyfile should not have been called
2961- assert mocked_copyfile.called is True, 'copyfile should be called'
2962+ assert mocked_shutil.copyfile.called is True, 'copyfile should be called'
2963
2964 def test_write_theme_special_char_name(self):
2965 """
2966@@ -207,7 +207,7 @@
2967 # THEN: Files should be unpacked
2968 assert (folder_path / 'Moss on tree' / 'Moss on tree.xml').exists() is True
2969 assert mocked_critical_error_message_box.call_count == 0, 'No errors should have happened'
2970- folder_path.rmtree()
2971+ shutil.rmtree(folder_path)
2972
2973 def test_unzip_theme_invalid_version(self):
2974 """
2975
2976=== modified file 'tests/functional/openlp_core/widgets/test_dialogs.py'
2977--- tests/functional/openlp_core/widgets/test_dialogs.py 2019-04-13 13:00:22 +0000
2978+++ tests/functional/openlp_core/widgets/test_dialogs.py 2019-05-23 20:08:25 +0000
2979@@ -20,12 +20,12 @@
2980 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
2981 ##########################################################################
2982 import os
2983+from pathlib import Path
2984 from unittest import TestCase
2985 from unittest.mock import patch
2986
2987 from PyQt5 import QtWidgets
2988
2989-from openlp.core.common.path import Path
2990 from openlp.core.widgets.dialogs import FileDialog
2991
2992
2993
2994=== modified file 'tests/functional/openlp_core/widgets/test_edits.py'
2995--- tests/functional/openlp_core/widgets/test_edits.py 2019-04-13 13:00:22 +0000
2996+++ tests/functional/openlp_core/widgets/test_edits.py 2019-05-23 20:08:25 +0000
2997@@ -23,10 +23,10 @@
2998 This module contains tests for the openlp.core.widgets.edits module
2999 """
3000 import os
3001+from pathlib import Path
3002 from unittest import TestCase
3003 from unittest.mock import MagicMock, PropertyMock, patch
3004
3005-from openlp.core.common.path import Path
3006 from openlp.core.widgets.dialogs import FileDialog
3007 from openlp.core.widgets.edits import PathEdit
3008 from openlp.core.widgets.enums import PathEditType
3009
3010=== modified file 'tests/functional/openlp_plugins/bibles/test_bibleimport.py'
3011--- tests/functional/openlp_plugins/bibles/test_bibleimport.py 2019-04-13 13:00:22 +0000
3012+++ tests/functional/openlp_plugins/bibles/test_bibleimport.py 2019-05-23 20:08:25 +0000
3013@@ -23,6 +23,7 @@
3014 This module contains tests for the bibleimport module.
3015 """
3016 from io import BytesIO
3017+from pathlib import Path
3018 from unittest import TestCase
3019 from unittest.mock import MagicMock, patch
3020
3021@@ -30,7 +31,6 @@
3022 from PyQt5.QtWidgets import QDialog
3023
3024 from openlp.core.common.i18n import Language
3025-from openlp.core.common.path import Path
3026 from openlp.core.lib.exceptions import ValidationError
3027 from openlp.plugins.bibles.lib.bibleimport import BibleImport
3028 from openlp.plugins.bibles.lib.db import BibleDB
3029
3030=== modified file 'tests/functional/openlp_plugins/bibles/test_csvimport.py'
3031--- tests/functional/openlp_plugins/bibles/test_csvimport.py 2019-05-04 12:05:53 +0000
3032+++ tests/functional/openlp_plugins/bibles/test_csvimport.py 2019-05-23 20:08:25 +0000
3033@@ -24,10 +24,10 @@
3034 """
3035 import csv
3036 from collections import namedtuple
3037+from pathlib import Path
3038 from unittest import TestCase
3039 from unittest.mock import MagicMock, PropertyMock, call, patch
3040
3041-from openlp.core.common.path import Path
3042 from openlp.core.lib.exceptions import ValidationError
3043 from openlp.plugins.bibles.lib.bibleimport import BibleImport
3044 from openlp.plugins.bibles.lib.importers.csvbible import Book, CSVBible, Verse
3045
3046=== modified file 'tests/functional/openlp_plugins/bibles/test_manager.py'
3047--- tests/functional/openlp_plugins/bibles/test_manager.py 2019-04-28 19:21:23 +0000
3048+++ tests/functional/openlp_plugins/bibles/test_manager.py 2019-05-23 20:08:25 +0000
3049@@ -22,10 +22,10 @@
3050 """
3051 This module contains tests for the manager submodule of the Bibles plugin.
3052 """
3053+from pathlib import Path
3054 from unittest import TestCase
3055 from unittest.mock import MagicMock, patch
3056
3057-from openlp.core.common.path import Path
3058 from openlp.plugins.bibles.lib.manager import BibleManager
3059
3060
3061
3062=== modified file 'tests/functional/openlp_plugins/bibles/test_wordprojectimport.py'
3063--- tests/functional/openlp_plugins/bibles/test_wordprojectimport.py 2019-04-13 13:00:22 +0000
3064+++ tests/functional/openlp_plugins/bibles/test_wordprojectimport.py 2019-05-23 20:08:25 +0000
3065@@ -22,10 +22,10 @@
3066 """
3067 This module contains tests for the WordProject Bible importer.
3068 """
3069+from pathlib import Path
3070 from unittest import TestCase
3071 from unittest.mock import MagicMock, call, patch
3072
3073-from openlp.core.common.path import Path
3074 from openlp.plugins.bibles.lib.importers.wordproject import WordProjectBible
3075 from tests.utils.constants import RESOURCE_PATH
3076
3077
3078=== modified file 'tests/functional/openlp_plugins/images/test_lib.py'
3079--- tests/functional/openlp_plugins/images/test_lib.py 2019-04-13 13:00:22 +0000
3080+++ tests/functional/openlp_plugins/images/test_lib.py 2019-05-23 20:08:25 +0000
3081@@ -22,12 +22,12 @@
3082 """
3083 This module contains tests for the lib submodule of the Images plugin.
3084 """
3085+from pathlib import Path
3086 from unittest import TestCase
3087 from unittest.mock import ANY, MagicMock, patch
3088
3089 from PyQt5 import QtCore, QtWidgets
3090
3091-from openlp.core.common.path import Path
3092 from openlp.core.common.registry import Registry
3093 from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
3094 from openlp.plugins.images.lib.mediaitem import ImageMediaItem
3095
3096=== modified file 'tests/functional/openlp_plugins/images/test_upgrade.py'
3097--- tests/functional/openlp_plugins/images/test_upgrade.py 2019-04-13 13:00:22 +0000
3098+++ tests/functional/openlp_plugins/images/test_upgrade.py 2019-05-23 20:08:25 +0000
3099@@ -24,12 +24,12 @@
3100 """
3101 import os
3102 import shutil
3103+from pathlib import Path
3104 from tempfile import mkdtemp
3105 from unittest import TestCase, skip
3106 from unittest.mock import patch
3107
3108 from openlp.core.common.applocation import AppLocation
3109-from openlp.core.common.path import Path
3110 from openlp.core.common.settings import Settings
3111 from openlp.core.lib.db import Manager
3112 from openlp.plugins.images.lib import upgrade
3113
3114=== modified file 'tests/functional/openlp_plugins/media/test_mediaitem.py'
3115--- tests/functional/openlp_plugins/media/test_mediaitem.py 2019-04-13 13:00:22 +0000
3116+++ tests/functional/openlp_plugins/media/test_mediaitem.py 2019-05-23 20:08:25 +0000
3117@@ -22,12 +22,12 @@
3118 """
3119 Test the media plugin
3120 """
3121+from pathlib import Path
3122 from unittest import TestCase
3123 from unittest.mock import MagicMock, patch
3124
3125 from PyQt5 import QtCore
3126
3127-from openlp.core.common.path import Path
3128 from openlp.core.common.settings import Settings
3129 from openlp.plugins.media.lib.mediaitem import MediaMediaItem
3130 from tests.helpers.testmixin import TestMixin
3131
3132=== modified file 'tests/functional/openlp_plugins/presentations/test_mediaitem.py'
3133--- tests/functional/openlp_plugins/presentations/test_mediaitem.py 2019-05-02 13:45:07 +0000
3134+++ tests/functional/openlp_plugins/presentations/test_mediaitem.py 2019-05-23 20:08:25 +0000
3135@@ -22,10 +22,10 @@
3136 """
3137 This module contains tests for the lib submodule of the Presentations plugin.
3138 """
3139+from pathlib import Path
3140 from unittest import TestCase
3141 from unittest.mock import MagicMock, call, patch
3142
3143-from openlp.core.common.path import Path
3144 from openlp.core.common.registry import Registry
3145 from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem
3146 from tests.helpers.testmixin import TestMixin
3147
3148=== modified file 'tests/functional/openlp_plugins/presentations/test_pdfcontroller.py'
3149--- tests/functional/openlp_plugins/presentations/test_pdfcontroller.py 2019-05-02 17:11:55 +0000
3150+++ tests/functional/openlp_plugins/presentations/test_pdfcontroller.py 2019-05-23 20:08:25 +0000
3151@@ -23,7 +23,8 @@
3152 This module contains tests for the PdfController
3153 """
3154 import os
3155-from shutil import which
3156+from pathlib import Path
3157+from shutil import rmtree, which
3158 from tempfile import mkdtemp
3159 from unittest import TestCase
3160 from unittest.mock import MagicMock, patch
3161@@ -31,7 +32,6 @@
3162 from PyQt5 import QtCore, QtGui
3163
3164 from openlp.core.common import is_macosx, is_linux, is_win
3165-from openlp.core.common.path import Path
3166 from openlp.core.common.settings import Settings
3167 from openlp.core.display.screens import ScreenList
3168 from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
3169@@ -99,8 +99,8 @@
3170 """
3171 del self.screens
3172 self.destroy_settings()
3173- self.thumbnail_folder_path.rmtree()
3174- self.temp_folder_path.rmtree()
3175+ rmtree(self.thumbnail_folder_path)
3176+ rmtree(self.temp_folder_path)
3177
3178 def test_constructor(self):
3179 """
3180
3181=== modified file 'tests/functional/openlp_plugins/presentations/test_presentationcontroller.py'
3182--- tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2019-04-13 13:00:22 +0000
3183+++ tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2019-05-23 20:08:25 +0000
3184@@ -23,10 +23,10 @@
3185 Functional tests to test the PresentationController and PresentationDocument
3186 classes and related methods.
3187 """
3188+from pathlib import Path
3189 from unittest import TestCase
3190 from unittest.mock import MagicMock, call, patch
3191
3192-from openlp.core.common.path import Path
3193 from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
3194
3195
3196
3197=== modified file 'tests/functional/openlp_plugins/songs/test_openlyricsexport.py'
3198--- tests/functional/openlp_plugins/songs/test_openlyricsexport.py 2019-04-13 13:00:22 +0000
3199+++ tests/functional/openlp_plugins/songs/test_openlyricsexport.py 2019-05-23 20:08:25 +0000
3200@@ -22,11 +22,12 @@
3201 """
3202 This module contains tests for the OpenLyrics song importer.
3203 """
3204+import shutil
3205+from pathlib import Path
3206 from tempfile import mkdtemp
3207 from unittest import TestCase
3208 from unittest.mock import MagicMock, patch
3209
3210-from openlp.core.common.path import Path
3211 from openlp.core.common.registry import Registry
3212 from openlp.plugins.songs.lib.openlyricsexport import OpenLyricsExport
3213 from tests.helpers.testmixin import TestMixin
3214@@ -47,7 +48,7 @@
3215 """
3216 Cleanup
3217 """
3218- self.temp_folder.rmtree()
3219+ shutil.rmtree(self.temp_folder)
3220
3221 def test_export_same_filename(self):
3222 """
3223
3224=== modified file 'tests/helpers/songfileimport.py'
3225--- tests/helpers/songfileimport.py 2019-04-13 13:00:22 +0000
3226+++ tests/helpers/songfileimport.py 2019-05-23 20:08:25 +0000
3227@@ -82,7 +82,7 @@
3228 """
3229 A method to load and return an object containing the song data from an external file.
3230
3231- :param openlp.core.common.path.Path file_path: The path of the file to load
3232+ :param pathlib.Path file_path: The path of the file to load
3233 """
3234 return json.loads(file_path.read_bytes().decode())
3235
3236
3237=== modified file 'tests/interfaces/openlp_core/lib/test_pluginmanager.py'
3238--- tests/interfaces/openlp_core/lib/test_pluginmanager.py 2019-04-13 13:00:22 +0000
3239+++ tests/interfaces/openlp_core/lib/test_pluginmanager.py 2019-05-23 20:08:25 +0000
3240@@ -22,7 +22,9 @@
3241 """
3242 Package to test the openlp.core.lib.pluginmanager package.
3243 """
3244+import shutil
3245 import sys
3246+from pathlib import Path
3247 from tempfile import mkdtemp
3248 from unittest import TestCase, skip
3249 from unittest.mock import MagicMock, patch
3250@@ -30,7 +32,6 @@
3251 from PyQt5 import QtWidgets
3252
3253 from openlp.core.common import is_win
3254-from openlp.core.common.path import Path
3255 from openlp.core.common.registry import Registry
3256 from openlp.core.common.settings import Settings
3257 from openlp.core.state import State
3258@@ -65,7 +66,7 @@
3259 if is_win():
3260 import gc
3261 gc.collect()
3262- self.temp_dir_path.rmtree()
3263+ shutil.rmtree(self.temp_dir_path)
3264
3265 @skip
3266 # This test is broken but totally unable to debug it.
3267
3268=== modified file 'tests/interfaces/openlp_core/ui/test_firsttimeform.py'
3269--- tests/interfaces/openlp_core/ui/test_firsttimeform.py 2019-04-13 13:00:22 +0000
3270+++ tests/interfaces/openlp_core/ui/test_firsttimeform.py 2019-05-23 20:08:25 +0000
3271@@ -22,10 +22,10 @@
3272 """
3273 Package to test the openlp.core.ui.firsttimeform package.
3274 """
3275+from pathlib import Path
3276 from unittest import TestCase
3277 from unittest.mock import MagicMock, call, patch
3278
3279-from openlp.core.common.path import Path
3280 from openlp.core.common.registry import Registry
3281 from openlp.core.ui.firsttimeform import ThemeListWidgetItem
3282 from openlp.core.ui.icons import UiIcons
3283
3284=== modified file 'tests/interfaces/openlp_core/ui/test_thememanager.py'
3285--- tests/interfaces/openlp_core/ui/test_thememanager.py 2019-04-13 13:00:22 +0000
3286+++ tests/interfaces/openlp_core/ui/test_thememanager.py 2019-05-23 20:08:25 +0000
3287@@ -22,10 +22,10 @@
3288 """
3289 Interface tests to test the themeManager class and related methods.
3290 """
3291+from pathlib import Path
3292 from unittest import TestCase
3293 from unittest.mock import MagicMock, patch
3294
3295-from openlp.core.common.path import Path
3296 from openlp.core.common.registry import Registry
3297 from openlp.core.common.settings import Settings
3298 from openlp.core.ui.thememanager import ThemeManager
3299
3300=== modified file 'tests/utils/__init__.py'
3301--- tests/utils/__init__.py 2019-04-13 13:00:22 +0000
3302+++ tests/utils/__init__.py 2019-05-23 20:08:25 +0000
3303@@ -44,6 +44,6 @@
3304 """
3305 A method to load and return an object containing the song data from an external file.
3306
3307- :param openlp.core.common.path.Path file_path: The path of the file to load
3308+ :param pathlib.Path file_path: The path of the file to load
3309 """
3310 return json.loads(file_path.read_bytes().decode())
3311
3312=== modified file 'tests/utils/constants.py'
3313--- tests/utils/constants.py 2019-04-13 13:00:22 +0000
3314+++ tests/utils/constants.py 2019-05-23 20:08:25 +0000
3315@@ -20,8 +20,7 @@
3316 # along with this program. If not, see <https://www.gnu.org/licenses/>. #
3317 ##########################################################################
3318 import os
3319-
3320-from openlp.core.common.path import Path
3321+from pathlib import Path
3322
3323
3324 OPENLP_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))