diff --git a/nose2.cfg b/nose2.cfg new file mode 100644 index 000000000..c34cc46e1 --- /dev/null +++ b/nose2.cfg @@ -0,0 +1,17 @@ +[unittest] +verbose = True + +[log-capture] +always-on = True +clear-handlers = True +filter = -nose +log-level = ERROR + +[test-result] +always-on = True +descriptions = True + +[coverage] +always-on = False +coverage = openlp +coverage-report = html diff --git a/openlp/core/common/__init__.py b/openlp/core/common/__init__.py index f1abd8fe6..9afc08c8f 100644 --- a/openlp/core/common/__init__.py +++ b/openlp/core/common/__init__.py @@ -195,7 +195,7 @@ def verify_ip_address(addr): return True if verify_ipv4(addr) else verify_ipv6(addr) -def md5_hash(salt, data=None): +def md5_hash(salt=None, data=None): """ Returns the hashed output of md5sum on salt,data using Python3 hashlib @@ -205,8 +205,11 @@ def md5_hash(salt, data=None): :returns: str """ log.debug('md5_hash(salt="{text}")'.format(text=salt)) + if not salt and not data: + return None hash_obj = hashlib.new('md5') - hash_obj.update(salt) + if salt: + hash_obj.update(salt) if data: hash_obj.update(data) hash_value = hash_obj.hexdigest() @@ -214,22 +217,30 @@ def md5_hash(salt, data=None): return hash_value -def qmd5_hash(salt, data=None): +def qmd5_hash(salt=None, data=None): """ Returns the hashed output of MD5Sum on salt, data - using PyQt5.QCryptographicHash. + using PyQt5.QCryptographicHash. Function returns a + QByteArray instead of a text string. + If you need a string instead, call with + + result = str(qmd5_hash(salt=..., data=...), encoding='ascii') :param salt: Initial salt :param data: OPTIONAL Data to hash - :returns: str + :returns: QByteArray """ log.debug('qmd5_hash(salt="{text}"'.format(text=salt)) + if salt is None and data is None: + return None hash_obj = QHash(QHash.Md5) - hash_obj.addData(salt) - hash_obj.addData(data) + if salt: + hash_obj.addData(salt) + if data: + hash_obj.addData(data) hash_value = hash_obj.result().toHex() - log.debug('qmd5_hash() returning "{text}"'.format(text=hash_value)) - return hash_value.data() + log.debug('qmd5_hash() returning "{hash}"'.format(hash=hash_value)) + return hash_value def clean_button_text(button_text): diff --git a/openlp/core/common/actions.py b/openlp/core/common/actions.py index d22ef8fd1..5e5dd2e05 100644 --- a/openlp/core/common/actions.py +++ b/openlp/core/common/actions.py @@ -138,7 +138,7 @@ class CategoryList(object): for category in self.categories: if category.name == key: return category - raise KeyError('Category "{keY}" does not exist.'.format(key=key)) + raise KeyError('Category "{key}" does not exist.'.format(key=key)) def __len__(self): """ diff --git a/openlp/core/common/db.py b/openlp/core/common/db.py index 1e18167ab..1fd7a6521 100644 --- a/openlp/core/common/db.py +++ b/openlp/core/common/db.py @@ -22,11 +22,12 @@ """ The :mod:`db` module provides helper functions for database related methods. """ -import sqlalchemy import logging - from copy import deepcopy +import sqlalchemy + + log = logging.getLogger(__name__) diff --git a/openlp/core/common/languagemanager.py b/openlp/core/common/languagemanager.py index 58262ffb5..099e84af6 100644 --- a/openlp/core/common/languagemanager.py +++ b/openlp/core/common/languagemanager.py @@ -168,7 +168,7 @@ def format_time(text, local_time): """ return local_time.strftime(match.group()) - return re.sub('\%[a-zA-Z]', match_formatting, text) + return re.sub(r'\%[a-zA-Z]', match_formatting, text) def get_locale_key(string): diff --git a/openlp/core/common/settings.py b/openlp/core/common/settings.py index 8c66e7abc..669792c06 100644 --- a/openlp/core/common/settings.py +++ b/openlp/core/common/settings.py @@ -26,7 +26,7 @@ import datetime import logging import os -from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5 import QtCore, QtGui from openlp.core.common import ThemeLevel, SlideLimits, UiStrings, is_win, is_linux @@ -129,7 +129,7 @@ class Settings(QtCore.QSettings): 'advanced/recent file count': 4, 'advanced/save current plugin': False, 'advanced/slide limits': SlideLimits.End, - 'advanced/slide max height': 0, + 'advanced/slide max height': -4, 'advanced/single click preview': False, 'advanced/single click service preview': False, 'advanced/x11 bypass wm': X11_BYPASS_DEFAULT, diff --git a/openlp/core/common/uistrings.py b/openlp/core/common/uistrings.py index ecaacba6a..f19a35f6f 100644 --- a/openlp/core/common/uistrings.py +++ b/openlp/core/common/uistrings.py @@ -68,7 +68,7 @@ class UiStrings(object): self.Default = translate('OpenLP.Ui', 'Default') self.DefaultColor = translate('OpenLP.Ui', 'Default Color:') self.DefaultServiceName = translate('OpenLP.Ui', 'Service %Y-%m-%d %H-%M', - 'This may not contain any of the following characters: /\\?*|<>\[\]":+\n' + 'This may not contain any of the following characters: /\\?*|<>[]":+\n' 'See http://docs.python.org/library/datetime' '.html#strftime-strptime-behavior for more information.') self.Delete = translate('OpenLP.Ui', '&Delete') diff --git a/openlp/core/common/versionchecker.py b/openlp/core/common/versionchecker.py index fb706968b..25479884f 100644 --- a/openlp/core/common/versionchecker.py +++ b/openlp/core/common/versionchecker.py @@ -10,10 +10,10 @@ from datetime import datetime from distutils.version import LooseVersion from subprocess import Popen, PIPE -from openlp.core.common import AppLocation, Settings - from PyQt5 import QtCore +from openlp.core.common import AppLocation, Settings + log = logging.getLogger(__name__) APPLICATION_VERSION = {} diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index a7e01bd24..fed6df05c 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -95,7 +95,7 @@ def get_text_file_string(text_file): content = None try: file_handle = open(text_file, 'r', encoding='utf-8') - if not file_handle.read(3) == '\xEF\xBB\xBF': + if file_handle.read(3) != '\xEF\xBB\xBF': # no BOM was found file_handle.seek(0) content = file_handle.read() diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index 3decb0a3b..f42c3b5fc 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -122,6 +122,21 @@ def get_upgrade_op(session): return Operations(context) +class BaseModel(object): + """ + BaseModel provides a base object with a set of generic functions + """ + @classmethod + def populate(cls, **kwargs): + """ + Creates an instance of a class and populates it, returning the instance + """ + instance = cls() + for key, value in kwargs.items(): + instance.__setattr__(key, value) + return instance + + def upgrade_db(url, upgrade): """ Upgrade a database. @@ -178,9 +193,9 @@ def upgrade_db(url, upgrade): version_meta = Metadata.populate(key='version', value=int(upgrade.__version__)) session.commit() upgrade_version = upgrade.__version__ - version_meta = int(version_meta.value) + version = int(version_meta.value) session.close() - return version_meta, upgrade_version + return version, upgrade_version def delete_database(plugin_name, db_file_name=None): @@ -197,21 +212,6 @@ def delete_database(plugin_name, db_file_name=None): return delete_file(db_file_path) -class BaseModel(object): - """ - BaseModel provides a base object with a set of generic functions - """ - @classmethod - def populate(cls, **kwargs): - """ - Creates an instance of a class and populates it, returning the instance - """ - instance = cls() - for key, value in kwargs.items(): - instance.__setattr__(key, value) - return instance - - class Manager(object): """ Provide generic object persistence management diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index f0d8ddef2..456925d5a 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -389,6 +389,7 @@ is the function which has to be called from outside. The generated and returned """ import logging +from string import Template from PyQt5 import QtWebKit from openlp.core.common import Settings @@ -396,157 +397,200 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, Vertic log = logging.getLogger(__name__) -# TODO: Verify where this is used before converting to python3 -HTMLSRC = """ - - -
-