Enable JSON to handle unsupported objects and tests

This commit is contained in:
Philip Ridout 2017-08-25 21:03:25 +01:00
parent cd158b63fd
commit f8a68c23d0
46 changed files with 382 additions and 202 deletions

View File

@ -33,13 +33,13 @@ import os
import shutil
import sys
import time
from pathlib import Path
from traceback import format_exception
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, is_macosx, is_win, translate
from openlp.core.common.path import Path
from openlp.core.common.versionchecker import VersionThread, get_application_version
from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources
@ -347,8 +347,7 @@ def set_up_logging(log_path):
"""
Setup our logging using log_path
:param pathlib.Path log_path: The file to save the log to
:return: None
:param openlp.core.common.path.Path log_path: The file to save the log to.
:rtype: None
"""
check_directory_exists(log_path, True)

View File

@ -66,9 +66,8 @@ def check_directory_exists(directory, do_not_log=False):
"""
Check a directory exists and if not create it
:param pathlib.Path directory: The directory to make sure exists
:param openlp.core.common.path.Path directory: The directory to make sure exists
:param bool do_not_log: To not log anything. This is need for the start up, when the log isn't ready.
:return: None
:rtype: None
"""
if not do_not_log:
@ -89,7 +88,6 @@ def extension_loader(glob_pattern, excluded_files=[]):
:param str glob_pattern: A glob pattern used to find the extension(s) to be imported. Should be relative to the
application directory. i.e. plugins/*/*plugin.py
:param list[str] excluded_files: A list of file names to exclude that the glob pattern may find.
:return: None
:rtype: None
"""
app_dir = AppLocation.get_directory(AppLocation.AppDir)
@ -110,7 +108,7 @@ def path_to_module(path):
"""
Convert a path to a module name (i.e openlp.core.common)
:param pathlib.Path path: The path to convert to a module name.
:param openlp.core.common.path.Path path: The path to convert to a module name.
:return: The module name.
:rtype: str
"""
@ -377,7 +375,7 @@ def delete_file(file_path):
"""
Deletes a file from the system.
:param pathlib.Path file_path: The file, including path, to delete.
:param openlp.core.common.path.Path file_path: The file, including path, to delete.
:return: True if the deletion was successful, or the file never existed. False otherwise.
:rtype: bool
"""
@ -412,7 +410,7 @@ def is_not_image_file(file_path):
"""
Validate that the file is not an image file.
:param pathlib.Path file_path: The file to be checked.
:param openlp.core.common.path.Path file_path: The file to be checked.
:return: If the file is not an image
:rtype: bool
"""
@ -440,7 +438,7 @@ def check_binary_exists(program_path):
"""
Function that checks whether a binary exists.
:param pathlib.Path program_path: The full path to the binary to check.
:param openlp.core.common.path.Path program_path: The full path to the binary to check.
:return: program output to be parsed
:rtype: bytes
"""
@ -466,7 +464,7 @@ def get_file_encoding(file_path):
"""
Utility function to incrementally detect the file encoding.
:param pathlib.Path file_path: Filename for the file to determine the encoding for.
:param openlp.core.common.path.Path file_path: Filename for the file to determine the encoding for.
:return: A dict with the keys 'encoding' and 'confidence'
:rtype: dict[str, float]
"""

View File

@ -25,9 +25,9 @@ The :mod:`openlp.core.common.applocation` module provides an utility for OpenLP
import logging
import os
import sys
from pathlib import Path
from openlp.core.common import Settings, is_win, is_macosx
from openlp.core.common.path import Path
if not is_win() and not is_macosx():
@ -64,10 +64,8 @@ class AppLocation(object):
Return the appropriate directory according to the directory type.
:param dir_type: The directory type you want, for instance the data directory. Default *AppLocation.AppDir*
:type dir_type: AppLocation Enum
:return: The requested path
:rtype: pathlib.Path
:rtype: openlp.core.common.path.Path
"""
if dir_type == AppLocation.AppDir or dir_type == AppLocation.VersionDir:
return get_frozen_path(FROZEN_APP_PATH, APP_PATH)
@ -84,7 +82,7 @@ class AppLocation(object):
Return the path OpenLP stores all its data under.
:return: The data path to use.
:rtype: pathlib.Path
:rtype: openlp.core.common.path.Path
"""
# Check if we have a different data location.
if Settings().contains('advanced/data path'):
@ -104,7 +102,7 @@ class AppLocation(object):
:param str extension: Defaults to ''. The extension to search for. For example::
'.png'
:return: List of files found.
:rtype: list[pathlib.Path]
:rtype: list[openlp.core.common.path.Path]
"""
path = AppLocation.get_data_path()
if section:
@ -121,8 +119,7 @@ class AppLocation(object):
Return the path a particular module stores its data under.
:type section: str
:rtype: pathlib.Path
:rtype: openlp.core.common.path.Path
"""
path = AppLocation.get_data_path() / section
check_directory_exists(path)
@ -135,7 +132,7 @@ def _get_os_dir_path(dir_type):
:param dir_type: AppLocation Enum of the requested path type
:return: The requested path
:rtype: pathlib.Path
:rtype: openlp.core.common.path.Path
"""
# If running from source, return the language directory from the source directory
if dir_type == AppLocation.LanguageDir:

View File

@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from json import JSONDecoder, JSONEncoder
from openlp.core.common.path import Path
class OpenLPJsonDecoder(JSONDecoder):
"""
Implement a custom JSONDecoder to handle Path objects
Example Usage:
object = json.loads(json_string, cls=OpenLPJsonDecoder)
"""
def __init__(self, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True,
object_pairs_hook=None, **kwargs):
"""
Re-implement __init__ so that we can pass in our object_hook method. Any additional kwargs, are stored in the
instance and are passed to custom objects upon encoding or decoding.
"""
self.kwargs = kwargs
if not object_hook:
object_hook = self.object_hook
super().__init__(object_hook, parse_float, parse_int, parse_constant, strict, object_pairs_hook)
def object_hook(self, obj):
"""
Implement a custom Path object decoder.
:param dict obj: A decoded JSON object
:return: The original object literal, or a Path object if the object literal contains a key '__Path__'
:rtype: dict | openlp.core.common.path.Path
"""
if '__Path__' in obj:
obj = Path.encode_json(obj, **self.kwargs)
return obj
class OpenLPJsonEncoder(JSONEncoder):
"""
Implement a custom JSONEncoder to handle Path objects
Example Usage:
json_string = json.dumps(object, cls=OpenLPJsonEncoder)
"""
def __init__(self, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False,
indent=None, separators=None, default=None, **kwargs):
"""
Re-implement __init__ so that we can pass in additional kwargs, which are stored in the instance and are passed
to custom objects upon encoding or decoding.
"""
self.kwargs = kwargs
super().__init__(skipkeys, ensure_ascii, check_circular, allow_nan, sort_keys, indent, separators, default)
def default(self, obj):
"""
Convert any Path objects into a dictionary object which can be serialized.
:param object obj: The object to convert
:return: The serializable object
:rtype: dict
"""
if isinstance(obj, Path):
return obj.json_object(**self.kwargs)
return super().default(obj)

View File

@ -19,17 +19,23 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import pathlib
from contextlib import suppress
from pathlib import Path
from openlp.core.common import is_win
def path_to_str(path):
if is_win():
path_variant = pathlib.WindowsPath
else:
path_variant = pathlib.PosixPath
def path_to_str(path=None):
"""
A utility function to convert a Path object or NoneType to a string equivalent.
:param path: The value to convert to a string
:type: pathlib.Path or None
:param openlp.core.common.path.Path | None path: The value to convert to a string
:return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
:rtype: str
"""
@ -48,14 +54,49 @@ def str_to_path(string):
This function is of particular use because initating a Path object with an empty string causes the Path object to
point to the current working directory.
:param string: The string to convert
:type string: str
:param str string: The string to convert
:return: None if :param:`string` is empty, or a Path object representation of :param:`string`
:rtype: pathlib.Path or None
:rtype: openlp.core.common.path.Path | None
"""
if not isinstance(string, str):
raise TypeError('parameter \'string\' must be of type str')
if string == '':
return None
return Path(string)
class Path(path_variant):
"""
Subclass pathlib.Path, so we can add json conversion methods
"""
@staticmethod
def encode_json(obj, base_path=None, **kwargs):
"""
Create a Path object from a dictionary representation. The dictionary has been constructed by JSON encoding of
a JSON reprensation of a Path object.
:param dict[str] obj: The dictionary representation
:param openlp.core.common.path.Path base_path: If specified, an absolute path to base the relative path off of.
:param kwargs: Contains any extra parameters. Not used!
:return: The reconstructed Path object
:rtype: openlp.core.common.path.Path
"""
path = Path(*obj['__Path__'])
if base_path and not path.is_absolute():
return base_path / path
return path
def json_object(self, base_path=None, **kwargs):
"""
Create a dictionary that can be JSON decoded.
:param openlp.core.common.path.Path base_path: If specified, an absolute path to make a relative path from.
:param kwargs: Contains any extra parameters. Not used!
:return: The dictionary representation of this Path object.
:rtype: dict[tuple]
"""
path = self
if base_path:
with suppress(ValueError):
path = path.relative_to(base_path)
return {'__Path__': path.parts}

View File

@ -89,7 +89,7 @@ def get_text_file_string(text_file_path):
returns False. If there is an error loading the file or the content can't be decoded then the function will return
None.
:param pathlib.Path text_file_path: The path to the file.
:param openlp.core.common.path.Path text_file_path: The path to the file.
:return: The contents of the file, False if the file does not exist, or None if there is an Error reading or
decoding the file.
:rtype: str | False | None
@ -610,17 +610,11 @@ def replace_params(args, kwargs, params):
"""
Apply a transformation function to the specified args or kwargs
:param args: Positional arguments
:type args: (,)
:param kwargs: Key Word arguments
:type kwargs: dict
:param tuple args: Positional arguments
:param dict kwargs: Key Word arguments
:param params: A tuple of tuples with the position and the key word to replace.
:type params: ((int, str, path_to_str),)
:return: The modified positional and keyword arguments
:rtype: (tuple, dict)
:rtype: tuple[tuple, dict]
Usage:

View File

@ -1,61 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from pathlib import Path
def path_to_str(path):
"""
A utility function to convert a Path object or NoneType to a string equivalent.
:param path: The value to convert to a string
:type: pathlib.Path or None
:return: An empty string if :param:`path` is None, else a string representation of the :param:`path`
:rtype: str
"""
if not isinstance(path, Path) and path is not None:
raise TypeError('parameter \'path\' must be of type Path or NoneType')
if path is None:
return ''
else:
return str(path)
def str_to_path(string):
"""
A utility function to convert a str object to a Path or NoneType.
This function is of particular use because initating a Path object with an empty string causes the Path object to
point to the current working directory.
:param string: The string to convert
:type string: str
:return: None if :param:`string` is empty, or a Path object representation of :param:`string`
:rtype: pathlib.Path or None
"""
if not isinstance(string, str):
raise TypeError('parameter \'string\' must be of type str')
if string == '':
return None
return Path(string)

View File

@ -30,13 +30,13 @@ import urllib.request
import urllib.parse
import urllib.error
from configparser import ConfigParser, MissingSectionHeaderError, NoOptionError, NoSectionError
from pathlib import Path
from tempfile import gettempdir
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, \
translate, clean_button_text, trace_error_handler
from openlp.core.common.path import Path
from openlp.core.lib import PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.common.httputils import get_web_page, get_url_file_size, url_get_file, CONNECTION_TIMEOUT

View File

@ -23,12 +23,11 @@
The general tab of the configuration dialog.
"""
import logging
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import SettingsTab, ScreenList
from openlp.core.ui.lib import ColorButton, PathEdit

View File

@ -20,11 +20,9 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
""" Patch the QFileDialog so it accepts and returns Path objects"""
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import replace_params
@ -36,7 +34,7 @@ class FileDialog(QtWidgets.QFileDialog):
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type directory: openlp.core.common.path.Path
:type options: QtWidgets.QFileDialog.Options
:rtype: tuple[Path, str]
"""
@ -55,7 +53,7 @@ class FileDialog(QtWidgets.QFileDialog):
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
@ -76,7 +74,7 @@ class FileDialog(QtWidgets.QFileDialog):
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options
@ -98,7 +96,7 @@ class FileDialog(QtWidgets.QFileDialog):
:type parent: QtWidgets.QWidget or None
:type caption: str
:type directory: pathlib.Path
:type directory: openlp.core.common.path.Path
:type filter: str
:type initialFilter: str
:type options: QtWidgets.QFileDialog.Options

View File

@ -20,12 +20,11 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from enum import Enum
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import UiStrings, translate
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import build_icon
from openlp.core.ui.lib.filedialog import FileDialog
@ -46,19 +45,10 @@ class PathEdit(QtWidgets.QWidget):
"""
Initialise the PathEdit widget
:param parent: The parent of the widget. This is just passed to the super method.
:type parent: QWidget or None
:param dialog_caption: Used to customise the caption in the QFileDialog.
:type dialog_caption: str
:param default_path: The default path. This is set as the path when the revert button is clicked
:type default_path: pathlib.Path
:param show_revert: Used to determine if the 'revert button' should be visible.
:type show_revert: bool
:return: None
:param QtWidget.QWidget | None: The parent of the widget. This is just passed to the super method.
:param str dialog_caption: Used to customise the caption in the QFileDialog.
:param openlp.core.common.path.Path default_path: The default path. This is set as the path when the revert button is clicked
:param bool show_revert: Used to determine if the 'revert button' should be visible.
:rtype: None
"""
super().__init__(parent)
@ -72,10 +62,7 @@ class PathEdit(QtWidgets.QWidget):
def _setup(self, show_revert):
"""
Set up the widget
:param show_revert: Show or hide the revert button
:type show_revert: bool
:return: None
:param bool show_revert: Show or hide the revert button
:rtype: None
"""
widget_layout = QtWidgets.QHBoxLayout()
@ -102,7 +89,7 @@ class PathEdit(QtWidgets.QWidget):
A property getter method to return the selected path.
:return: The selected path
:rtype: pathlib.Path
:rtype: openlp.core.common.path.Path
"""
return self._path
@ -111,10 +98,7 @@ class PathEdit(QtWidgets.QWidget):
"""
A Property setter method to set the selected path
:param path: The path to set the widget to
:type path: pathlib.Path
:return: None
:param openlp.core.common.path.Path path: The path to set the widget to
:rtype: None
"""
self._path = path
@ -138,10 +122,7 @@ class PathEdit(QtWidgets.QWidget):
"""
A Property setter method to set the path type
:param path_type: The type of path to select
:type path_type: PathType
:return: None
:param PathType path_type: The type of path to select
:rtype: None
"""
self._path_type = path_type
@ -151,7 +132,6 @@ class PathEdit(QtWidgets.QWidget):
"""
Called to update the tooltips on the buttons. This is changing path types, and when the widget is initalised
:return: None
:rtype: None
"""
if self._path_type == PathType.Directories:
@ -167,7 +147,6 @@ class PathEdit(QtWidgets.QWidget):
Show the QFileDialog and process the input from the user
:return: None
:rtype: None
"""
caption = self.dialog_caption
@ -189,7 +168,6 @@ class PathEdit(QtWidgets.QWidget):
Set the new path to the value of the default_path instance variable.
:return: None
:rtype: None
"""
self.on_new_path(self.default_path)
@ -198,7 +176,6 @@ class PathEdit(QtWidgets.QWidget):
"""
A handler to handle when the line edit has finished being edited.
:return: None
:rtype: None
"""
path = str_to_path(self.line_edit.text())
@ -210,10 +187,7 @@ class PathEdit(QtWidgets.QWidget):
Emits the pathChanged Signal
:param path: The new path
:type path: pathlib.Path
:return: None
:param openlp.core.common.path.Path path: The new path
:rtype: None
"""
if self._path != path:

View File

@ -30,7 +30,6 @@ import time
from datetime import datetime
from distutils import dir_util
from distutils.errors import DistutilsFileError
from pathlib import Path
from tempfile import gettempdir
from PyQt5 import QtCore, QtGui, QtWidgets
@ -40,6 +39,7 @@ from openlp.core.api.http import server
from openlp.core.common import Registry, RegistryProperties, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path
from openlp.core.common.versionchecker import get_application_version
from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon
from openlp.core.lib.ui import create_action

View File

@ -28,7 +28,6 @@ import os
import shutil
import zipfile
from datetime import datetime, timedelta
from pathlib import Path
from tempfile import mkstemp
from PyQt5 import QtCore, QtGui, QtWidgets
@ -36,6 +35,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, ThemeLevel, OpenLPMixin, \
RegistryMixin, check_directory_exists, UiStrings, translate, split_filename, delete_file
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path
from openlp.core.lib import ServiceItem, ItemCapabilities, PluginStatus, build_icon
from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm

View File

@ -24,12 +24,11 @@ The Theme wizard
"""
import logging
import os
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, UiStrings, translate, get_images_filter, is_not_image_file
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ThemeLayoutForm

View File

@ -25,14 +25,13 @@ The Theme Manager manages adding, deleteing and modifying of themes.
import os
import zipfile
import shutil
from pathlib import Path
from xml.etree.ElementTree import ElementTree, XML
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, OpenLPMixin, RegistryMixin, \
UiStrings, check_directory_exists, translate, is_win, get_filesystem_encoding, delete_file
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import ImageSource, ValidationError, get_text_file_string, build_icon, \
check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.theme import Theme, BackgroundType

View File

@ -22,11 +22,10 @@
"""
The Create/Edit theme wizard
"""
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import UiStrings, translate, is_macosx
from openlp.core.common.path import Path
from openlp.core.lib import build_icon
from openlp.core.lib.theme import HorizontalType, BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import add_welcome_page, create_valign_selection_widgets

View File

@ -51,9 +51,9 @@ All CSV files are expected to use a comma (',') as the delimiter and double quot
"""
import csv
from collections import namedtuple
from pathlib import Path
from openlp.core.common import get_file_encoding, translate
from openlp.core.common.path import Path
from openlp.core.lib.exceptions import ValidationError
from openlp.plugins.bibles.lib.bibleimport import BibleImport

View File

@ -21,10 +21,9 @@
###############################################################################
import logging
import os
from pathlib import Path
from openlp.core.common import AppLocation, OpenLPMixin, RegistryProperties, Settings, translate, delete_file, UiStrings
from openlp.core.common.path import Path
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from .importers.csvbible import CSVBible
@ -306,13 +305,10 @@ class BibleManager(OpenLPMixin, RegistryProperties):
"""
Does a verse search for the given bible and text.
:param bible: The bible to search
:type bible: str
:param text: The text to search for
:type text: str
:param str bible: The bible to search
:param str text: The text to search for
:return: The search results if valid, or None if the search is invalid.
:rtype: None, list
:rtype: None | list
"""
log.debug('BibleManager.verse_search("{bible}", "{text}")'.format(bible=bible, text=text))
if not text:

View File

@ -465,8 +465,7 @@ class BibleMediaItem(MediaManagerItem):
"""
Show the selected tab and set focus to it
:param index: The tab selected
:type index: int
:param int index: The tab selected
:return: None
"""
if index == SearchTabs.Search or index == SearchTabs.Select:
@ -483,7 +482,7 @@ class BibleMediaItem(MediaManagerItem):
Update list_widget with the contents of the selected list
:param index: The index of the tab that has been changed to. (int)
:return: None
:rtype: None
"""
if index == ResultsTab.Saved:
self.add_built_results_to_list_widget(self.saved_results)

View File

@ -22,12 +22,12 @@
import logging
import os
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, AppLocation, Settings, UiStrings, check_directory_exists, translate, \
delete_file, get_images_filter
from openlp.core.common.path import Path
from openlp.core.lib import ItemCapabilities, MediaManagerItem, ServiceItemContext, StringContent, build_icon, \
check_item_selected, create_thumb, validate_thumb
from openlp.core.lib.ui import create_widget_action, critical_error_message_box

View File

@ -22,12 +22,12 @@
import logging
import os
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, Settings, check_directory_exists, UiStrings,\
translate
from openlp.core.common.path import Path
from openlp.core.lib import ItemCapabilities, MediaManagerItem, MediaType, ServiceItem, ServiceItemContext, \
build_icon, check_item_selected
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box

View File

@ -26,12 +26,11 @@ The Media plugin
import logging
import os
import re
from pathlib import Path
from PyQt5 import QtCore
from openlp.core.api.http import register_endpoint
from openlp.core.common import AppLocation, translate, check_binary_exists
from openlp.core.common.path import Path
from openlp.core.lib import Plugin, StringContent, build_icon
from openlp.plugins.media.endpoint import api_media_endpoint, media_endpoint
from openlp.plugins.media.lib import MediaMediaItem, MediaTab

View File

@ -34,9 +34,9 @@
import logging
import os
import time
from pathlib import Path
from openlp.core.common import is_win, Registry, get_uno_command, get_uno_instance, delete_file
from openlp.core.common import is_win, Registry, delete_file
from openlp.core.common.path import Path
if is_win():
from win32com.client import Dispatch

View File

@ -23,12 +23,12 @@
import os
import logging
import re
from pathlib import Path
from shutil import which
from subprocess import check_output, CalledProcessError
from openlp.core.common import AppLocation, check_binary_exists
from openlp.core.common import Settings, is_win
from openlp.core.common.path import Path
from openlp.core.lib import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument

View File

@ -23,11 +23,11 @@
import logging
import os
import shutil
from pathlib import Path
from PyQt5 import QtCore
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, md5_hash
from openlp.core.common.path import Path
from openlp.core.lib import create_thumb, validate_thumb
log = logging.getLogger(__name__)

View File

@ -28,12 +28,11 @@ import logging
import re
import os
import shutil
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, AppLocation, UiStrings, check_directory_exists, translate
from openlp.core.common.path import path_to_str
from openlp.core.common.path import Path, path_to_str
from openlp.core.lib import PluginStatus, MediaType, create_separated_list
from openlp.core.lib.ui import set_case_insensitive_completer, critical_error_message_box, find_and_set_in_combo_box
from openlp.core.ui.lib.filedialog import FileDialog

View File

@ -27,11 +27,11 @@ import os
import re
import base64
import math
from pathlib import Path
from openlp.core.common import Settings, is_win, is_macosx, get_file_encoding
from openlp.core.common.path import Path
from openlp.plugins.songs.lib import VerseType
from openlp.plugins.songs.lib.importers.songimport import SongImport
from openlp.core.common import Settings, is_win, is_macosx, get_file_encoding
log = logging.getLogger(__name__)

View File

@ -24,11 +24,11 @@ import logging
import re
import shutil
import os
from pathlib import Path
from PyQt5 import QtCore
from openlp.core.common import Registry, AppLocation, check_directory_exists, translate
from openlp.core.common.path import Path
from openlp.core.ui.lib.wizard import WizardStrings
from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book, MediaFile

View File

@ -23,12 +23,12 @@
import logging
import os
import shutil
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_, or_
from openlp.core.common import Registry, AppLocation, Settings, check_directory_exists, UiStrings, translate
from openlp.core.common.path import Path
from openlp.core.lib import MediaManagerItem, ItemCapabilities, PluginStatus, ServiceItemContext, \
check_item_selected, create_separated_list
from openlp.core.lib.ui import create_widget_action

View File

@ -25,11 +25,11 @@ format.
"""
import logging
import os
from pathlib import Path
from lxml import etree
from openlp.core.common import RegistryProperties, check_directory_exists, translate, clean_filename
from openlp.core.common.path import Path
from openlp.plugins.songs.lib.openlyricsxml import OpenLyrics
log = logging.getLogger(__name__)

View File

@ -22,13 +22,12 @@
import logging
import os
from pathlib import Path
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_
from openlp.core.common import RegistryProperties, Settings, check_directory_exists, translate
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.songusage.lib.db import SongUsageItem
from .songusagedetaildialog import Ui_SongUsageDetailDialog

View File

@ -22,13 +22,12 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
import copy
import os
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common import AppLocation, get_frozen_path
from openlp.core.common.path import Path
FILE_LIST = ['file1', 'file2', 'file3.txt', 'file4.txt', 'file5.mp3', 'file6.mp3']

View File

@ -22,13 +22,12 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, call, patch
from openlp.core import common
from openlp.core.common import check_directory_exists, clean_button_text, de_hump, extension_loader, is_macosx, \
is_linux, is_win, path_to_module, trace_error_handler, translate
from openlp.core.common.path import Path
class TestCommonFunctions(TestCase):

View File

@ -24,12 +24,12 @@ Functional tests to test the AppLocation class and related methods.
"""
import os
from io import BytesIO
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, PropertyMock, call, patch
from openlp.core.common import add_actions, clean_filename, delete_file, get_file_encoding, get_filesystem_encoding, \
get_uno_command, get_uno_instance, split_filename
from openlp.core.common.path import Path
from tests.helpers.testmixin import TestMixin

View File

@ -0,0 +1,122 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Package to test the openlp.core.common.json package.
"""
import json
from unittest import TestCase
from unittest.mock import patch
from openlp.core.common.path import Path
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
class TestOpenLPJsonDecoder(TestCase):
"""
Test the OpenLPJsonDecoder class
"""
def test_object_hook_path_object(self):
"""
Test the object_hook method when called with a decoded Path JSON object
"""
# GIVEN: An instance of OpenLPJsonDecoder
instance = OpenLPJsonDecoder()
# WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
result = instance.object_hook({'__Path__': ['test', 'path']})
# THEN: A Path object should be returned
self.assertEqual(result, Path('test', 'path'))
def test_object_hook_non_path_object(self):
"""
Test the object_hook method when called with a decoded JSON object
"""
# GIVEN: An instance of OpenLPJsonDecoder
instance = OpenLPJsonDecoder()
# WHEN: Calling the object_hook method with a decoded JSON object which contains a Path
with patch('openlp.core.common.json.Path') as mocked_path:
result = instance.object_hook({'key': 'value'})
# THEN: The object should be returned unchanged and a Path object should not have been initiated
self.assertEqual(result, {'key': 'value'})
self.assertFalse(mocked_path.called)
def test_json_decode(self):
"""
Test the OpenLPJsonDecoder when decoding a JSON string
"""
# GIVEN: A JSON encoded string
json_string = '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]'
# WHEN: Decoding the string using the OpenLPJsonDecoder class
obj = json.loads(json_string, cls=OpenLPJsonDecoder)
# THEN: The object returned should be a python version of the JSON string
self.assertEqual(obj, [Path('test', 'path1'), Path('test', 'path2')])
class TestOpenLPJsonEncoder(TestCase):
"""
Test the OpenLPJsonEncoder class
"""
def test_default_path_object(self):
"""
Test the default method when called with a Path object
"""
# GIVEN: An instance of OpenLPJsonEncoder
instance = OpenLPJsonEncoder()
# WHEN: Calling the default method with a Path object
result = instance.default(Path('test', 'path'))
# THEN: A dictionary object that can be JSON encoded should be returned
self.assertEqual(result, {'__Path__': ('test', 'path')})
def test_default_non_path_object(self):
"""
Test the default method when called with a object other than a Path object
"""
with patch('openlp.core.common.json.JSONEncoder.default') as mocked_super_default:
# GIVEN: An instance of OpenLPJsonEncoder
instance = OpenLPJsonEncoder()
# WHEN: Calling the default method with a object other than a Path object
instance.default('invalid object')
# THEN: default method of the super class should have been called
mocked_super_default.assert_called_once_with('invalid object')
def test_json_encode(self):
"""
Test the OpenLPJsonDEncoder when encoding an object conatining Path objects
"""
# GIVEN: A list of Path objects
obj = [Path('test', 'path1'), Path('test', 'path2')]
# WHEN: Encoding the object using the OpenLPJsonEncoder class
json_string = json.dumps(obj, cls=OpenLPJsonEncoder)
# THEN: The JSON string return should be a representation of the object encoded
self.assertEqual(json_string, '[{"__Path__": ["test", "path1"]}, {"__Path__": ["test", "path2"]}]')

View File

@ -23,10 +23,9 @@
Package to test the openlp.core.common.path package.
"""
import os
from pathlib import Path
from unittest import TestCase
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
class TestPath(TestCase):
@ -86,3 +85,54 @@ class TestPath(TestCase):
# THEN: `path_to_str` should return None
self.assertEqual(result, None)
def test_path_encode_json(self):
"""
Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
from JSON
"""
# GIVEN: A Path object from openlp.core.common.path
# WHEN: Calling encode_json, with a dictionary representation
path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, extra=1, args=2)
# THEN: A Path object should have been returned
self.assertEqual(path, Path('path', 'to', 'fi.le'))
def test_path_encode_json_base_path(self):
"""
Test that `Path.encode_json` returns a Path object from a dictionary representation of a Path object decoded
from JSON when the base_path arg is supplied.
"""
# GIVEN: A Path object from openlp.core.common.path
# WHEN: Calling encode_json, with a dictionary representation
path = Path.encode_json({'__Path__': ['path', 'to', 'fi.le']}, base_path=Path('/base'))
# THEN: A Path object should have been returned with an absolute path
self.assertEqual(path, Path('/', 'base', 'path', 'to', 'fi.le'))
def test_path_json_object(self):
"""
Test that `Path.json_object` creates a JSON decode-able object from a Path object
"""
# GIVEN: A Path object from openlp.core.common.path
path = Path('/base', 'path', 'to', 'fi.le')
# WHEN: Calling json_object
obj = path.json_object(extra=1, args=2)
# THEN: A JSON decodable object should have been returned.
self.assertEqual(obj, {'__Path__': ('/', 'base', 'path', 'to', 'fi.le')})
def test_path_json_object_base_path(self):
"""
Test that `Path.json_object` creates a JSON decode-able object from a Path object, that is relative to the
base_path
"""
# GIVEN: A Path object from openlp.core.common.path
path = Path('/base', 'path', 'to', 'fi.le')
# WHEN: Calling json_object with a base_path
obj = path.json_object(base_path=Path('/', 'base'))
# THEN: A JSON decodable object should have been returned.
self.assertEqual(obj, {'__Path__': ('path', 'to', 'fi.le')})

View File

@ -22,9 +22,7 @@
"""
Package to test the openlp.core.lib package.
"""
import os
import shutil
from pathlib import Path
from tempfile import mkdtemp
from unittest import TestCase
@ -34,6 +32,7 @@ from sqlalchemy.pool import NullPool
from sqlalchemy.orm.scoping import ScopedSession
from sqlalchemy import MetaData
from openlp.core.common.path import Path
from openlp.core.lib.db import init_db, get_upgrade_op, delete_database, upgrade_db
from openlp.core.lib.projector import upgrade as pjlink_upgrade

View File

@ -24,12 +24,12 @@ Package to test the openlp.core.lib package.
"""
import os
from datetime import datetime, timedelta
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui
from openlp.core.common.path import Path
from openlp.core.lib import FormattingTags, build_icon, check_item_selected, clean_tags, compare_chord_lyric, \
create_separated_list, create_thumb, expand_chords, expand_chords_for_printing, expand_tags, find_formatting_tags, \
get_text_file_string, image_to_byte, replace_params, resize_image, str_to_bool, validate_thumb

View File

@ -23,10 +23,9 @@
Package to test the openlp.core.lib.path package.
"""
import os
from pathlib import Path
from unittest import TestCase
from openlp.core.lib.path import path_to_str, str_to_path
from openlp.core.common.path import Path, path_to_str, str_to_path
class TestPath(TestCase):

View File

@ -25,11 +25,11 @@ Package to test the openlp.core.ui.firsttimeform package.
import os
import tempfile
import urllib
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common import Registry
from openlp.core.common.path import Path
from openlp.core.ui.firsttimeform import FirstTimeForm
from tests.helpers.testmixin import TestMixin

View File

@ -22,10 +22,10 @@
"""
Package to test the openlp.core.ui.themeform package.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.path import Path
from openlp.core.ui import ThemeForm

View File

@ -1,10 +1,10 @@
import os
from unittest import TestCase
from unittest.mock import patch
from pathlib import Path
from PyQt5 import QtWidgets
from openlp.core.common.path import Path
from openlp.core.ui.lib.filedialog import FileDialog

View File

@ -23,10 +23,10 @@
This module contains tests for the openlp.core.ui.lib.pathedit module
"""
import os
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, PropertyMock, patch
from openlp.core.common.path import Path
from openlp.core.ui.lib import PathEdit, PathType
from openlp.core.ui.lib.filedialog import FileDialog

View File

@ -22,10 +22,10 @@
"""
This module contains tests for the manager submodule of the Bibles plugin.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.path import Path
from openlp.plugins.bibles.lib.manager import BibleManager

View File

@ -24,10 +24,10 @@ Functional tests to test the PresentationController and PresentationDocument
classes and related methods.
"""
import os
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, mock_open, patch
from openlp.core.common.path import Path
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder'

View File

@ -22,10 +22,10 @@
"""
Functional tests to test the AppLocation class and related methods.
"""
from pathlib import Path
from unittest import TestCase
from openlp.core.common import is_not_image_file
from openlp.core.common.path import Path
from tests.utils.constants import TEST_RESOURCES_PATH
from tests.helpers.testmixin import TestMixin