Status: | Superseded |
---|---|
Proposed branch: | lp:~phill-ridout/openlp/pathlib3 |
Merge into: | lp:openlp |
Diff against target: |
1730 lines (+292/-327) 42 files modified
openlp/core/__init__.py (+16/-12) openlp/core/common/__init__.py (+47/-47) openlp/core/common/applocation.py (+8/-19) openlp/core/common/settings.py (+0/-28) openlp/core/lib/__init__.py (+13/-15) openlp/core/lib/db.py (+2/-2) openlp/core/lib/pluginmanager.py (+1/-1) openlp/core/lib/theme.py (+2/-3) openlp/core/ui/firsttimeform.py (+3/-2) openlp/core/ui/mainwindow.py (+2/-1) openlp/core/ui/media/mediacontroller.py (+1/-1) openlp/core/ui/printserviceform.py (+1/-1) openlp/core/ui/servicemanager.py (+6/-5) openlp/core/ui/themeform.py (+3/-1) openlp/core/ui/thememanager.py (+13/-12) openlp/plugins/bibles/lib/importers/csvbible.py (+2/-1) openlp/plugins/bibles/lib/manager.py (+3/-2) openlp/plugins/images/lib/mediaitem.py (+6/-5) openlp/plugins/media/lib/mediaitem.py (+2/-1) openlp/plugins/media/mediaplugin.py (+2/-2) openlp/plugins/presentations/lib/impresscontroller.py (+2/-1) openlp/plugins/presentations/lib/pdfcontroller.py (+2/-1) openlp/plugins/presentations/lib/presentationcontroller.py (+4/-3) openlp/plugins/presentations/presentationplugin.py (+1/-1) openlp/plugins/songs/forms/editsongform.py (+1/-1) openlp/plugins/songs/lib/importers/songbeamer.py (+2/-1) openlp/plugins/songs/lib/importers/songimport.py (+2/-1) openlp/plugins/songs/lib/mediaitem.py (+3/-2) openlp/plugins/songs/lib/openlyricsexport.py (+2/-1) openlp/plugins/songusage/forms/songusagedetailform.py (+2/-1) tests/functional/openlp_core_common/test_applocation.py (+5/-7) tests/functional/openlp_core_common/test_common.py (+61/-35) tests/functional/openlp_core_common/test_init.py (+36/-32) tests/functional/openlp_core_lib/test_db.py (+5/-4) tests/functional/openlp_core_lib/test_file_dialog.py (+0/-45) tests/functional/openlp_core_lib/test_lib.py (+15/-15) tests/functional/openlp_core_ui/test_firsttimeform.py (+2/-1) tests/functional/openlp_core_ui/test_thememanager.py (+2/-2) tests/functional/openlp_plugins/bibles/test_manager.py (+2/-2) tests/functional/openlp_plugins/media/test_mediaplugin.py (+3/-5) tests/functional/openlp_plugins/presentations/test_presentationcontroller.py (+4/-2) tests/interfaces/openlp_core_common/test_utils.py (+3/-3) |
To merge this branch: | bzr merge lp:~phill-ridout/openlp/pathlib3 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tomas Groth | Needs Fixing | ||
Raoul Snyman | Needs Information | ||
Tim Bentley | Needs Fixing | ||
Review via email: mp+328950@code.launchpad.net |
This proposal has been superseded by a proposal from 2017-08-23.
Commit message
Description of the change
Part 3, converted some more utility methods
lp:~phill-ridout/openlp/pathlib3 (revision 2759)
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[SUCCESS] https:/
[FAILURE] https:/
Stopping after failure
Raoul Snyman (raoul-snyman) : | # |
Phill (phill-ridout) wrote : | # |
> See inline
See my inline reply.
Phill (phill-ridout) wrote : | # |
See my inline reply.
Phill (phill-ridout) wrote : | # |
See inline
Tomas Groth (tomasgroth) wrote : | # |
It seems the AppVeyor tests fails for a reason: https:/
Unmerged revisions
Preview Diff
1 | === modified file 'openlp/core/__init__.py' |
2 | --- openlp/core/__init__.py 2017-08-03 17:54:40 +0000 |
3 | +++ openlp/core/__init__.py 2017-08-23 20:14:53 +0000 |
4 | @@ -33,6 +33,7 @@ |
5 | import shutil |
6 | import sys |
7 | import time |
8 | +from pathlib import Path |
9 | from traceback import format_exception |
10 | |
11 | from PyQt5 import QtCore, QtGui, QtWidgets |
12 | @@ -346,15 +347,18 @@ |
13 | """ |
14 | Setup our logging using log_path |
15 | |
16 | - :param log_path: the path |
17 | + :param pathlib.Path log_path: The file to save the log to |
18 | + :return: None |
19 | + :rtype: None |
20 | """ |
21 | check_directory_exists(log_path, True) |
22 | - filename = os.path.join(log_path, 'openlp.log') |
23 | - logfile = logging.FileHandler(filename, 'w', encoding="UTF-8") |
24 | + file_path = log_path / 'openlp.log' |
25 | + # TODO: FileHandler accepts a Path object in Py3.6 |
26 | + logfile = logging.FileHandler(str(file_path), 'w', encoding='UTF-8') |
27 | logfile.setFormatter(logging.Formatter('%(asctime)s %(name)-55s %(levelname)-8s %(message)s')) |
28 | log.addHandler(logfile) |
29 | if log.isEnabledFor(logging.DEBUG): |
30 | - print('Logging to: {name}'.format(name=filename)) |
31 | + print('Logging to: {name}'.format(name=file_path)) |
32 | |
33 | |
34 | def main(args=None): |
35 | @@ -390,24 +394,24 @@ |
36 | application.setApplicationName('OpenLPPortable') |
37 | Settings.setDefaultFormat(Settings.IniFormat) |
38 | # Get location OpenLPPortable.ini |
39 | - application_path = str(AppLocation.get_directory(AppLocation.AppDir)) |
40 | - set_up_logging(os.path.abspath(os.path.join(application_path, '..', '..', 'Other'))) |
41 | + portable_path = (AppLocation.get_directory(AppLocation.AppDir) / '..' / '..').resolve() |
42 | + data_path = portable_path / 'Data' |
43 | + set_up_logging(portable_path / 'Other') |
44 | log.info('Running portable') |
45 | - portable_settings_file = os.path.abspath(os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini')) |
46 | + portable_settings_path = data_path / 'OpenLP.ini' |
47 | # Make this our settings file |
48 | - log.info('INI file: {name}'.format(name=portable_settings_file)) |
49 | - Settings.set_filename(portable_settings_file) |
50 | + log.info('INI file: {name}'.format(name=portable_settings_path)) |
51 | + Settings.set_filename(str(portable_settings_path)) |
52 | portable_settings = Settings() |
53 | # Set our data path |
54 | - data_path = os.path.abspath(os.path.join(application_path, '..', '..', 'Data',)) |
55 | log.info('Data path: {name}'.format(name=data_path)) |
56 | # Point to our data path |
57 | - portable_settings.setValue('advanced/data path', data_path) |
58 | + portable_settings.setValue('advanced/data path', str(data_path)) |
59 | portable_settings.setValue('advanced/is portable', True) |
60 | portable_settings.sync() |
61 | else: |
62 | application.setApplicationName('OpenLP') |
63 | - set_up_logging(str(AppLocation.get_directory(AppLocation.CacheDir))) |
64 | + set_up_logging(AppLocation.get_directory(AppLocation.CacheDir)) |
65 | Registry.create() |
66 | Registry().register('application', application) |
67 | Registry().set_flag('no_web_server', args.no_web_server) |
68 | |
69 | === modified file 'openlp/core/common/__init__.py' |
70 | --- openlp/core/common/__init__.py 2017-08-01 20:59:41 +0000 |
71 | +++ openlp/core/common/__init__.py 2017-08-23 20:14:53 +0000 |
72 | @@ -32,7 +32,6 @@ |
73 | import traceback |
74 | from chardet.universaldetector import UniversalDetector |
75 | from ipaddress import IPv4Address, IPv6Address, AddressValueError |
76 | -from pathlib import Path |
77 | from shutil import which |
78 | from subprocess import check_output, CalledProcessError, STDOUT |
79 | |
80 | @@ -65,17 +64,19 @@ |
81 | |
82 | def check_directory_exists(directory, do_not_log=False): |
83 | """ |
84 | - Check a theme directory exists and if not create it |
85 | + Check a directory exists and if not create it |
86 | |
87 | - :param directory: The directory to make sure exists |
88 | - :param do_not_log: To not log anything. This is need for the start up, when the log isn't ready. |
89 | + :param pathlib.Path directory: The directory to make sure exists |
90 | + :param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready. |
91 | + :return: None |
92 | + :rtype: None |
93 | """ |
94 | if not do_not_log: |
95 | log.debug('check_directory_exists {text}'.format(text=directory)) |
96 | try: |
97 | - if not os.path.exists(directory): |
98 | - os.makedirs(directory) |
99 | - except IOError as e: |
100 | + if not directory.exists(): |
101 | + directory.mkdir(parents=True) |
102 | + except IOError: |
103 | if not do_not_log: |
104 | log.exception('failed to check if directory exists or create directory') |
105 | |
106 | @@ -85,19 +86,15 @@ |
107 | A utility function to find and load OpenLP extensions, such as plugins, presentation and media controllers and |
108 | importers. |
109 | |
110 | - :param glob_pattern: A glob pattern used to find the extension(s) to be imported. Should be relative to the |
111 | - application directory. i.e. openlp/plugins/*/*plugin.py |
112 | - :type glob_pattern: str |
113 | - |
114 | - :param excluded_files: A list of file names to exclude that the glob pattern may find. |
115 | - :type excluded_files: list of strings |
116 | - |
117 | + :param str glob_pattern: A glob pattern used to find the extension(s) to be imported. Should be relative to the |
118 | + application directory. i.e. plugins/*/*plugin.py |
119 | + :param list[str] excluded_files: A list of file names to exclude that the glob pattern may find. |
120 | :return: None |
121 | :rtype: None |
122 | """ |
123 | - base_dir_path = AppLocation.get_directory(AppLocation.AppDir).parent |
124 | - for extension_path in base_dir_path.glob(glob_pattern): |
125 | - extension_path = extension_path.relative_to(base_dir_path) |
126 | + app_dir = AppLocation.get_directory(AppLocation.AppDir) |
127 | + for extension_path in app_dir.glob(glob_pattern): |
128 | + extension_path = extension_path.relative_to(app_dir) |
129 | if extension_path.name in excluded_files: |
130 | continue |
131 | module_name = path_to_module(extension_path) |
132 | @@ -106,21 +103,19 @@ |
133 | except (ImportError, OSError): |
134 | # On some platforms importing vlc.py might cause OSError exceptions. (e.g. Mac OS X) |
135 | log.warning('Failed to import {module_name} on path {extension_path}' |
136 | - .format(module_name=module_name, extension_path=str(extension_path))) |
137 | + .format(module_name=module_name, extension_path=extension_path)) |
138 | |
139 | |
140 | def path_to_module(path): |
141 | """ |
142 | Convert a path to a module name (i.e openlp.core.common) |
143 | |
144 | - :param path: The path to convert to a module name. |
145 | - :type path: Path |
146 | - |
147 | + :param pathlib.Path path: The path to convert to a module name. |
148 | :return: The module name. |
149 | :rtype: str |
150 | """ |
151 | module_path = path.with_suffix('') |
152 | - return '.'.join(module_path.parts) |
153 | + return 'openlp.' + '.'.join(module_path.parts) |
154 | |
155 | |
156 | def get_frozen_path(frozen_option, non_frozen_option): |
157 | @@ -378,20 +373,22 @@ |
158 | return os.path.split(path) |
159 | |
160 | |
161 | -def delete_file(file_path_name): |
162 | +def delete_file(file_path): |
163 | """ |
164 | Deletes a file from the system. |
165 | |
166 | - :param file_path_name: The file, including path, to delete. |
167 | + :param pathlib.Path file_path: The file, including path, to delete. |
168 | + :return: True if the deletion was successful, or the file never existed. False otherwise. |
169 | + :rtype: bool |
170 | """ |
171 | - if not file_path_name: |
172 | + if not file_path: |
173 | return False |
174 | try: |
175 | - if os.path.exists(file_path_name): |
176 | - os.remove(file_path_name) |
177 | + if file_path.exists(): |
178 | + file_path.unlink() |
179 | return True |
180 | except (IOError, OSError): |
181 | - log.exception("Unable to delete file {text}".format(text=file_path_name)) |
182 | + log.exception('Unable to delete file {file_path}'.format(file_path=file_path)) |
183 | return False |
184 | |
185 | |
186 | @@ -411,18 +408,19 @@ |
187 | return IMAGES_FILTER |
188 | |
189 | |
190 | -def is_not_image_file(file_name): |
191 | +def is_not_image_file(file_path): |
192 | """ |
193 | Validate that the file is not an image file. |
194 | |
195 | - :param file_name: File name to be checked. |
196 | + :param pathlib.Path file_path: The file to be checked. |
197 | + :return: If the file is not an image |
198 | + :rtype: bool |
199 | """ |
200 | - if not file_name: |
201 | + if not (file_path and file_path.exists()): |
202 | return True |
203 | else: |
204 | formats = [bytes(fmt).decode().lower() for fmt in QtGui.QImageReader.supportedImageFormats()] |
205 | - file_part, file_extension = os.path.splitext(str(file_name)) |
206 | - if file_extension[1:].lower() in formats and os.path.exists(file_name): |
207 | + if file_path.suffix[1:].lower() in formats: |
208 | return False |
209 | return True |
210 | |
211 | @@ -431,10 +429,10 @@ |
212 | """ |
213 | Removes invalid characters from the given ``filename``. |
214 | |
215 | - :param filename: The "dirty" file name to clean. |
216 | + :param str filename: The "dirty" file name to clean. |
217 | + :return: The cleaned string |
218 | + :rtype: str |
219 | """ |
220 | - if not isinstance(filename, str): |
221 | - filename = str(filename, 'utf-8') |
222 | return INVALID_FILE_CHARS.sub('_', CONTROL_CHARS.sub('', filename)) |
223 | |
224 | |
225 | @@ -442,8 +440,9 @@ |
226 | """ |
227 | Function that checks whether a binary exists. |
228 | |
229 | - :param program_path: The full path to the binary to check. |
230 | + :param pathlib.Path program_path: The full path to the binary to check. |
231 | :return: program output to be parsed |
232 | + :rtype: bytes |
233 | """ |
234 | log.debug('testing program_path: {text}'.format(text=program_path)) |
235 | try: |
236 | @@ -453,26 +452,27 @@ |
237 | startupinfo.dwFlags |= STARTF_USESHOWWINDOW |
238 | else: |
239 | startupinfo = None |
240 | - runlog = check_output([program_path, '--help'], stderr=STDOUT, startupinfo=startupinfo) |
241 | + run_log = check_output([str(program_path), '--help'], stderr=STDOUT, startupinfo=startupinfo) |
242 | except CalledProcessError as e: |
243 | - runlog = e.output |
244 | + run_log = e.output |
245 | except Exception: |
246 | trace_error_handler(log) |
247 | - runlog = '' |
248 | - log.debug('check_output returned: {text}'.format(text=runlog)) |
249 | - return runlog |
250 | - |
251 | - |
252 | -def get_file_encoding(filename): |
253 | + run_log = '' |
254 | + log.debug('check_output returned: {text}'.format(text=run_log)) |
255 | + return run_log |
256 | + |
257 | + |
258 | +def get_file_encoding(file_path): |
259 | """ |
260 | Utility function to incrementally detect the file encoding. |
261 | |
262 | - :param filename: Filename for the file to determine the encoding for. Str |
263 | + :param pathlib.Path file_path: Filename for the file to determine the encoding for. |
264 | :return: A dict with the keys 'encoding' and 'confidence' |
265 | + :rtype: dict[str, float] |
266 | """ |
267 | detector = UniversalDetector() |
268 | try: |
269 | - with open(filename, 'rb') as detect_file: |
270 | + with file_path.open('rb') as detect_file: |
271 | while not detector.done: |
272 | chunk = detect_file.read(1024) |
273 | if not chunk: |
274 | |
275 | === modified file 'openlp/core/common/applocation.py' |
276 | --- openlp/core/common/applocation.py 2017-08-02 06:09:38 +0000 |
277 | +++ openlp/core/common/applocation.py 2017-08-23 20:14:53 +0000 |
278 | @@ -58,9 +58,6 @@ |
279 | CacheDir = 5 |
280 | LanguageDir = 6 |
281 | |
282 | - # Base path where data/config/cache dir is located |
283 | - BaseDir = None |
284 | - |
285 | @staticmethod |
286 | def get_directory(dir_type=AppDir): |
287 | """ |
288 | @@ -78,8 +75,6 @@ |
289 | return get_frozen_path(FROZEN_APP_PATH, APP_PATH) / 'plugins' |
290 | elif dir_type == AppLocation.LanguageDir: |
291 | return get_frozen_path(FROZEN_APP_PATH, _get_os_dir_path(dir_type)) / 'i18n' |
292 | - elif dir_type == AppLocation.DataDir and AppLocation.BaseDir: |
293 | - return Path(AppLocation.BaseDir, 'data') |
294 | else: |
295 | return _get_os_dir_path(dir_type) |
296 | |
297 | @@ -96,7 +91,7 @@ |
298 | path = Path(Settings().value('advanced/data path')) |
299 | else: |
300 | path = AppLocation.get_directory(AppLocation.DataDir) |
301 | - check_directory_exists(str(path)) |
302 | + check_directory_exists(path) |
303 | return path |
304 | |
305 | @staticmethod |
306 | @@ -104,14 +99,10 @@ |
307 | """ |
308 | Get a list of files from the data files path. |
309 | |
310 | - :param section: Defaults to *None*. The section of code getting the files - used to load from a section's data |
311 | - subdirectory. |
312 | - :type section: None | str |
313 | - |
314 | - :param extension: Defaults to ''. The extension to search for. For example:: |
315 | + :param None | str section: Defaults to *None*. The section of code getting the files - used to load from a |
316 | + section's data subdirectory. |
317 | + :param str extension: Defaults to ''. The extension to search for. For example:: |
318 | '.png' |
319 | - :type extension: str |
320 | - |
321 | :return: List of files found. |
322 | :rtype: list[pathlib.Path] |
323 | """ |
324 | @@ -134,7 +125,7 @@ |
325 | :rtype: pathlib.Path |
326 | """ |
327 | path = AppLocation.get_data_path() / section |
328 | - check_directory_exists(str(path)) |
329 | + check_directory_exists(path) |
330 | return path |
331 | |
332 | |
333 | @@ -143,14 +134,12 @@ |
334 | Return a path based on which OS and environment we are running in. |
335 | |
336 | :param dir_type: AppLocation Enum of the requested path type |
337 | - :type dir_type: AppLocation Enum |
338 | - |
339 | :return: The requested path |
340 | :rtype: pathlib.Path |
341 | """ |
342 | # If running from source, return the language directory from the source directory |
343 | if dir_type == AppLocation.LanguageDir: |
344 | - directory = Path(os.path.abspath(os.path.join(os.path.dirname(openlp.__file__), '..', 'resources'))) |
345 | + directory = Path(openlp.__file__, '..', '..').resolve() / 'resources' |
346 | if directory.exists(): |
347 | return directory |
348 | if is_win(): |
349 | @@ -158,14 +147,14 @@ |
350 | if dir_type == AppLocation.DataDir: |
351 | return openlp_folder_path / 'data' |
352 | elif dir_type == AppLocation.LanguageDir: |
353 | - return os.path.dirname(openlp.__file__) |
354 | + return Path(openlp.__file__).parent |
355 | return openlp_folder_path |
356 | elif is_macosx(): |
357 | openlp_folder_path = Path(os.getenv('HOME'), 'Library', 'Application Support', 'openlp') |
358 | if dir_type == AppLocation.DataDir: |
359 | return openlp_folder_path / 'Data' |
360 | elif dir_type == AppLocation.LanguageDir: |
361 | - return os.path.dirname(openlp.__file__) |
362 | + return Path(openlp.__file__).parent |
363 | return openlp_folder_path |
364 | else: |
365 | if dir_type == AppLocation.LanguageDir: |
366 | |
367 | === modified file 'openlp/core/common/settings.py' |
368 | --- openlp/core/common/settings.py 2017-06-09 15:56:40 +0000 |
369 | +++ openlp/core/common/settings.py 2017-08-23 20:14:53 +0000 |
370 | @@ -501,31 +501,3 @@ |
371 | if isinstance(default_value, int): |
372 | return int(setting) |
373 | return setting |
374 | - |
375 | - def get_files_from_config(self, plugin): |
376 | - """ |
377 | - This removes the settings needed for old way we saved files (e. g. the image paths for the image plugin). A list |
378 | - of file paths are returned. |
379 | - |
380 | - **Note**: Only a list of paths is returned; this does not convert anything! |
381 | - |
382 | - :param plugin: The Plugin object.The caller has to convert/save the list himself; o |
383 | - """ |
384 | - files_list = [] |
385 | - # We need QSettings instead of Settings here to bypass our central settings dict. |
386 | - # Do NOT do this anywhere else! |
387 | - settings = QtCore.QSettings(self.fileName(), Settings.IniFormat) |
388 | - settings.beginGroup(plugin.settings_section) |
389 | - if settings.contains('{name} count'.format(name=plugin.name)): |
390 | - # Get the count. |
391 | - list_count = int(settings.value('{name} count'.format(name=plugin.name), 0)) |
392 | - if list_count: |
393 | - for counter in range(list_count): |
394 | - # The keys were named e. g.: "image 0" |
395 | - item = settings.value('{name} {counter:d}'.format(name=plugin.name, counter=counter), '') |
396 | - if item: |
397 | - files_list.append(item) |
398 | - settings.remove('{name} {counter:d}'.format(name=plugin.name, counter=counter)) |
399 | - settings.remove('{name} count'.format(name=plugin.name)) |
400 | - settings.endGroup() |
401 | - return files_list |
402 | |
403 | === modified file 'openlp/core/lib/__init__.py' |
404 | --- openlp/core/lib/__init__.py 2017-08-07 20:51:50 +0000 |
405 | +++ openlp/core/lib/__init__.py 2017-08-23 20:14:53 +0000 |
406 | @@ -83,30 +83,28 @@ |
407 | Next = 3 |
408 | |
409 | |
410 | -def get_text_file_string(text_file): |
411 | +def get_text_file_string(text_file_path): |
412 | """ |
413 | - Open a file and return its content as unicode string. If the supplied file name is not a file then the function |
414 | + Open a file and return its content as a string. If the supplied file path is not a file then the function |
415 | returns False. If there is an error loading the file or the content can't be decoded then the function will return |
416 | None. |
417 | |
418 | - :param text_file: The name of the file. |
419 | - :return: The file as a single string |
420 | + :param pathlib.Path text_file_path: The path to the file. |
421 | + :return: The contents of the file, False if the file does not exist, or None if there is an Error reading or |
422 | + decoding the file. |
423 | + :rtype: str | False | None |
424 | """ |
425 | - if not os.path.isfile(text_file): |
426 | + if not text_file_path.is_file(): |
427 | return False |
428 | - file_handle = None |
429 | content = None |
430 | try: |
431 | - file_handle = open(text_file, 'r', encoding='utf-8') |
432 | - if file_handle.read(3) != '\xEF\xBB\xBF': |
433 | - # no BOM was found |
434 | - file_handle.seek(0) |
435 | - content = file_handle.read() |
436 | + with text_file_path.open('r', encoding='utf-8') as file_handle: |
437 | + if file_handle.read(3) != '\xEF\xBB\xBF': |
438 | + # no BOM was found |
439 | + file_handle.seek(0) |
440 | + content = file_handle.read() |
441 | except (IOError, UnicodeError): |
442 | - log.exception('Failed to open text file {text}'.format(text=text_file)) |
443 | - finally: |
444 | - if file_handle: |
445 | - file_handle.close() |
446 | + log.exception('Failed to open text file {text}'.format(text=text_file_path)) |
447 | return content |
448 | |
449 | |
450 | |
451 | === modified file 'openlp/core/lib/db.py' |
452 | --- openlp/core/lib/db.py 2017-08-01 20:59:41 +0000 |
453 | +++ openlp/core/lib/db.py 2017-08-23 20:14:53 +0000 |
454 | @@ -274,9 +274,9 @@ |
455 | :param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used. |
456 | """ |
457 | if db_file_name: |
458 | - db_file_path = os.path.join(str(AppLocation.get_section_data_path(plugin_name)), db_file_name) |
459 | + db_file_path = AppLocation.get_section_data_path(plugin_name) / db_file_name |
460 | else: |
461 | - db_file_path = os.path.join(str(AppLocation.get_section_data_path(plugin_name)), plugin_name) |
462 | + db_file_path = AppLocation.get_section_data_path(plugin_name) / plugin_name |
463 | return delete_file(db_file_path) |
464 | |
465 | |
466 | |
467 | === modified file 'openlp/core/lib/pluginmanager.py' |
468 | --- openlp/core/lib/pluginmanager.py 2017-08-01 20:59:41 +0000 |
469 | +++ openlp/core/lib/pluginmanager.py 2017-08-23 20:14:53 +0000 |
470 | @@ -69,7 +69,7 @@ |
471 | """ |
472 | Scan a directory for objects inheriting from the ``Plugin`` class. |
473 | """ |
474 | - glob_pattern = os.path.join('openlp', 'plugins', '*', '*plugin.py') |
475 | + glob_pattern = os.path.join('plugins', '*', '*plugin.py') |
476 | extension_loader(glob_pattern) |
477 | plugin_classes = Plugin.__subclasses__() |
478 | plugin_objects = [] |
479 | |
480 | === modified file 'openlp/core/lib/theme.py' |
481 | --- openlp/core/lib/theme.py 2017-08-01 20:59:41 +0000 |
482 | +++ openlp/core/lib/theme.py 2017-08-23 20:14:53 +0000 |
483 | @@ -158,9 +158,8 @@ |
484 | Initialise the theme object. |
485 | """ |
486 | # basic theme object with defaults |
487 | - json_dir = os.path.join(str(AppLocation.get_directory(AppLocation.AppDir)), 'core', 'lib', 'json') |
488 | - json_file = os.path.join(json_dir, 'theme.json') |
489 | - jsn = get_text_file_string(json_file) |
490 | + json_path = AppLocation.get_directory(AppLocation.AppDir) / 'core' / 'lib' / 'json' / 'theme.json' |
491 | + jsn = get_text_file_string(json_path) |
492 | jsn = json.loads(jsn) |
493 | self.expand_json(jsn) |
494 | self.background_filename = '' |
495 | |
496 | === modified file 'openlp/core/ui/firsttimeform.py' |
497 | --- openlp/core/ui/firsttimeform.py 2017-08-03 17:54:40 +0000 |
498 | +++ openlp/core/ui/firsttimeform.py 2017-08-23 20:14:53 +0000 |
499 | @@ -29,8 +29,9 @@ |
500 | import urllib.request |
501 | import urllib.parse |
502 | import urllib.error |
503 | +from configparser import ConfigParser, MissingSectionHeaderError, NoOptionError, NoSectionError |
504 | +from pathlib import Path |
505 | from tempfile import gettempdir |
506 | -from configparser import ConfigParser, MissingSectionHeaderError, NoSectionError, NoOptionError |
507 | |
508 | from PyQt5 import QtCore, QtWidgets |
509 | |
510 | @@ -282,7 +283,7 @@ |
511 | self.no_internet_cancel_button.setVisible(False) |
512 | # Check if this is a re-run of the wizard. |
513 | self.has_run_wizard = Settings().value('core/has run wizard') |
514 | - check_directory_exists(os.path.join(gettempdir(), 'openlp')) |
515 | + check_directory_exists(Path(gettempdir(), 'openlp')) |
516 | |
517 | def update_screen_list_combo(self): |
518 | """ |
519 | |
520 | === modified file 'openlp/core/ui/mainwindow.py' |
521 | --- openlp/core/ui/mainwindow.py 2017-08-03 17:54:40 +0000 |
522 | +++ openlp/core/ui/mainwindow.py 2017-08-23 20:14:53 +0000 |
523 | @@ -30,6 +30,7 @@ |
524 | from datetime import datetime |
525 | from distutils import dir_util |
526 | from distutils.errors import DistutilsFileError |
527 | +from pathlib import Path |
528 | from tempfile import gettempdir |
529 | |
530 | from PyQt5 import QtCore, QtGui, QtWidgets |
531 | @@ -870,7 +871,7 @@ |
532 | setting_sections.extend([plugin.name for plugin in self.plugin_manager.plugins]) |
533 | # Copy the settings file to the tmp dir, because we do not want to change the original one. |
534 | temp_directory = os.path.join(str(gettempdir()), 'openlp') |
535 | - check_directory_exists(temp_directory) |
536 | + check_directory_exists(Path(temp_directory)) |
537 | temp_config = os.path.join(temp_directory, os.path.basename(import_file_name)) |
538 | shutil.copyfile(import_file_name, temp_config) |
539 | settings = Settings() |
540 | |
541 | === modified file 'openlp/core/ui/media/mediacontroller.py' |
542 | --- openlp/core/ui/media/mediacontroller.py 2017-06-25 17:03:31 +0000 |
543 | +++ openlp/core/ui/media/mediacontroller.py 2017-08-23 20:14:53 +0000 |
544 | @@ -177,7 +177,7 @@ |
545 | Check to see if we have any media Player's available. |
546 | """ |
547 | log.debug('_check_available_media_players') |
548 | - controller_dir = os.path.join('openlp', 'core', 'ui', 'media') |
549 | + controller_dir = os.path.join('core', 'ui', 'media') |
550 | glob_pattern = os.path.join(controller_dir, '*player.py') |
551 | extension_loader(glob_pattern, ['mediaplayer.py']) |
552 | player_classes = MediaPlayer.__subclasses__() |
553 | |
554 | === modified file 'openlp/core/ui/printserviceform.py' |
555 | --- openlp/core/ui/printserviceform.py 2017-08-01 20:59:41 +0000 |
556 | +++ openlp/core/ui/printserviceform.py 2017-08-23 20:14:53 +0000 |
557 | @@ -176,7 +176,7 @@ |
558 | html_data = self._add_element('html') |
559 | self._add_element('head', parent=html_data) |
560 | self._add_element('title', self.title_line_edit.text(), html_data.head) |
561 | - css_path = os.path.join(str(AppLocation.get_data_path()), 'serviceprint', 'service_print.css') |
562 | + css_path = AppLocation.get_data_path() / 'serviceprint' / 'service_print.css' |
563 | custom_css = get_text_file_string(css_path) |
564 | if not custom_css: |
565 | custom_css = DEFAULT_CSS |
566 | |
567 | === modified file 'openlp/core/ui/servicemanager.py' |
568 | --- openlp/core/ui/servicemanager.py 2017-08-03 17:54:40 +0000 |
569 | +++ openlp/core/ui/servicemanager.py 2017-08-23 20:14:53 +0000 |
570 | @@ -28,6 +28,7 @@ |
571 | import shutil |
572 | import zipfile |
573 | from datetime import datetime, timedelta |
574 | +from pathlib import Path |
575 | from tempfile import mkstemp |
576 | |
577 | from PyQt5 import QtCore, QtGui, QtWidgets |
578 | @@ -587,7 +588,7 @@ |
579 | audio_from = os.path.join(self.service_path, audio_from) |
580 | save_file = os.path.join(self.service_path, audio_to) |
581 | save_path = os.path.split(save_file)[0] |
582 | - check_directory_exists(save_path) |
583 | + check_directory_exists(Path(save_path)) |
584 | if not os.path.exists(save_file): |
585 | shutil.copy(audio_from, save_file) |
586 | zip_file.write(audio_from, audio_to) |
587 | @@ -614,7 +615,7 @@ |
588 | success = False |
589 | self.main_window.add_recent_file(path_file_name) |
590 | self.set_modified(False) |
591 | - delete_file(temp_file_name) |
592 | + delete_file(Path(temp_file_name)) |
593 | return success |
594 | |
595 | def save_local_file(self): |
596 | @@ -669,7 +670,7 @@ |
597 | return self.save_file_as() |
598 | self.main_window.add_recent_file(path_file_name) |
599 | self.set_modified(False) |
600 | - delete_file(temp_file_name) |
601 | + delete_file(Path(temp_file_name)) |
602 | return success |
603 | |
604 | def save_file_as(self, field=None): |
605 | @@ -774,7 +775,7 @@ |
606 | self.set_file_name(file_name) |
607 | self.main_window.display_progress_bar(len(items)) |
608 | self.process_service_items(items) |
609 | - delete_file(p_file) |
610 | + delete_file(Path(p_file)) |
611 | self.main_window.add_recent_file(file_name) |
612 | self.set_modified(False) |
613 | Settings().setValue('servicemanager/last file', file_name) |
614 | @@ -1343,7 +1344,7 @@ |
615 | Empties the service_path of temporary files on system exit. |
616 | """ |
617 | for file_name in os.listdir(self.service_path): |
618 | - file_path = os.path.join(self.service_path, file_name) |
619 | + file_path = Path(self.service_path, file_name) |
620 | delete_file(file_path) |
621 | if os.path.exists(os.path.join(self.service_path, 'audio')): |
622 | shutil.rmtree(os.path.join(self.service_path, 'audio'), True) |
623 | |
624 | === modified file 'openlp/core/ui/themeform.py' |
625 | --- openlp/core/ui/themeform.py 2017-08-07 20:50:01 +0000 |
626 | +++ openlp/core/ui/themeform.py 2017-08-23 20:14:53 +0000 |
627 | @@ -24,6 +24,7 @@ |
628 | """ |
629 | import logging |
630 | import os |
631 | +from pathlib import Path |
632 | |
633 | from PyQt5 import QtCore, QtGui, QtWidgets |
634 | |
635 | @@ -188,7 +189,8 @@ |
636 | """ |
637 | background_image = BackgroundType.to_string(BackgroundType.Image) |
638 | if self.page(self.currentId()) == self.background_page and \ |
639 | - self.theme.background_type == background_image and is_not_image_file(self.theme.background_filename): |
640 | + self.theme.background_type == background_image and \ |
641 | + is_not_image_file(Path(self.theme.background_filename)): |
642 | QtWidgets.QMessageBox.critical(self, translate('OpenLP.ThemeWizard', 'Background Image Empty'), |
643 | translate('OpenLP.ThemeWizard', 'You have not selected a ' |
644 | 'background image. Please select one before continuing.')) |
645 | |
646 | === modified file 'openlp/core/ui/thememanager.py' |
647 | --- openlp/core/ui/thememanager.py 2017-08-07 20:50:01 +0000 |
648 | +++ openlp/core/ui/thememanager.py 2017-08-23 20:14:53 +0000 |
649 | @@ -25,6 +25,7 @@ |
650 | import os |
651 | import zipfile |
652 | import shutil |
653 | +from pathlib import Path |
654 | |
655 | from xml.etree.ElementTree import ElementTree, XML |
656 | from PyQt5 import QtCore, QtGui, QtWidgets |
657 | @@ -161,9 +162,9 @@ |
658 | Set up the theme path variables |
659 | """ |
660 | self.path = str(AppLocation.get_section_data_path(self.settings_section)) |
661 | - check_directory_exists(self.path) |
662 | + check_directory_exists(Path(self.path)) |
663 | self.thumb_path = os.path.join(self.path, 'thumbnails') |
664 | - check_directory_exists(self.thumb_path) |
665 | + check_directory_exists(Path(self.thumb_path)) |
666 | |
667 | def check_list_state(self, item, field=None): |
668 | """ |
669 | @@ -355,8 +356,8 @@ |
670 | """ |
671 | self.theme_list.remove(theme) |
672 | thumb = '{name}.png'.format(name=theme) |
673 | - delete_file(os.path.join(self.path, thumb)) |
674 | - delete_file(os.path.join(self.thumb_path, thumb)) |
675 | + delete_file(Path(self.path, thumb)) |
676 | + delete_file(Path(self.thumb_path, thumb)) |
677 | try: |
678 | # Windows is always unicode, so no need to encode filenames |
679 | if is_win(): |
680 | @@ -450,7 +451,7 @@ |
681 | for theme_file in files: |
682 | theme_file = os.path.join(self.path, str(theme_file)) |
683 | self.unzip_theme(theme_file, self.path) |
684 | - delete_file(theme_file) |
685 | + delete_file(Path(theme_file)) |
686 | files = AppLocation.get_files(self.settings_section, '.png') |
687 | # No themes have been found so create one |
688 | if not files: |
689 | @@ -514,12 +515,12 @@ |
690 | :return: The theme object. |
691 | """ |
692 | self.log_debug('get theme data for theme {name}'.format(name=theme_name)) |
693 | - theme_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.json') |
694 | - theme_data = get_text_file_string(theme_file) |
695 | + theme_file_path = Path(self.path, str(theme_name), '{file_name}.json'.format(file_name=theme_name)) |
696 | + theme_data = get_text_file_string(theme_file_path) |
697 | jsn = True |
698 | if not theme_data: |
699 | - theme_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.xml') |
700 | - theme_data = get_text_file_string(theme_file) |
701 | + theme_file_path = theme_file_path.with_suffix('.xml') |
702 | + theme_data = get_text_file_string(theme_file_path) |
703 | jsn = False |
704 | if not theme_data: |
705 | self.log_debug('No theme data - using default theme') |
706 | @@ -592,7 +593,7 @@ |
707 | # is directory or preview file |
708 | continue |
709 | full_name = os.path.join(directory, out_name) |
710 | - check_directory_exists(os.path.dirname(full_name)) |
711 | + check_directory_exists(Path(os.path.dirname(full_name))) |
712 | if os.path.splitext(name)[1].lower() == '.xml' or os.path.splitext(name)[1].lower() == '.json': |
713 | file_xml = str(theme_zip.read(name), 'utf-8') |
714 | out_file = open(full_name, 'w', encoding='utf-8') |
715 | @@ -670,10 +671,10 @@ |
716 | name = theme.theme_name |
717 | theme_pretty = theme.export_theme() |
718 | theme_dir = os.path.join(self.path, name) |
719 | - check_directory_exists(theme_dir) |
720 | + check_directory_exists(Path(theme_dir)) |
721 | theme_file = os.path.join(theme_dir, name + '.json') |
722 | if self.old_background_image and image_to != self.old_background_image: |
723 | - delete_file(self.old_background_image) |
724 | + delete_file(Path(self.old_background_image)) |
725 | out_file = None |
726 | try: |
727 | out_file = open(theme_file, 'w', encoding='utf-8') |
728 | |
729 | === modified file 'openlp/plugins/bibles/lib/importers/csvbible.py' |
730 | --- openlp/plugins/bibles/lib/importers/csvbible.py 2016-12-31 11:01:36 +0000 |
731 | +++ openlp/plugins/bibles/lib/importers/csvbible.py 2017-08-23 20:14:53 +0000 |
732 | @@ -51,6 +51,7 @@ |
733 | """ |
734 | import csv |
735 | from collections import namedtuple |
736 | +from pathlib import Path |
737 | |
738 | from openlp.core.common import get_file_encoding, translate |
739 | from openlp.core.lib.exceptions import ValidationError |
740 | @@ -100,7 +101,7 @@ |
741 | :return: An iterable yielding namedtuples of type results_tuple |
742 | """ |
743 | try: |
744 | - encoding = get_file_encoding(filename)['encoding'] |
745 | + encoding = get_file_encoding(Path(filename))['encoding'] |
746 | with open(filename, 'r', encoding=encoding, newline='') as csv_file: |
747 | csv_reader = csv.reader(csv_file, delimiter=',', quotechar='"') |
748 | return [results_tuple(*line) for line in csv_reader] |
749 | |
750 | === modified file 'openlp/plugins/bibles/lib/manager.py' |
751 | --- openlp/plugins/bibles/lib/manager.py 2017-08-01 20:59:41 +0000 |
752 | +++ openlp/plugins/bibles/lib/manager.py 2017-08-23 20:14:53 +0000 |
753 | @@ -22,6 +22,7 @@ |
754 | |
755 | import logging |
756 | import os |
757 | +from pathlib import Path |
758 | |
759 | from openlp.core.common import AppLocation, OpenLPMixin, RegistryProperties, Settings, translate, delete_file, UiStrings |
760 | from openlp.plugins.bibles.lib import LanguageSelection, parse_reference |
761 | @@ -137,7 +138,7 @@ |
762 | # Remove corrupted files. |
763 | if name is None: |
764 | bible.session.close_all() |
765 | - delete_file(os.path.join(self.path, filename)) |
766 | + delete_file(Path(self.path, filename)) |
767 | continue |
768 | log.debug('Bible Name: "{name}"'.format(name=name)) |
769 | self.db_cache[name] = bible |
770 | @@ -185,7 +186,7 @@ |
771 | bible = self.db_cache[name] |
772 | bible.session.close_all() |
773 | bible.session = None |
774 | - return delete_file(os.path.join(bible.path, bible.file)) |
775 | + return delete_file(Path(bible.path, bible.file)) |
776 | |
777 | def get_bibles(self): |
778 | """ |
779 | |
780 | === modified file 'openlp/plugins/images/lib/mediaitem.py' |
781 | --- openlp/plugins/images/lib/mediaitem.py 2017-08-03 17:54:40 +0000 |
782 | +++ openlp/plugins/images/lib/mediaitem.py 2017-08-23 20:14:53 +0000 |
783 | @@ -22,6 +22,7 @@ |
784 | |
785 | import logging |
786 | import os |
787 | +from pathlib import Path |
788 | |
789 | from PyQt5 import QtCore, QtGui, QtWidgets |
790 | |
791 | @@ -99,7 +100,7 @@ |
792 | self.list_view.setIndentation(self.list_view.default_indentation) |
793 | self.list_view.allow_internal_dnd = True |
794 | self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails') |
795 | - check_directory_exists(self.service_path) |
796 | + check_directory_exists(Path(self.service_path)) |
797 | # Load images from the database |
798 | self.load_full_list( |
799 | self.manager.get_all_objects(ImageFilenames, order_by_ref=ImageFilenames.filename), initial_load=True) |
800 | @@ -210,8 +211,8 @@ |
801 | """ |
802 | images = self.manager.get_all_objects(ImageFilenames, ImageFilenames.group_id == image_group.id) |
803 | for image in images: |
804 | - delete_file(os.path.join(self.service_path, os.path.split(image.filename)[1])) |
805 | - delete_file(self.generate_thumbnail_path(image)) |
806 | + delete_file(Path(self.service_path, os.path.split(image.filename)[1])) |
807 | + delete_file(Path(self.generate_thumbnail_path(image))) |
808 | self.manager.delete_object(ImageFilenames, image.id) |
809 | image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == image_group.id) |
810 | for group in image_groups: |
811 | @@ -233,8 +234,8 @@ |
812 | if row_item: |
813 | item_data = row_item.data(0, QtCore.Qt.UserRole) |
814 | if isinstance(item_data, ImageFilenames): |
815 | - delete_file(os.path.join(self.service_path, row_item.text(0))) |
816 | - delete_file(self.generate_thumbnail_path(item_data)) |
817 | + delete_file(Path(self.service_path, row_item.text(0))) |
818 | + delete_file(Path(self.generate_thumbnail_path(item_data))) |
819 | if item_data.group_id == 0: |
820 | self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) |
821 | else: |
822 | |
823 | === modified file 'openlp/plugins/media/lib/mediaitem.py' |
824 | --- openlp/plugins/media/lib/mediaitem.py 2017-08-03 17:54:40 +0000 |
825 | +++ openlp/plugins/media/lib/mediaitem.py 2017-08-23 20:14:53 +0000 |
826 | @@ -22,6 +22,7 @@ |
827 | |
828 | import logging |
829 | import os |
830 | +from pathlib import Path |
831 | |
832 | from PyQt5 import QtCore, QtWidgets |
833 | |
834 | @@ -301,7 +302,7 @@ |
835 | """ |
836 | self.list_view.clear() |
837 | self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails') |
838 | - check_directory_exists(self.service_path) |
839 | + check_directory_exists(Path(self.service_path)) |
840 | self.load_list(Settings().value(self.settings_section + '/media files')) |
841 | self.rebuild_players() |
842 | |
843 | |
844 | === modified file 'openlp/plugins/media/mediaplugin.py' |
845 | --- openlp/plugins/media/mediaplugin.py 2017-08-03 17:54:40 +0000 |
846 | +++ openlp/plugins/media/mediaplugin.py 2017-08-23 20:14:53 +0000 |
847 | @@ -26,6 +26,7 @@ |
848 | import logging |
849 | import os |
850 | import re |
851 | +from pathlib import Path |
852 | |
853 | from PyQt5 import QtCore |
854 | |
855 | @@ -165,8 +166,7 @@ |
856 | :param program_path:The full path to the binary to check. |
857 | :return: If exists or not |
858 | """ |
859 | - program_type = None |
860 | - runlog = check_binary_exists(program_path) |
861 | + runlog = check_binary_exists(Path(program_path)) |
862 | # Analyse the output to see it the program is mediainfo |
863 | for line in runlog.splitlines(): |
864 | decoded_line = line.decode() |
865 | |
866 | === modified file 'openlp/plugins/presentations/lib/impresscontroller.py' |
867 | --- openlp/plugins/presentations/lib/impresscontroller.py 2017-05-14 10:11:10 +0000 |
868 | +++ openlp/plugins/presentations/lib/impresscontroller.py 2017-08-23 20:14:53 +0000 |
869 | @@ -34,6 +34,7 @@ |
870 | import logging |
871 | import os |
872 | import time |
873 | +from pathlib import Path |
874 | |
875 | from openlp.core.common import is_win, Registry, get_uno_command, get_uno_instance, delete_file |
876 | |
877 | @@ -275,7 +276,7 @@ |
878 | try: |
879 | doc.storeToURL(url_path, properties) |
880 | self.convert_thumbnail(path, index + 1) |
881 | - delete_file(path) |
882 | + delete_file(Path(path)) |
883 | except ErrorCodeIOException as exception: |
884 | log.exception('ERROR! ErrorCodeIOException {error:d}'.format(error=exception.ErrCode)) |
885 | except: |
886 | |
887 | === modified file 'openlp/plugins/presentations/lib/pdfcontroller.py' |
888 | --- openlp/plugins/presentations/lib/pdfcontroller.py 2017-08-01 20:59:41 +0000 |
889 | +++ openlp/plugins/presentations/lib/pdfcontroller.py 2017-08-23 20:14:53 +0000 |
890 | @@ -23,6 +23,7 @@ |
891 | import os |
892 | import logging |
893 | import re |
894 | +from pathlib import Path |
895 | from shutil import which |
896 | from subprocess import check_output, CalledProcessError |
897 | |
898 | @@ -69,7 +70,7 @@ |
899 | :return: Type of the binary, 'gs' if ghostscript, 'mudraw' if mudraw, None if invalid. |
900 | """ |
901 | program_type = None |
902 | - runlog = check_binary_exists(program_path) |
903 | + runlog = check_binary_exists(Path(program_path)) |
904 | # Analyse the output to see it the program is mudraw, ghostscript or neither |
905 | for line in runlog.splitlines(): |
906 | decoded_line = line.decode() |
907 | |
908 | === modified file 'openlp/plugins/presentations/lib/presentationcontroller.py' |
909 | --- openlp/plugins/presentations/lib/presentationcontroller.py 2017-08-01 20:59:41 +0000 |
910 | +++ openlp/plugins/presentations/lib/presentationcontroller.py 2017-08-23 20:14:53 +0000 |
911 | @@ -23,6 +23,7 @@ |
912 | import logging |
913 | import os |
914 | import shutil |
915 | +from pathlib import Path |
916 | |
917 | from PyQt5 import QtCore |
918 | |
919 | @@ -98,7 +99,7 @@ |
920 | """ |
921 | self.slide_number = 0 |
922 | self.file_path = name |
923 | - check_directory_exists(self.get_thumbnail_folder()) |
924 | + check_directory_exists(Path(self.get_thumbnail_folder())) |
925 | |
926 | def load_presentation(self): |
927 | """ |
928 | @@ -419,8 +420,8 @@ |
929 | self.thumbnail_folder = os.path.join( |
930 | str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails') |
931 | self.thumbnail_prefix = 'slide' |
932 | - check_directory_exists(self.thumbnail_folder) |
933 | - check_directory_exists(self.temp_folder) |
934 | + check_directory_exists(Path(self.thumbnail_folder)) |
935 | + check_directory_exists(Path(self.temp_folder)) |
936 | |
937 | def enabled(self): |
938 | """ |
939 | |
940 | === modified file 'openlp/plugins/presentations/presentationplugin.py' |
941 | --- openlp/plugins/presentations/presentationplugin.py 2017-06-09 15:56:40 +0000 |
942 | +++ openlp/plugins/presentations/presentationplugin.py 2017-08-23 20:14:53 +0000 |
943 | @@ -125,7 +125,7 @@ |
944 | Check to see if we have any presentation software available. If not do not install the plugin. |
945 | """ |
946 | log.debug('check_pre_conditions') |
947 | - controller_dir = os.path.join('openlp', 'plugins', 'presentations', 'lib') |
948 | + controller_dir = os.path.join('plugins', 'presentations', 'lib') |
949 | glob_pattern = os.path.join(controller_dir, '*controller.py') |
950 | extension_loader(glob_pattern, ['presentationcontroller.py']) |
951 | controller_classes = PresentationController.__subclasses__() |
952 | |
953 | === modified file 'openlp/plugins/songs/forms/editsongform.py' |
954 | --- openlp/plugins/songs/forms/editsongform.py 2017-08-11 20:47:52 +0000 |
955 | +++ openlp/plugins/songs/forms/editsongform.py 2017-08-23 20:14:53 +0000 |
956 | @@ -1071,7 +1071,7 @@ |
957 | log.debug(audio_files) |
958 | save_path = os.path.join(str(AppLocation.get_section_data_path(self.media_item.plugin.name)), 'audio', |
959 | str(self.song.id)) |
960 | - check_directory_exists(save_path) |
961 | + check_directory_exists(Path(save_path)) |
962 | self.song.media_files = [] |
963 | files = [] |
964 | for row in range(self.audio_list_widget.count()): |
965 | |
966 | === modified file 'openlp/plugins/songs/lib/importers/songbeamer.py' |
967 | --- openlp/plugins/songs/lib/importers/songbeamer.py 2017-05-11 19:53:47 +0000 |
968 | +++ openlp/plugins/songs/lib/importers/songbeamer.py 2017-08-23 20:14:53 +0000 |
969 | @@ -27,6 +27,7 @@ |
970 | import re |
971 | import base64 |
972 | import math |
973 | +from pathlib import Path |
974 | |
975 | from openlp.plugins.songs.lib import VerseType |
976 | from openlp.plugins.songs.lib.importers.songimport import SongImport |
977 | @@ -122,7 +123,7 @@ |
978 | file_name = os.path.split(import_file)[1] |
979 | if os.path.isfile(import_file): |
980 | # Detect the encoding |
981 | - self.input_file_encoding = get_file_encoding(import_file)['encoding'] |
982 | + self.input_file_encoding = get_file_encoding(Path(import_file))['encoding'] |
983 | # The encoding should only be ANSI (cp1252), UTF-8, Unicode, Big-Endian-Unicode. |
984 | # So if it doesn't start with 'u' we default to cp1252. See: |
985 | # https://forum.songbeamer.com/viewtopic.php?p=419&sid=ca4814924e37c11e4438b7272a98b6f2 |
986 | |
987 | === modified file 'openlp/plugins/songs/lib/importers/songimport.py' |
988 | --- openlp/plugins/songs/lib/importers/songimport.py 2017-08-01 20:59:41 +0000 |
989 | +++ openlp/plugins/songs/lib/importers/songimport.py 2017-08-23 20:14:53 +0000 |
990 | @@ -24,6 +24,7 @@ |
991 | import re |
992 | import shutil |
993 | import os |
994 | +from pathlib import Path |
995 | |
996 | from PyQt5 import QtCore |
997 | |
998 | @@ -423,7 +424,7 @@ |
999 | if not hasattr(self, 'save_path'): |
1000 | self.save_path = os.path.join(str(AppLocation.get_section_data_path(self.import_wizard.plugin.name)), |
1001 | 'audio', str(song_id)) |
1002 | - check_directory_exists(self.save_path) |
1003 | + check_directory_exists(Path(self.save_path)) |
1004 | if not filename.startswith(self.save_path): |
1005 | old_file, filename = filename, os.path.join(self.save_path, os.path.split(filename)[1]) |
1006 | shutil.copyfile(old_file, filename) |
1007 | |
1008 | === modified file 'openlp/plugins/songs/lib/mediaitem.py' |
1009 | --- openlp/plugins/songs/lib/mediaitem.py 2017-08-03 17:54:40 +0000 |
1010 | +++ openlp/plugins/songs/lib/mediaitem.py 2017-08-23 20:14:53 +0000 |
1011 | @@ -23,6 +23,7 @@ |
1012 | import logging |
1013 | import os |
1014 | import shutil |
1015 | +from pathlib import Path |
1016 | |
1017 | from PyQt5 import QtCore, QtWidgets |
1018 | from sqlalchemy.sql import and_, or_ |
1019 | @@ -89,7 +90,7 @@ |
1020 | for i, bga in enumerate(item.background_audio): |
1021 | dest_file = os.path.join( |
1022 | str(AppLocation.get_section_data_path(self.plugin.name)), 'audio', str(song.id), os.path.split(bga)[1]) |
1023 | - check_directory_exists(os.path.split(dest_file)[0]) |
1024 | + check_directory_exists(Path(os.path.split(dest_file)[0])) |
1025 | shutil.copyfile(os.path.join(str(AppLocation.get_section_data_path('servicemanager')), bga), dest_file) |
1026 | song.media_files.append(MediaFile.populate(weight=i, file_name=dest_file)) |
1027 | self.plugin.manager.save_object(song, True) |
1028 | @@ -535,7 +536,7 @@ |
1029 | if len(old_song.media_files) > 0: |
1030 | save_path = os.path.join( |
1031 | str(AppLocation.get_section_data_path(self.plugin.name)), 'audio', str(new_song.id)) |
1032 | - check_directory_exists(save_path) |
1033 | + check_directory_exists(Path(save_path)) |
1034 | for media_file in old_song.media_files: |
1035 | new_media_file_name = os.path.join(save_path, os.path.basename(media_file.file_name)) |
1036 | shutil.copyfile(media_file.file_name, new_media_file_name) |
1037 | |
1038 | === modified file 'openlp/plugins/songs/lib/openlyricsexport.py' |
1039 | --- openlp/plugins/songs/lib/openlyricsexport.py 2016-12-31 11:01:36 +0000 |
1040 | +++ openlp/plugins/songs/lib/openlyricsexport.py 2017-08-23 20:14:53 +0000 |
1041 | @@ -25,6 +25,7 @@ |
1042 | """ |
1043 | import logging |
1044 | import os |
1045 | +from pathlib import Path |
1046 | |
1047 | from lxml import etree |
1048 | |
1049 | @@ -47,7 +48,7 @@ |
1050 | self.manager = parent.plugin.manager |
1051 | self.songs = songs |
1052 | self.save_path = save_path |
1053 | - check_directory_exists(self.save_path) |
1054 | + check_directory_exists(Path(self.save_path)) |
1055 | |
1056 | def do_export(self): |
1057 | """ |
1058 | |
1059 | === modified file 'openlp/plugins/songusage/forms/songusagedetailform.py' |
1060 | --- openlp/plugins/songusage/forms/songusagedetailform.py 2017-08-04 17:40:57 +0000 |
1061 | +++ openlp/plugins/songusage/forms/songusagedetailform.py 2017-08-23 20:14:53 +0000 |
1062 | @@ -22,6 +22,7 @@ |
1063 | |
1064 | import logging |
1065 | import os |
1066 | +from pathlib import Path |
1067 | |
1068 | from PyQt5 import QtCore, QtWidgets |
1069 | from sqlalchemy.sql import and_ |
1070 | @@ -78,7 +79,7 @@ |
1071 | ' song usage report. \nPlease select an existing path on your computer.') |
1072 | ) |
1073 | return |
1074 | - check_directory_exists(path) |
1075 | + check_directory_exists(Path(path)) |
1076 | file_name = translate('SongUsagePlugin.SongUsageDetailForm', |
1077 | 'usage_detail_{old}_{new}.txt' |
1078 | ).format(old=self.from_date_calendar.selectedDate().toString('ddMMyyyy'), |
1079 | |
1080 | === modified file 'tests/functional/openlp_core_common/test_applocation.py' |
1081 | --- tests/functional/openlp_core_common/test_applocation.py 2017-08-01 20:59:41 +0000 |
1082 | +++ tests/functional/openlp_core_common/test_applocation.py 2017-08-23 20:14:53 +0000 |
1083 | @@ -43,14 +43,12 @@ |
1084 | """ |
1085 | with patch('openlp.core.common.applocation.Settings') as mocked_class, \ |
1086 | patch('openlp.core.common.AppLocation.get_directory') as mocked_get_directory, \ |
1087 | - patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists, \ |
1088 | - patch('openlp.core.common.applocation.os') as mocked_os: |
1089 | + patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists: |
1090 | # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory() |
1091 | mocked_settings = mocked_class.return_value |
1092 | mocked_settings.contains.return_value = False |
1093 | - mocked_get_directory.return_value = os.path.join('test', 'dir') |
1094 | + mocked_get_directory.return_value = Path('test', 'dir') |
1095 | mocked_check_directory_exists.return_value = True |
1096 | - mocked_os.path.normpath.return_value = os.path.join('test', 'dir') |
1097 | |
1098 | # WHEN: we call AppLocation.get_data_path() |
1099 | data_path = AppLocation.get_data_path() |
1100 | @@ -58,8 +56,8 @@ |
1101 | # THEN: check that all the correct methods were called, and the result is correct |
1102 | mocked_settings.contains.assert_called_with('advanced/data path') |
1103 | mocked_get_directory.assert_called_with(AppLocation.DataDir) |
1104 | - mocked_check_directory_exists.assert_called_with(os.path.join('test', 'dir')) |
1105 | - self.assertEqual(os.path.join('test', 'dir'), data_path, 'Result should be "test/dir"') |
1106 | + mocked_check_directory_exists.assert_called_with(Path('test', 'dir')) |
1107 | + self.assertEqual(Path('test', 'dir'), data_path, 'Result should be "test/dir"') |
1108 | |
1109 | def test_get_data_path_with_custom_location(self): |
1110 | """ |
1111 | @@ -125,7 +123,7 @@ |
1112 | data_path = AppLocation.get_section_data_path('section') |
1113 | |
1114 | # THEN: check that all the correct methods were called, and the result is correct |
1115 | - mocked_check_directory_exists.assert_called_with(os.path.join('test', 'dir', 'section')) |
1116 | + mocked_check_directory_exists.assert_called_with(Path('test', 'dir', 'section')) |
1117 | self.assertEqual(Path('test', 'dir', 'section'), data_path, 'Result should be "test/dir/section"') |
1118 | |
1119 | def test_get_directory_for_app_dir(self): |
1120 | |
1121 | === modified file 'tests/functional/openlp_core_common/test_common.py' |
1122 | --- tests/functional/openlp_core_common/test_common.py 2017-08-01 20:59:41 +0000 |
1123 | +++ tests/functional/openlp_core_common/test_common.py 2017-08-23 20:14:53 +0000 |
1124 | @@ -35,44 +35,70 @@ |
1125 | """ |
1126 | A test suite to test out various functions in the openlp.core.common module. |
1127 | """ |
1128 | - def test_check_directory_exists(self): |
1129 | - """ |
1130 | - Test the check_directory_exists() function |
1131 | - """ |
1132 | - with patch('openlp.core.lib.os.path.exists') as mocked_exists, \ |
1133 | - patch('openlp.core.lib.os.makedirs') as mocked_makedirs: |
1134 | - # GIVEN: A directory to check and a mocked out os.makedirs and os.path.exists |
1135 | - directory_to_check = 'existing/directory' |
1136 | + def test_check_directory_exists_dir_exists(self): |
1137 | + """ |
1138 | + Test the check_directory_exists() function when the path already exists |
1139 | + """ |
1140 | + # GIVEN: A `Path` to check with patched out mkdir and exists methods |
1141 | + with patch.object(Path, 'exists') as mocked_exists, \ |
1142 | + patch.object(Path, 'mkdir') as mocked_mkdir, \ |
1143 | + patch('openlp.core.common.log'): |
1144 | |
1145 | - # WHEN: os.path.exists returns True and we check to see if the directory exists |
1146 | + # WHEN: `check_directory_exists` is called and the path exists |
1147 | mocked_exists.return_value = True |
1148 | - check_directory_exists(directory_to_check) |
1149 | - |
1150 | - # THEN: Only os.path.exists should have been called |
1151 | - mocked_exists.assert_called_with(directory_to_check) |
1152 | - self.assertIsNot(mocked_makedirs.called, 'os.makedirs should not have been called') |
1153 | - |
1154 | - # WHEN: os.path.exists returns False and we check the directory exists |
1155 | + check_directory_exists(Path('existing', 'directory')) |
1156 | + |
1157 | + # THEN: The function should not attempt to create the directory |
1158 | + mocked_exists.assert_called_with() |
1159 | + self.assertFalse(mocked_mkdir.called) |
1160 | + |
1161 | + def test_check_directory_exists_dir_doesnt_exists(self): |
1162 | + """ |
1163 | + Test the check_directory_exists() function when the path does not already exist |
1164 | + """ |
1165 | + # GIVEN: A `Path` to check with patched out mkdir and exists methods |
1166 | + with patch.object(Path, 'exists') as mocked_exists, \ |
1167 | + patch.object(Path, 'mkdir') as mocked_mkdir, \ |
1168 | + patch('openlp.core.common.log'): |
1169 | + |
1170 | + # WHEN: `check_directory_exists` is called and the path does not exist |
1171 | mocked_exists.return_value = False |
1172 | - check_directory_exists(directory_to_check) |
1173 | - |
1174 | - # THEN: Both the mocked functions should have been called |
1175 | - mocked_exists.assert_called_with(directory_to_check) |
1176 | - mocked_makedirs.assert_called_with(directory_to_check) |
1177 | - |
1178 | - # WHEN: os.path.exists raises an IOError |
1179 | + check_directory_exists(Path('existing', 'directory')) |
1180 | + |
1181 | + # THEN: The directory should have been created |
1182 | + mocked_exists.assert_called_with() |
1183 | + mocked_mkdir.assert_called_with(parents=True) |
1184 | + |
1185 | + def test_check_directory_exists_dir_io_error(self): |
1186 | + """ |
1187 | + Test the check_directory_exists() when an IOError is raised |
1188 | + """ |
1189 | + # GIVEN: A `Path` to check with patched out mkdir and exists methods |
1190 | + with patch.object(Path, 'exists') as mocked_exists, \ |
1191 | + patch.object(Path, 'mkdir'), \ |
1192 | + patch('openlp.core.common.log') as mocked_logger: |
1193 | + |
1194 | + # WHEN: An IOError is raised when checking the if the path exists. |
1195 | mocked_exists.side_effect = IOError() |
1196 | - check_directory_exists(directory_to_check) |
1197 | - |
1198 | - # THEN: We shouldn't get an exception though the mocked exists has been called |
1199 | - mocked_exists.assert_called_with(directory_to_check) |
1200 | + check_directory_exists(Path('existing', 'directory')) |
1201 | + |
1202 | + # THEN: The Error should have been logged |
1203 | + mocked_logger.exception.assert_called_once_with('failed to check if directory exists or create directory') |
1204 | + |
1205 | + def test_check_directory_exists_dir_value_error(self): |
1206 | + """ |
1207 | + Test the check_directory_exists() when an error other than IOError is raised |
1208 | + """ |
1209 | + # GIVEN: A `Path` to check with patched out mkdir and exists methods |
1210 | + with patch.object(Path, 'exists') as mocked_exists, \ |
1211 | + patch.object(Path, 'mkdir'), \ |
1212 | + patch('openlp.core.common.log'): |
1213 | |
1214 | # WHEN: Some other exception is raised |
1215 | mocked_exists.side_effect = ValueError() |
1216 | |
1217 | - # THEN: check_directory_exists raises an exception |
1218 | - mocked_exists.assert_called_with(directory_to_check) |
1219 | - self.assertRaises(ValueError, check_directory_exists, directory_to_check) |
1220 | + # THEN: `check_directory_exists` raises an exception |
1221 | + self.assertRaises(ValueError, check_directory_exists, Path('existing', 'directory')) |
1222 | |
1223 | def test_extension_loader_no_files_found(self): |
1224 | """ |
1225 | @@ -80,7 +106,7 @@ |
1226 | """ |
1227 | # GIVEN: A mocked `Path.glob` method which does not match any files |
1228 | with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \ |
1229 | - patch.object(common.Path, 'glob', return_value=[]), \ |
1230 | + patch.object(Path, 'glob', return_value=[]), \ |
1231 | patch('openlp.core.common.importlib.import_module') as mocked_import_module: |
1232 | |
1233 | # WHEN: Calling `extension_loader` |
1234 | @@ -95,7 +121,7 @@ |
1235 | """ |
1236 | # GIVEN: A mocked `Path.glob` method which returns a list of files |
1237 | with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \ |
1238 | - patch.object(common.Path, 'glob', return_value=[ |
1239 | + patch.object(Path, 'glob', return_value=[ |
1240 | Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py'), |
1241 | Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file2.py'), |
1242 | Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file3.py'), |
1243 | @@ -115,7 +141,7 @@ |
1244 | """ |
1245 | # GIVEN: A mocked `import_module` which raises an `ImportError` |
1246 | with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \ |
1247 | - patch.object(common.Path, 'glob', return_value=[ |
1248 | + patch.object(Path, 'glob', return_value=[ |
1249 | Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \ |
1250 | patch('openlp.core.common.importlib.import_module', side_effect=ImportError()), \ |
1251 | patch('openlp.core.common.log') as mocked_logger: |
1252 | @@ -132,7 +158,7 @@ |
1253 | """ |
1254 | # GIVEN: A mocked `SourceFileLoader` which raises an `OSError` |
1255 | with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \ |
1256 | - patch.object(common.Path, 'glob', return_value=[ |
1257 | + patch.object(Path, 'glob', return_value=[ |
1258 | Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \ |
1259 | patch('openlp.core.common.importlib.import_module', side_effect=OSError()), \ |
1260 | patch('openlp.core.common.log') as mocked_logger: |
1261 | @@ -174,7 +200,7 @@ |
1262 | Test `path_to_module` when supplied with a `Path` object |
1263 | """ |
1264 | # GIVEN: A `Path` object |
1265 | - path = Path('openlp/core/ui/media/webkitplayer.py') |
1266 | + path = Path('core', 'ui', 'media', 'webkitplayer.py') |
1267 | |
1268 | # WHEN: Calling path_to_module with the `Path` object |
1269 | result = path_to_module(path) |
1270 | |
1271 | === modified file 'tests/functional/openlp_core_common/test_init.py' |
1272 | --- tests/functional/openlp_core_common/test_init.py 2017-04-24 05:17:55 +0000 |
1273 | +++ tests/functional/openlp_core_common/test_init.py 2017-08-23 20:14:53 +0000 |
1274 | @@ -24,6 +24,7 @@ |
1275 | """ |
1276 | import os |
1277 | from io import BytesIO |
1278 | +from pathlib import Path |
1279 | from unittest import TestCase |
1280 | from unittest.mock import MagicMock, PropertyMock, call, patch |
1281 | |
1282 | @@ -296,10 +297,10 @@ |
1283 | """ |
1284 | # GIVEN: A blank path |
1285 | # WEHN: Calling delete_file |
1286 | - result = delete_file('') |
1287 | + result = delete_file(None) |
1288 | |
1289 | # THEN: delete_file should return False |
1290 | - self.assertFalse(result, "delete_file should return False when called with ''") |
1291 | + self.assertFalse(result, "delete_file should return False when called with None") |
1292 | |
1293 | def test_delete_file_path_success(self): |
1294 | """ |
1295 | @@ -309,84 +310,87 @@ |
1296 | with patch('openlp.core.common.os', **{'path.exists.return_value': False}): |
1297 | |
1298 | # WHEN: Calling delete_file with a file path |
1299 | - result = delete_file('path/file.ext') |
1300 | + result = delete_file(Path('path', 'file.ext')) |
1301 | |
1302 | # THEN: delete_file should return True |
1303 | self.assertTrue(result, 'delete_file should return True when it successfully deletes a file') |
1304 | |
1305 | def test_delete_file_path_no_file_exists(self): |
1306 | """ |
1307 | - Test the delete_file function when the file to remove does not exist |
1308 | + Test the `delete_file` function when the file to remove does not exist |
1309 | """ |
1310 | - # GIVEN: A mocked os which returns False when os.path.exists is called |
1311 | - with patch('openlp.core.common.os', **{'path.exists.return_value': False}): |
1312 | - |
1313 | - # WHEN: Calling delete_file with a file path |
1314 | - result = delete_file('path/file.ext') |
1315 | - |
1316 | - # THEN: delete_file should return True |
1317 | + # GIVEN: A patched `exists` methods on the Path object, which returns False |
1318 | + with patch.object(Path, 'exists', return_value=False), \ |
1319 | + patch.object(Path, 'unlink') as mocked_unlink: |
1320 | + |
1321 | + # WHEN: Calling `delete_file with` a file path |
1322 | + result = delete_file(Path('path', 'file.ext')) |
1323 | + |
1324 | + # THEN: The function should not attempt to delete the file and it should return True |
1325 | + self.assertFalse(mocked_unlink.called) |
1326 | self.assertTrue(result, 'delete_file should return True when the file doesnt exist') |
1327 | |
1328 | def test_delete_file_path_exception(self): |
1329 | """ |
1330 | - Test the delete_file function when os.remove raises an exception |
1331 | + Test the delete_file function when an exception is raised |
1332 | """ |
1333 | - # GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is |
1334 | + # GIVEN: A test `Path` object with a patched exists method which raises an OSError |
1335 | # called. |
1336 | - with patch('openlp.core.common.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \ |
1337 | + with patch.object(Path, 'exists') as mocked_exists, \ |
1338 | patch('openlp.core.common.log') as mocked_log: |
1339 | - |
1340 | - # WHEN: Calling delete_file with a file path |
1341 | - result = delete_file('path/file.ext') |
1342 | - |
1343 | - # THEN: delete_file should log and exception and return False |
1344 | - self.assertEqual(mocked_log.exception.call_count, 1) |
1345 | - self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError') |
1346 | - |
1347 | - def test_get_file_name_encoding_done_test(self): |
1348 | + mocked_exists.side_effect = OSError |
1349 | + |
1350 | + # WHEN: Calling delete_file with a the test Path object |
1351 | + result = delete_file(Path('path', 'file.ext')) |
1352 | + |
1353 | + # THEN: The exception should be logged and `delete_file` should return False |
1354 | + self.assertTrue(mocked_log.exception.called) |
1355 | + self.assertFalse(result, 'delete_file should return False when an OSError is raised') |
1356 | + |
1357 | + def test_get_file_encoding_done_test(self): |
1358 | """ |
1359 | Test get_file_encoding when the detector sets done to True |
1360 | """ |
1361 | # GIVEN: A mocked UniversalDetector instance with done attribute set to True after first iteration |
1362 | with patch('openlp.core.common.UniversalDetector') as mocked_universal_detector, \ |
1363 | - patch('builtins.open', return_value=BytesIO(b"data" * 260)) as mocked_open: |
1364 | + patch.object(Path, 'open', return_value=BytesIO(b"data" * 260)) as mocked_open: |
1365 | encoding_result = {'encoding': 'UTF-8', 'confidence': 0.99} |
1366 | mocked_universal_detector_inst = MagicMock(result=encoding_result) |
1367 | type(mocked_universal_detector_inst).done = PropertyMock(side_effect=[False, True]) |
1368 | mocked_universal_detector.return_value = mocked_universal_detector_inst |
1369 | |
1370 | # WHEN: Calling get_file_encoding |
1371 | - result = get_file_encoding('file name') |
1372 | + result = get_file_encoding(Path('file name')) |
1373 | |
1374 | # THEN: The feed method of UniversalDetector should only br called once before returning a result |
1375 | - mocked_open.assert_called_once_with('file name', 'rb') |
1376 | + mocked_open.assert_called_once_with('rb') |
1377 | self.assertEqual(mocked_universal_detector_inst.feed.mock_calls, [call(b"data" * 256)]) |
1378 | mocked_universal_detector_inst.close.assert_called_once_with() |
1379 | self.assertEqual(result, encoding_result) |
1380 | |
1381 | - def test_get_file_name_encoding_eof_test(self): |
1382 | + def test_get_file_encoding_eof_test(self): |
1383 | """ |
1384 | Test get_file_encoding when the end of the file is reached |
1385 | """ |
1386 | # GIVEN: A mocked UniversalDetector instance which isn't set to done and a mocked open, with 1040 bytes of test |
1387 | # data (enough to run the iterator twice) |
1388 | with patch('openlp.core.common.UniversalDetector') as mocked_universal_detector, \ |
1389 | - patch('builtins.open', return_value=BytesIO(b"data" * 260)) as mocked_open: |
1390 | + patch.object(Path, 'open', return_value=BytesIO(b"data" * 260)) as mocked_open: |
1391 | encoding_result = {'encoding': 'UTF-8', 'confidence': 0.99} |
1392 | mocked_universal_detector_inst = MagicMock(mock=mocked_universal_detector, |
1393 | **{'done': False, 'result': encoding_result}) |
1394 | mocked_universal_detector.return_value = mocked_universal_detector_inst |
1395 | |
1396 | # WHEN: Calling get_file_encoding |
1397 | - result = get_file_encoding('file name') |
1398 | + result = get_file_encoding(Path('file name')) |
1399 | |
1400 | # THEN: The feed method of UniversalDetector should have been called twice before returning a result |
1401 | - mocked_open.assert_called_once_with('file name', 'rb') |
1402 | + mocked_open.assert_called_once_with('rb') |
1403 | self.assertEqual(mocked_universal_detector_inst.feed.mock_calls, [call(b"data" * 256), call(b"data" * 4)]) |
1404 | mocked_universal_detector_inst.close.assert_called_once_with() |
1405 | self.assertEqual(result, encoding_result) |
1406 | |
1407 | - def test_get_file_name_encoding_oserror_test(self): |
1408 | + def test_get_file_encoding_oserror_test(self): |
1409 | """ |
1410 | Test get_file_encoding when the end of the file is reached |
1411 | """ |
1412 | @@ -397,7 +401,7 @@ |
1413 | patch('openlp.core.common.log') as mocked_log: |
1414 | |
1415 | # WHEN: Calling get_file_encoding |
1416 | - result = get_file_encoding('file name') |
1417 | + result = get_file_encoding(Path('file name')) |
1418 | |
1419 | # THEN: log.exception should be called and get_file_encoding should return None |
1420 | mocked_log.exception.assert_called_once_with('Error detecting file encoding') |
1421 | |
1422 | === modified file 'tests/functional/openlp_core_lib/test_db.py' |
1423 | --- tests/functional/openlp_core_lib/test_db.py 2017-06-09 13:45:18 +0000 |
1424 | +++ tests/functional/openlp_core_lib/test_db.py 2017-08-23 20:14:53 +0000 |
1425 | @@ -24,6 +24,7 @@ |
1426 | """ |
1427 | import os |
1428 | import shutil |
1429 | +from pathlib import Path |
1430 | |
1431 | from tempfile import mkdtemp |
1432 | from unittest import TestCase |
1433 | @@ -129,10 +130,10 @@ |
1434 | # GIVEN: Mocked out AppLocation class and delete_file method, a test plugin name and a db location |
1435 | with patch('openlp.core.lib.db.AppLocation') as MockedAppLocation, \ |
1436 | patch('openlp.core.lib.db.delete_file') as mocked_delete_file: |
1437 | - MockedAppLocation.get_section_data_path.return_value = 'test-dir' |
1438 | + MockedAppLocation.get_section_data_path.return_value = Path('test-dir') |
1439 | mocked_delete_file.return_value = True |
1440 | test_plugin = 'test' |
1441 | - test_location = os.path.join('test-dir', test_plugin) |
1442 | + test_location = Path('test-dir', test_plugin) |
1443 | |
1444 | # WHEN: delete_database is run without a database file |
1445 | result = delete_database(test_plugin) |
1446 | @@ -149,11 +150,11 @@ |
1447 | # GIVEN: Mocked out AppLocation class and delete_file method, a test plugin name and a db location |
1448 | with patch('openlp.core.lib.db.AppLocation') as MockedAppLocation, \ |
1449 | patch('openlp.core.lib.db.delete_file') as mocked_delete_file: |
1450 | - MockedAppLocation.get_section_data_path.return_value = 'test-dir' |
1451 | + MockedAppLocation.get_section_data_path.return_value = Path('test-dir') |
1452 | mocked_delete_file.return_value = False |
1453 | test_plugin = 'test' |
1454 | test_db_file = 'mydb.sqlite' |
1455 | - test_location = os.path.join('test-dir', test_db_file) |
1456 | + test_location = Path('test-dir', test_db_file) |
1457 | |
1458 | # WHEN: delete_database is run without a database file |
1459 | result = delete_database(test_plugin, test_db_file) |
1460 | |
1461 | === removed file 'tests/functional/openlp_core_lib/test_file_dialog.py' |
1462 | --- tests/functional/openlp_core_lib/test_file_dialog.py 2017-08-07 21:12:42 +0000 |
1463 | +++ tests/functional/openlp_core_lib/test_file_dialog.py 1970-01-01 00:00:00 +0000 |
1464 | @@ -1,45 +0,0 @@ |
1465 | -# -*- coding: utf-8 -*- |
1466 | -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 |
1467 | - |
1468 | -############################################################################### |
1469 | -# OpenLP - Open Source Lyrics Projection # |
1470 | -# --------------------------------------------------------------------------- # |
1471 | -# Copyright (c) 2008-2017 OpenLP Developers # |
1472 | -# --------------------------------------------------------------------------- # |
1473 | -# This program is free software; you can redistribute it and/or modify it # |
1474 | -# under the terms of the GNU General Public License as published by the Free # |
1475 | -# Software Foundation; version 2 of the License. # |
1476 | -# # |
1477 | -# This program is distributed in the hope that it will be useful, but WITHOUT # |
1478 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # |
1479 | -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # |
1480 | -# more details. # |
1481 | -# # |
1482 | -# You should have received a copy of the GNU General Public License along # |
1483 | -# with this program; if not, write to the Free Software Foundation, Inc., 59 # |
1484 | -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # |
1485 | -############################################################################### |
1486 | -""" |
1487 | -Package to test the openlp.core.ui.lib.filedialog package. |
1488 | -""" |
1489 | -from unittest import TestCase |
1490 | -from unittest.mock import MagicMock, patch |
1491 | - |
1492 | - |
1493 | -class TestFileDialog(TestCase): |
1494 | - """ |
1495 | - Test the functions in the :mod:`filedialog` module. |
1496 | - """ |
1497 | - def setUp(self): |
1498 | - self.os_patcher = patch('openlp.core.ui.lib.filedialog.os') |
1499 | - self.qt_gui_patcher = patch('openlp.core.ui.lib.filedialog.QtWidgets') |
1500 | - self.ui_strings_patcher = patch('openlp.core.ui.lib.filedialog.UiStrings') |
1501 | - self.mocked_os = self.os_patcher.start() |
1502 | - self.mocked_qt_gui = self.qt_gui_patcher.start() |
1503 | - self.mocked_ui_strings = self.ui_strings_patcher.start() |
1504 | - self.mocked_parent = MagicMock() |
1505 | - |
1506 | - def tearDown(self): |
1507 | - self.os_patcher.stop() |
1508 | - self.qt_gui_patcher.stop() |
1509 | - self.ui_strings_patcher.stop() |
1510 | |
1511 | === modified file 'tests/functional/openlp_core_lib/test_lib.py' |
1512 | --- tests/functional/openlp_core_lib/test_lib.py 2017-08-04 17:40:57 +0000 |
1513 | +++ tests/functional/openlp_core_lib/test_lib.py 2017-08-23 20:14:53 +0000 |
1514 | @@ -24,6 +24,7 @@ |
1515 | """ |
1516 | import os |
1517 | from datetime import datetime, timedelta |
1518 | +from pathlib import Path |
1519 | from unittest import TestCase |
1520 | from unittest.mock import MagicMock, patch |
1521 | |
1522 | @@ -148,35 +149,34 @@ |
1523 | """ |
1524 | Test the get_text_file_string() function when a file does not exist |
1525 | """ |
1526 | - with patch('openlp.core.lib.os.path.isfile') as mocked_isfile: |
1527 | - # GIVEN: A mocked out isfile which returns true, and a text file name |
1528 | - filename = 'testfile.txt' |
1529 | - mocked_isfile.return_value = False |
1530 | + # GIVEN: A patched is_file which returns False, and a file path |
1531 | + with patch.object(Path, 'is_file', return_value=False): |
1532 | + file_path = Path('testfile.txt') |
1533 | |
1534 | # WHEN: get_text_file_string is called |
1535 | - result = get_text_file_string(filename) |
1536 | + result = get_text_file_string(file_path) |
1537 | |
1538 | # THEN: The result should be False |
1539 | - mocked_isfile.assert_called_with(filename) |
1540 | + file_path.is_file.assert_called_with() |
1541 | self.assertFalse(result, 'False should be returned if no file exists') |
1542 | |
1543 | def test_get_text_file_string_read_error(self): |
1544 | """ |
1545 | Test the get_text_file_string() method when a read error happens |
1546 | """ |
1547 | - with patch('openlp.core.lib.os.path.isfile') as mocked_isfile, \ |
1548 | - patch('openlp.core.lib.open', create=True) as mocked_open: |
1549 | - # GIVEN: A mocked-out open() which raises an exception and isfile returns True |
1550 | - filename = 'testfile.txt' |
1551 | - mocked_isfile.return_value = True |
1552 | - mocked_open.side_effect = IOError() |
1553 | + # GIVEN: A patched open which raises an exception and is_file which returns True |
1554 | + with patch.object(Path, 'is_file'), \ |
1555 | + patch.object(Path, 'open'): |
1556 | + file_path = Path('testfile.txt') |
1557 | + file_path.is_file.return_value = True |
1558 | + file_path.open.side_effect = IOError() |
1559 | |
1560 | # WHEN: get_text_file_string is called |
1561 | - result = get_text_file_string(filename) |
1562 | + result = get_text_file_string(file_path) |
1563 | |
1564 | # THEN: None should be returned |
1565 | - mocked_isfile.assert_called_with(filename) |
1566 | - mocked_open.assert_called_with(filename, 'r', encoding='utf-8') |
1567 | + file_path.is_file.assert_called_once_with() |
1568 | + file_path.open.assert_called_once_with('r', encoding='utf-8') |
1569 | self.assertIsNone(result, 'None should be returned if the file cannot be opened') |
1570 | |
1571 | def test_get_text_file_string_decode_error(self): |
1572 | |
1573 | === modified file 'tests/functional/openlp_core_ui/test_firsttimeform.py' |
1574 | --- tests/functional/openlp_core_ui/test_firsttimeform.py 2017-04-24 05:17:55 +0000 |
1575 | +++ tests/functional/openlp_core_ui/test_firsttimeform.py 2017-08-23 20:14:53 +0000 |
1576 | @@ -25,6 +25,7 @@ |
1577 | import os |
1578 | import tempfile |
1579 | import urllib |
1580 | +from pathlib import Path |
1581 | from unittest import TestCase |
1582 | from unittest.mock import MagicMock, patch |
1583 | |
1584 | @@ -116,7 +117,7 @@ |
1585 | mocked_settings.value.return_value = True |
1586 | MockedSettings.return_value = mocked_settings |
1587 | mocked_gettempdir.return_value = 'temp' |
1588 | - expected_temp_path = os.path.join('temp', 'openlp') |
1589 | + expected_temp_path = Path('temp', 'openlp') |
1590 | |
1591 | # WHEN: The set_defaults() method is run |
1592 | frw.set_defaults() |
1593 | |
1594 | === modified file 'tests/functional/openlp_core_ui/test_thememanager.py' |
1595 | --- tests/functional/openlp_core_ui/test_thememanager.py 2017-06-01 06:18:47 +0000 |
1596 | +++ tests/functional/openlp_core_ui/test_thememanager.py 2017-08-23 20:14:53 +0000 |
1597 | @@ -90,7 +90,7 @@ |
1598 | # theme, check_directory_exists and thememanager-attributes. |
1599 | with patch('builtins.open') as mocked_open, \ |
1600 | patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ |
1601 | - patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: |
1602 | + patch('openlp.core.ui.thememanager.check_directory_exists'): |
1603 | mocked_open.return_value = MagicMock() |
1604 | theme_manager = ThemeManager(None) |
1605 | theme_manager.old_background_image = None |
1606 | @@ -118,7 +118,7 @@ |
1607 | # theme, check_directory_exists and thememanager-attributes. |
1608 | with patch('builtins.open') as mocked_open, \ |
1609 | patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ |
1610 | - patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: |
1611 | + patch('openlp.core.ui.thememanager.check_directory_exists'): |
1612 | mocked_open.return_value = MagicMock() |
1613 | theme_manager = ThemeManager(None) |
1614 | theme_manager.old_background_image = None |
1615 | |
1616 | === modified file 'tests/functional/openlp_plugins/bibles/test_manager.py' |
1617 | --- tests/functional/openlp_plugins/bibles/test_manager.py 2016-12-31 11:01:36 +0000 |
1618 | +++ tests/functional/openlp_plugins/bibles/test_manager.py 2017-08-23 20:14:53 +0000 |
1619 | @@ -22,6 +22,7 @@ |
1620 | """ |
1621 | This module contains tests for the manager submodule of the Bibles plugin. |
1622 | """ |
1623 | +from pathlib import Path |
1624 | from unittest import TestCase |
1625 | from unittest.mock import MagicMock, patch |
1626 | |
1627 | @@ -50,7 +51,6 @@ |
1628 | """ |
1629 | # GIVEN: An instance of BibleManager and a mocked bible |
1630 | with patch.object(BibleManager, 'reload_bibles'), \ |
1631 | - patch('openlp.plugins.bibles.lib.manager.os.path.join', side_effect=lambda x, y: '{}/{}'.format(x, y)),\ |
1632 | patch('openlp.plugins.bibles.lib.manager.delete_file', return_value=True) as mocked_delete_file: |
1633 | instance = BibleManager(MagicMock()) |
1634 | # We need to keep a reference to the mock for close_all as it gets set to None later on! |
1635 | @@ -66,4 +66,4 @@ |
1636 | self.assertTrue(result) |
1637 | mocked_close_all.assert_called_once_with() |
1638 | self.assertIsNone(mocked_bible.session) |
1639 | - mocked_delete_file.assert_called_once_with('bibles/KJV.sqlite') |
1640 | + mocked_delete_file.assert_called_once_with(Path('bibles', 'KJV.sqlite')) |
1641 | |
1642 | === modified file 'tests/functional/openlp_plugins/media/test_mediaplugin.py' |
1643 | --- tests/functional/openlp_plugins/media/test_mediaplugin.py 2017-06-06 20:58:12 +0000 |
1644 | +++ tests/functional/openlp_plugins/media/test_mediaplugin.py 2017-08-23 20:14:53 +0000 |
1645 | @@ -38,20 +38,18 @@ |
1646 | def setUp(self): |
1647 | Registry.create() |
1648 | |
1649 | - @patch(u'openlp.plugins.media.mediaplugin.Plugin.initialise') |
1650 | + @patch('openlp.plugins.media.mediaplugin.Plugin.initialise') |
1651 | def test_initialise(self, mocked_initialise): |
1652 | """ |
1653 | Test that the initialise() method overwrites the built-in one, but still calls it |
1654 | """ |
1655 | - # GIVEN: A media plugin instance and a mocked settings object |
1656 | + # GIVEN: A media plugin instance |
1657 | media_plugin = MediaPlugin() |
1658 | - mocked_settings = MagicMock() |
1659 | - mocked_settings.get_files_from_config.return_value = True # Not the real value, just need something "true-ish" |
1660 | |
1661 | # WHEN: initialise() is called |
1662 | media_plugin.initialise() |
1663 | |
1664 | - # THEN: The settings should be upgraded and the base initialise() method should be called |
1665 | + # THEN: The the base initialise() method should be called |
1666 | mocked_initialise.assert_called_with() |
1667 | |
1668 | def test_about_text(self): |
1669 | |
1670 | === modified file 'tests/functional/openlp_plugins/presentations/test_presentationcontroller.py' |
1671 | --- tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-05-30 18:42:35 +0000 |
1672 | +++ tests/functional/openlp_plugins/presentations/test_presentationcontroller.py 2017-08-23 20:14:53 +0000 |
1673 | @@ -24,6 +24,7 @@ |
1674 | classes and related methods. |
1675 | """ |
1676 | import os |
1677 | +from pathlib import Path |
1678 | from unittest import TestCase |
1679 | from unittest.mock import MagicMock, mock_open, patch |
1680 | |
1681 | @@ -38,7 +39,8 @@ |
1682 | """ |
1683 | def setUp(self): |
1684 | self.get_thumbnail_folder_patcher = \ |
1685 | - patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder') |
1686 | + patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder', |
1687 | + return_value=Path()) |
1688 | self.get_thumbnail_folder_patcher.start() |
1689 | mocked_plugin = MagicMock() |
1690 | mocked_plugin.settings_section = 'presentations' |
1691 | @@ -225,7 +227,7 @@ |
1692 | PresentationDocument(self.mock_controller, 'Name') |
1693 | |
1694 | # THEN: check_directory_exists should have been called with 'returned/path/' |
1695 | - self.mock_check_directory_exists.assert_called_once_with('returned/path/') |
1696 | + self.mock_check_directory_exists.assert_called_once_with(Path('returned', 'path')) |
1697 | |
1698 | self._setup_patcher.start() |
1699 | |
1700 | |
1701 | === modified file 'tests/interfaces/openlp_core_common/test_utils.py' |
1702 | --- tests/interfaces/openlp_core_common/test_utils.py 2016-12-31 11:01:36 +0000 |
1703 | +++ tests/interfaces/openlp_core_common/test_utils.py 2017-08-23 20:14:53 +0000 |
1704 | @@ -22,7 +22,7 @@ |
1705 | """ |
1706 | Functional tests to test the AppLocation class and related methods. |
1707 | """ |
1708 | -import os |
1709 | +from pathlib import Path |
1710 | from unittest import TestCase |
1711 | |
1712 | from openlp.core.common import is_not_image_file |
1713 | @@ -59,7 +59,7 @@ |
1714 | Test the method handles an image file |
1715 | """ |
1716 | # Given and empty string |
1717 | - file_name = os.path.join(TEST_RESOURCES_PATH, 'church.jpg') |
1718 | + file_name = Path(TEST_RESOURCES_PATH, 'church.jpg') |
1719 | |
1720 | # WHEN testing for it |
1721 | result = is_not_image_file(file_name) |
1722 | @@ -72,7 +72,7 @@ |
1723 | Test the method handles a non image file |
1724 | """ |
1725 | # Given and empty string |
1726 | - file_name = os.path.join(TEST_RESOURCES_PATH, 'serviceitem_custom_1.osj') |
1727 | + file_name = Path(TEST_RESOURCES_PATH, 'serviceitem_custom_1.osj') |
1728 | |
1729 | # WHEN testing for it |
1730 | result = is_not_image_file(file_name) |
See inline