forked from openlp/openlp
Part 3, converted some more utility methods
Fixed the problem TGC was having. Superflys fix included (https://bin.snyman.info/mmm5sqj8) lp:~phill-ridout/openlp/pathlib3 (revision 2764) [SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2175/ [SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/2079/ [SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1966/ [SUCCESS] https://ci.openlp.io/job/Branch-04a-Code_Analysis/1336/ [SUCCESS] https://ci.openlp.io/job/Branch-04b-Test_C... bzr-revno: 2762
This commit is contained in:
commit
cd158b63fd
@ -33,6 +33,7 @@ import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
from traceback import format_exception
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
@ -346,15 +347,18 @@ def set_up_logging(log_path):
|
||||
"""
|
||||
Setup our logging using log_path
|
||||
|
||||
:param log_path: the path
|
||||
:param pathlib.Path log_path: The file to save the log to
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
check_directory_exists(log_path, True)
|
||||
filename = os.path.join(log_path, 'openlp.log')
|
||||
logfile = logging.FileHandler(filename, 'w', encoding="UTF-8")
|
||||
file_path = log_path / 'openlp.log'
|
||||
# TODO: FileHandler accepts a Path object in Py3.6
|
||||
logfile = logging.FileHandler(str(file_path), 'w', encoding='UTF-8')
|
||||
logfile.setFormatter(logging.Formatter('%(asctime)s %(name)-55s %(levelname)-8s %(message)s'))
|
||||
log.addHandler(logfile)
|
||||
if log.isEnabledFor(logging.DEBUG):
|
||||
print('Logging to: {name}'.format(name=filename))
|
||||
print('Logging to: {name}'.format(name=file_path))
|
||||
|
||||
|
||||
def main(args=None):
|
||||
@ -390,24 +394,24 @@ def main(args=None):
|
||||
application.setApplicationName('OpenLPPortable')
|
||||
Settings.setDefaultFormat(Settings.IniFormat)
|
||||
# Get location OpenLPPortable.ini
|
||||
application_path = str(AppLocation.get_directory(AppLocation.AppDir))
|
||||
set_up_logging(os.path.abspath(os.path.join(application_path, '..', '..', 'Other')))
|
||||
portable_path = (AppLocation.get_directory(AppLocation.AppDir) / '..' / '..').resolve()
|
||||
data_path = portable_path / 'Data'
|
||||
set_up_logging(portable_path / 'Other')
|
||||
log.info('Running portable')
|
||||
portable_settings_file = os.path.abspath(os.path.join(application_path, '..', '..', 'Data', 'OpenLP.ini'))
|
||||
portable_settings_path = data_path / 'OpenLP.ini'
|
||||
# Make this our settings file
|
||||
log.info('INI file: {name}'.format(name=portable_settings_file))
|
||||
Settings.set_filename(portable_settings_file)
|
||||
log.info('INI file: {name}'.format(name=portable_settings_path))
|
||||
Settings.set_filename(str(portable_settings_path))
|
||||
portable_settings = Settings()
|
||||
# Set our data path
|
||||
data_path = os.path.abspath(os.path.join(application_path, '..', '..', 'Data',))
|
||||
log.info('Data path: {name}'.format(name=data_path))
|
||||
# Point to our data path
|
||||
portable_settings.setValue('advanced/data path', data_path)
|
||||
portable_settings.setValue('advanced/data path', str(data_path))
|
||||
portable_settings.setValue('advanced/is portable', True)
|
||||
portable_settings.sync()
|
||||
else:
|
||||
application.setApplicationName('OpenLP')
|
||||
set_up_logging(str(AppLocation.get_directory(AppLocation.CacheDir)))
|
||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||
Registry.create()
|
||||
Registry().register('application', application)
|
||||
Registry().set_flag('no_web_server', args.no_web_server)
|
||||
|
@ -64,7 +64,7 @@ def controller_text(request):
|
||||
elif current_item.is_image() and not frame.get('image', '') and Settings().value('api/thumbnails'):
|
||||
item['tag'] = str(index + 1)
|
||||
thumbnail_path = os.path.join('images', 'thumbnails', frame['title'])
|
||||
full_thumbnail_path = os.path.join(AppLocation.get_data_path(), thumbnail_path)
|
||||
full_thumbnail_path = str(AppLocation.get_data_path() / thumbnail_path)
|
||||
# Create thumbnail if it doesn't exists
|
||||
if not os.path.exists(full_thumbnail_path):
|
||||
create_thumb(current_item.get_frame_path(index), full_thumbnail_path, False)
|
||||
@ -82,7 +82,7 @@ def controller_text(request):
|
||||
if current_item.is_capable(ItemCapabilities.HasThumbnails) and \
|
||||
Settings().value('api/thumbnails'):
|
||||
# If the file is under our app directory tree send the portion after the match
|
||||
data_path = AppLocation.get_data_path()
|
||||
data_path = str(AppLocation.get_data_path())
|
||||
if frame['image'][0:len(data_path)] == data_path:
|
||||
item['img'] = urllib.request.pathname2url(frame['image'][len(data_path):])
|
||||
Registry().get('image_manager').add_image(frame['image'], frame['title'], None, 88, 88)
|
||||
|
@ -125,12 +125,9 @@ def display_thumbnails(request, controller_name, log, dimensions, file_name, sli
|
||||
file_name = urllib.parse.unquote(file_name)
|
||||
if '..' not in file_name: # no hacking please
|
||||
if slide:
|
||||
full_path = os.path.normpath(os.path.join(AppLocation.get_section_data_path(controller_name),
|
||||
'thumbnails', file_name, slide))
|
||||
full_path = str(AppLocation.get_section_data_path(controller_name) / 'thumbnails' / file_name / slide)
|
||||
else:
|
||||
full_path = os.path.normpath(os.path.join(AppLocation.get_section_data_path(controller_name),
|
||||
|
||||
'thumbnails', file_name))
|
||||
full_path = str(AppLocation.get_section_data_path(controller_name) / 'thumbnails' / file_name)
|
||||
if os.path.exists(full_path):
|
||||
path, just_file_name = os.path.split(full_path)
|
||||
Registry().get('image_manager').add_image(full_path, just_file_name, None, width, height)
|
||||
|
@ -68,11 +68,10 @@ class Endpoint(object):
|
||||
"""
|
||||
Render a mako template
|
||||
"""
|
||||
root = os.path.join(str(AppLocation.get_section_data_path('remotes')))
|
||||
root = str(AppLocation.get_section_data_path('remotes'))
|
||||
if not self.template_dir:
|
||||
raise Exception('No template directory specified')
|
||||
path = os.path.join(root, self.template_dir, filename)
|
||||
# path = os.path.abspath(os.path.join(self.template_dir, filename))
|
||||
if self.static_dir:
|
||||
kwargs['static_url'] = '/{prefix}/static'.format(prefix=self.url_prefix)
|
||||
kwargs['static_url'] = kwargs['static_url'].replace('//', '/')
|
||||
|
@ -138,8 +138,12 @@ class WSGIApplication(object):
|
||||
Add a static directory as a route
|
||||
"""
|
||||
if route not in self.static_routes:
|
||||
root = os.path.join(str(AppLocation.get_section_data_path('remotes')))
|
||||
self.static_routes[route] = DirectoryApp(os.path.abspath(os.path.join(root, static_dir)))
|
||||
root = str(AppLocation.get_section_data_path('remotes'))
|
||||
static_path = os.path.abspath(os.path.join(root, static_dir))
|
||||
if not os.path.exists(static_path):
|
||||
log.error('Static path "%s" does not exist. Skipping creating static route/', static_path)
|
||||
return
|
||||
self.static_routes[route] = DirectoryApp(static_path)
|
||||
|
||||
def dispatch(self, request):
|
||||
"""
|
||||
|
@ -32,7 +32,6 @@ import sys
|
||||
import traceback
|
||||
from chardet.universaldetector import UniversalDetector
|
||||
from ipaddress import IPv4Address, IPv6Address, AddressValueError
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
from subprocess import check_output, CalledProcessError, STDOUT
|
||||
|
||||
@ -65,17 +64,19 @@ def trace_error_handler(logger):
|
||||
|
||||
def check_directory_exists(directory, do_not_log=False):
|
||||
"""
|
||||
Check a theme directory exists and if not create it
|
||||
Check a directory exists and if not create it
|
||||
|
||||
:param directory: The directory to make sure exists
|
||||
:param do_not_log: To not log anything. This is need for the start up, when the log isn't ready.
|
||||
:param pathlib.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:
|
||||
log.debug('check_directory_exists {text}'.format(text=directory))
|
||||
try:
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
except IOError as e:
|
||||
if not directory.exists():
|
||||
directory.mkdir(parents=True)
|
||||
except IOError:
|
||||
if not do_not_log:
|
||||
log.exception('failed to check if directory exists or create directory')
|
||||
|
||||
@ -85,19 +86,15 @@ def extension_loader(glob_pattern, excluded_files=[]):
|
||||
A utility function to find and load OpenLP extensions, such as plugins, presentation and media controllers and
|
||||
importers.
|
||||
|
||||
:param glob_pattern: A glob pattern used to find the extension(s) to be imported. Should be relative to the
|
||||
application directory. i.e. openlp/plugins/*/*plugin.py
|
||||
:type glob_pattern: str
|
||||
|
||||
:param excluded_files: A list of file names to exclude that the glob pattern may find.
|
||||
:type excluded_files: list of strings
|
||||
|
||||
: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
|
||||
"""
|
||||
base_dir_path = AppLocation.get_directory(AppLocation.AppDir).parent
|
||||
for extension_path in base_dir_path.glob(glob_pattern):
|
||||
extension_path = extension_path.relative_to(base_dir_path)
|
||||
app_dir = AppLocation.get_directory(AppLocation.AppDir)
|
||||
for extension_path in app_dir.glob(glob_pattern):
|
||||
extension_path = extension_path.relative_to(app_dir)
|
||||
if extension_path.name in excluded_files:
|
||||
continue
|
||||
module_name = path_to_module(extension_path)
|
||||
@ -106,21 +103,19 @@ def extension_loader(glob_pattern, excluded_files=[]):
|
||||
except (ImportError, OSError):
|
||||
# On some platforms importing vlc.py might cause OSError exceptions. (e.g. Mac OS X)
|
||||
log.warning('Failed to import {module_name} on path {extension_path}'
|
||||
.format(module_name=module_name, extension_path=str(extension_path)))
|
||||
.format(module_name=module_name, extension_path=extension_path))
|
||||
|
||||
|
||||
def path_to_module(path):
|
||||
"""
|
||||
Convert a path to a module name (i.e openlp.core.common)
|
||||
|
||||
:param path: The path to convert to a module name.
|
||||
:type path: Path
|
||||
|
||||
:param pathlib.Path path: The path to convert to a module name.
|
||||
:return: The module name.
|
||||
:rtype: str
|
||||
"""
|
||||
module_path = path.with_suffix('')
|
||||
return '.'.join(module_path.parts)
|
||||
return 'openlp.' + '.'.join(module_path.parts)
|
||||
|
||||
|
||||
def get_frozen_path(frozen_option, non_frozen_option):
|
||||
@ -378,20 +373,22 @@ def split_filename(path):
|
||||
return os.path.split(path)
|
||||
|
||||
|
||||
def delete_file(file_path_name):
|
||||
def delete_file(file_path):
|
||||
"""
|
||||
Deletes a file from the system.
|
||||
|
||||
:param file_path_name: The file, including path, to delete.
|
||||
:param pathlib.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
|
||||
"""
|
||||
if not file_path_name:
|
||||
if not file_path:
|
||||
return False
|
||||
try:
|
||||
if os.path.exists(file_path_name):
|
||||
os.remove(file_path_name)
|
||||
if file_path.exists():
|
||||
file_path.unlink()
|
||||
return True
|
||||
except (IOError, OSError):
|
||||
log.exception("Unable to delete file {text}".format(text=file_path_name))
|
||||
log.exception('Unable to delete file {file_path}'.format(file_path=file_path))
|
||||
return False
|
||||
|
||||
|
||||
@ -411,18 +408,19 @@ def get_images_filter():
|
||||
return IMAGES_FILTER
|
||||
|
||||
|
||||
def is_not_image_file(file_name):
|
||||
def is_not_image_file(file_path):
|
||||
"""
|
||||
Validate that the file is not an image file.
|
||||
|
||||
:param file_name: File name to be checked.
|
||||
:param pathlib.Path file_path: The file to be checked.
|
||||
:return: If the file is not an image
|
||||
:rtype: bool
|
||||
"""
|
||||
if not file_name:
|
||||
if not (file_path and file_path.exists()):
|
||||
return True
|
||||
else:
|
||||
formats = [bytes(fmt).decode().lower() for fmt in QtGui.QImageReader.supportedImageFormats()]
|
||||
file_part, file_extension = os.path.splitext(str(file_name))
|
||||
if file_extension[1:].lower() in formats and os.path.exists(file_name):
|
||||
if file_path.suffix[1:].lower() in formats:
|
||||
return False
|
||||
return True
|
||||
|
||||
@ -431,10 +429,10 @@ def clean_filename(filename):
|
||||
"""
|
||||
Removes invalid characters from the given ``filename``.
|
||||
|
||||
:param filename: The "dirty" file name to clean.
|
||||
:param str filename: The "dirty" file name to clean.
|
||||
:return: The cleaned string
|
||||
:rtype: str
|
||||
"""
|
||||
if not isinstance(filename, str):
|
||||
filename = str(filename, 'utf-8')
|
||||
return INVALID_FILE_CHARS.sub('_', CONTROL_CHARS.sub('', filename))
|
||||
|
||||
|
||||
@ -442,8 +440,9 @@ def check_binary_exists(program_path):
|
||||
"""
|
||||
Function that checks whether a binary exists.
|
||||
|
||||
:param program_path: The full path to the binary to check.
|
||||
:param pathlib.Path program_path: The full path to the binary to check.
|
||||
:return: program output to be parsed
|
||||
:rtype: bytes
|
||||
"""
|
||||
log.debug('testing program_path: {text}'.format(text=program_path))
|
||||
try:
|
||||
@ -453,26 +452,27 @@ def check_binary_exists(program_path):
|
||||
startupinfo.dwFlags |= STARTF_USESHOWWINDOW
|
||||
else:
|
||||
startupinfo = None
|
||||
runlog = check_output([program_path, '--help'], stderr=STDOUT, startupinfo=startupinfo)
|
||||
run_log = check_output([str(program_path), '--help'], stderr=STDOUT, startupinfo=startupinfo)
|
||||
except CalledProcessError as e:
|
||||
runlog = e.output
|
||||
run_log = e.output
|
||||
except Exception:
|
||||
trace_error_handler(log)
|
||||
runlog = ''
|
||||
log.debug('check_output returned: {text}'.format(text=runlog))
|
||||
return runlog
|
||||
run_log = ''
|
||||
log.debug('check_output returned: {text}'.format(text=run_log))
|
||||
return run_log
|
||||
|
||||
|
||||
def get_file_encoding(filename):
|
||||
def get_file_encoding(file_path):
|
||||
"""
|
||||
Utility function to incrementally detect the file encoding.
|
||||
|
||||
:param filename: Filename for the file to determine the encoding for. Str
|
||||
:param pathlib.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]
|
||||
"""
|
||||
detector = UniversalDetector()
|
||||
try:
|
||||
with open(filename, 'rb') as detect_file:
|
||||
with file_path.open('rb') as detect_file:
|
||||
while not detector.done:
|
||||
chunk = detect_file.read(1024)
|
||||
if not chunk:
|
||||
|
@ -58,9 +58,6 @@ class AppLocation(object):
|
||||
CacheDir = 5
|
||||
LanguageDir = 6
|
||||
|
||||
# Base path where data/config/cache dir is located
|
||||
BaseDir = None
|
||||
|
||||
@staticmethod
|
||||
def get_directory(dir_type=AppDir):
|
||||
"""
|
||||
@ -78,8 +75,6 @@ class AppLocation(object):
|
||||
return get_frozen_path(FROZEN_APP_PATH, APP_PATH) / 'plugins'
|
||||
elif dir_type == AppLocation.LanguageDir:
|
||||
return get_frozen_path(FROZEN_APP_PATH, _get_os_dir_path(dir_type)) / 'i18n'
|
||||
elif dir_type == AppLocation.DataDir and AppLocation.BaseDir:
|
||||
return Path(AppLocation.BaseDir, 'data')
|
||||
else:
|
||||
return _get_os_dir_path(dir_type)
|
||||
|
||||
@ -96,7 +91,7 @@ class AppLocation(object):
|
||||
path = Path(Settings().value('advanced/data path'))
|
||||
else:
|
||||
path = AppLocation.get_directory(AppLocation.DataDir)
|
||||
check_directory_exists(str(path))
|
||||
check_directory_exists(path)
|
||||
return path
|
||||
|
||||
@staticmethod
|
||||
@ -104,14 +99,10 @@ class AppLocation(object):
|
||||
"""
|
||||
Get a list of files from the data files path.
|
||||
|
||||
:param section: Defaults to *None*. The section of code getting the files - used to load from a section's data
|
||||
subdirectory.
|
||||
:type section: None | str
|
||||
|
||||
:param extension: Defaults to ''. The extension to search for. For example::
|
||||
:param None | str section: Defaults to *None*. The section of code getting the files - used to load from a
|
||||
section's data subdirectory.
|
||||
:param str extension: Defaults to ''. The extension to search for. For example::
|
||||
'.png'
|
||||
:type extension: str
|
||||
|
||||
:return: List of files found.
|
||||
:rtype: list[pathlib.Path]
|
||||
"""
|
||||
@ -134,7 +125,7 @@ class AppLocation(object):
|
||||
:rtype: pathlib.Path
|
||||
"""
|
||||
path = AppLocation.get_data_path() / section
|
||||
check_directory_exists(str(path))
|
||||
check_directory_exists(path)
|
||||
return path
|
||||
|
||||
|
||||
@ -143,14 +134,12 @@ def _get_os_dir_path(dir_type):
|
||||
Return a path based on which OS and environment we are running in.
|
||||
|
||||
:param dir_type: AppLocation Enum of the requested path type
|
||||
:type dir_type: AppLocation Enum
|
||||
|
||||
:return: The requested path
|
||||
:rtype: pathlib.Path
|
||||
"""
|
||||
# If running from source, return the language directory from the source directory
|
||||
if dir_type == AppLocation.LanguageDir:
|
||||
directory = Path(os.path.abspath(os.path.join(os.path.dirname(openlp.__file__), '..', 'resources')))
|
||||
directory = Path(openlp.__file__, '..', '..').resolve() / 'resources'
|
||||
if directory.exists():
|
||||
return directory
|
||||
if is_win():
|
||||
@ -158,14 +147,14 @@ def _get_os_dir_path(dir_type):
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return openlp_folder_path / 'data'
|
||||
elif dir_type == AppLocation.LanguageDir:
|
||||
return os.path.dirname(openlp.__file__)
|
||||
return Path(openlp.__file__).parent
|
||||
return openlp_folder_path
|
||||
elif is_macosx():
|
||||
openlp_folder_path = Path(os.getenv('HOME'), 'Library', 'Application Support', 'openlp')
|
||||
if dir_type == AppLocation.DataDir:
|
||||
return openlp_folder_path / 'Data'
|
||||
elif dir_type == AppLocation.LanguageDir:
|
||||
return os.path.dirname(openlp.__file__)
|
||||
return Path(openlp.__file__).parent
|
||||
return openlp_folder_path
|
||||
else:
|
||||
if dir_type == AppLocation.LanguageDir:
|
||||
|
@ -502,31 +502,3 @@ class Settings(QtCore.QSettings):
|
||||
if isinstance(default_value, int):
|
||||
return int(setting)
|
||||
return setting
|
||||
|
||||
def get_files_from_config(self, plugin):
|
||||
"""
|
||||
This removes the settings needed for old way we saved files (e. g. the image paths for the image plugin). A list
|
||||
of file paths are returned.
|
||||
|
||||
**Note**: Only a list of paths is returned; this does not convert anything!
|
||||
|
||||
:param plugin: The Plugin object.The caller has to convert/save the list himself; o
|
||||
"""
|
||||
files_list = []
|
||||
# We need QSettings instead of Settings here to bypass our central settings dict.
|
||||
# Do NOT do this anywhere else!
|
||||
settings = QtCore.QSettings(self.fileName(), Settings.IniFormat)
|
||||
settings.beginGroup(plugin.settings_section)
|
||||
if settings.contains('{name} count'.format(name=plugin.name)):
|
||||
# Get the count.
|
||||
list_count = int(settings.value('{name} count'.format(name=plugin.name), 0))
|
||||
if list_count:
|
||||
for counter in range(list_count):
|
||||
# The keys were named e. g.: "image 0"
|
||||
item = settings.value('{name} {counter:d}'.format(name=plugin.name, counter=counter), '')
|
||||
if item:
|
||||
files_list.append(item)
|
||||
settings.remove('{name} {counter:d}'.format(name=plugin.name, counter=counter))
|
||||
settings.remove('{name} count'.format(name=plugin.name))
|
||||
settings.endGroup()
|
||||
return files_list
|
||||
|
@ -83,30 +83,28 @@ class ServiceItemAction(object):
|
||||
Next = 3
|
||||
|
||||
|
||||
def get_text_file_string(text_file):
|
||||
def get_text_file_string(text_file_path):
|
||||
"""
|
||||
Open a file and return its content as unicode string. If the supplied file name is not a file then the function
|
||||
Open a file and return its content as a string. If the supplied file path is not a file then the function
|
||||
returns False. If there is an error loading the file or the content can't be decoded then the function will return
|
||||
None.
|
||||
|
||||
:param text_file: The name of the file.
|
||||
:return: The file as a single string
|
||||
:param pathlib.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
|
||||
"""
|
||||
if not os.path.isfile(text_file):
|
||||
if not text_file_path.is_file():
|
||||
return False
|
||||
file_handle = None
|
||||
content = None
|
||||
try:
|
||||
file_handle = open(text_file, 'r', encoding='utf-8')
|
||||
with text_file_path.open('r', encoding='utf-8') as file_handle:
|
||||
if file_handle.read(3) != '\xEF\xBB\xBF':
|
||||
# no BOM was found
|
||||
file_handle.seek(0)
|
||||
content = file_handle.read()
|
||||
except (IOError, UnicodeError):
|
||||
log.exception('Failed to open text file {text}'.format(text=text_file))
|
||||
finally:
|
||||
if file_handle:
|
||||
file_handle.close()
|
||||
log.exception('Failed to open text file {text}'.format(text=text_file_path))
|
||||
return content
|
||||
|
||||
|
||||
|
@ -274,9 +274,9 @@ def delete_database(plugin_name, db_file_name=None):
|
||||
:param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used.
|
||||
"""
|
||||
if db_file_name:
|
||||
db_file_path = os.path.join(str(AppLocation.get_section_data_path(plugin_name)), db_file_name)
|
||||
db_file_path = AppLocation.get_section_data_path(plugin_name) / db_file_name
|
||||
else:
|
||||
db_file_path = os.path.join(str(AppLocation.get_section_data_path(plugin_name)), plugin_name)
|
||||
db_file_path = AppLocation.get_section_data_path(plugin_name) / plugin_name
|
||||
return delete_file(db_file_path)
|
||||
|
||||
|
||||
|
@ -69,7 +69,7 @@ class PluginManager(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
"""
|
||||
Scan a directory for objects inheriting from the ``Plugin`` class.
|
||||
"""
|
||||
glob_pattern = os.path.join('openlp', 'plugins', '*', '*plugin.py')
|
||||
glob_pattern = os.path.join('plugins', '*', '*plugin.py')
|
||||
extension_loader(glob_pattern)
|
||||
plugin_classes = Plugin.__subclasses__()
|
||||
plugin_objects = []
|
||||
|
@ -158,9 +158,8 @@ class Theme(object):
|
||||
Initialise the theme object.
|
||||
"""
|
||||
# basic theme object with defaults
|
||||
json_dir = os.path.join(str(AppLocation.get_directory(AppLocation.AppDir)), 'core', 'lib', 'json')
|
||||
json_file = os.path.join(json_dir, 'theme.json')
|
||||
jsn = get_text_file_string(json_file)
|
||||
json_path = AppLocation.get_directory(AppLocation.AppDir) / 'core' / 'lib' / 'json' / 'theme.json'
|
||||
jsn = get_text_file_string(json_path)
|
||||
jsn = json.loads(jsn)
|
||||
self.expand_json(jsn)
|
||||
self.background_filename = ''
|
||||
|
@ -29,8 +29,9 @@ import time
|
||||
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 configparser import ConfigParser, MissingSectionHeaderError, NoSectionError, NoOptionError
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
@ -282,7 +283,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
|
||||
self.no_internet_cancel_button.setVisible(False)
|
||||
# Check if this is a re-run of the wizard.
|
||||
self.has_run_wizard = Settings().value('core/has run wizard')
|
||||
check_directory_exists(os.path.join(gettempdir(), 'openlp'))
|
||||
check_directory_exists(Path(gettempdir(), 'openlp'))
|
||||
|
||||
def update_screen_list_combo(self):
|
||||
"""
|
||||
|
@ -30,6 +30,7 @@ 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
|
||||
@ -870,7 +871,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
|
||||
setting_sections.extend([plugin.name for plugin in self.plugin_manager.plugins])
|
||||
# Copy the settings file to the tmp dir, because we do not want to change the original one.
|
||||
temp_directory = os.path.join(str(gettempdir()), 'openlp')
|
||||
check_directory_exists(temp_directory)
|
||||
check_directory_exists(Path(temp_directory))
|
||||
temp_config = os.path.join(temp_directory, os.path.basename(import_file_name))
|
||||
shutil.copyfile(import_file_name, temp_config)
|
||||
settings = Settings()
|
||||
|
@ -177,7 +177,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties):
|
||||
Check to see if we have any media Player's available.
|
||||
"""
|
||||
log.debug('_check_available_media_players')
|
||||
controller_dir = os.path.join('openlp', 'core', 'ui', 'media')
|
||||
controller_dir = os.path.join('core', 'ui', 'media')
|
||||
glob_pattern = os.path.join(controller_dir, '*player.py')
|
||||
extension_loader(glob_pattern, ['mediaplayer.py'])
|
||||
player_classes = MediaPlayer.__subclasses__()
|
||||
|
@ -176,7 +176,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
|
||||
html_data = self._add_element('html')
|
||||
self._add_element('head', parent=html_data)
|
||||
self._add_element('title', self.title_line_edit.text(), html_data.head)
|
||||
css_path = os.path.join(str(AppLocation.get_data_path()), 'serviceprint', 'service_print.css')
|
||||
css_path = AppLocation.get_data_path() / 'serviceprint' / 'service_print.css'
|
||||
custom_css = get_text_file_string(css_path)
|
||||
if not custom_css:
|
||||
custom_css = DEFAULT_CSS
|
||||
|
@ -28,6 +28,7 @@ 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
|
||||
@ -587,7 +588,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
audio_from = os.path.join(self.service_path, audio_from)
|
||||
save_file = os.path.join(self.service_path, audio_to)
|
||||
save_path = os.path.split(save_file)[0]
|
||||
check_directory_exists(save_path)
|
||||
check_directory_exists(Path(save_path))
|
||||
if not os.path.exists(save_file):
|
||||
shutil.copy(audio_from, save_file)
|
||||
zip_file.write(audio_from, audio_to)
|
||||
@ -614,7 +615,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
success = False
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
self.set_modified(False)
|
||||
delete_file(temp_file_name)
|
||||
delete_file(Path(temp_file_name))
|
||||
return success
|
||||
|
||||
def save_local_file(self):
|
||||
@ -669,7 +670,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
return self.save_file_as()
|
||||
self.main_window.add_recent_file(path_file_name)
|
||||
self.set_modified(False)
|
||||
delete_file(temp_file_name)
|
||||
delete_file(Path(temp_file_name))
|
||||
return success
|
||||
|
||||
def save_file_as(self, field=None):
|
||||
@ -774,7 +775,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
self.set_file_name(file_name)
|
||||
self.main_window.display_progress_bar(len(items))
|
||||
self.process_service_items(items)
|
||||
delete_file(p_file)
|
||||
delete_file(Path(p_file))
|
||||
self.main_window.add_recent_file(file_name)
|
||||
self.set_modified(False)
|
||||
Settings().setValue('servicemanager/last file', file_name)
|
||||
@ -1343,7 +1344,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
|
||||
Empties the service_path of temporary files on system exit.
|
||||
"""
|
||||
for file_name in os.listdir(self.service_path):
|
||||
file_path = os.path.join(self.service_path, file_name)
|
||||
file_path = Path(self.service_path, file_name)
|
||||
delete_file(file_path)
|
||||
if os.path.exists(os.path.join(self.service_path, 'audio')):
|
||||
shutil.rmtree(os.path.join(self.service_path, 'audio'), True)
|
||||
|
@ -24,6 +24,7 @@ The Theme wizard
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
@ -188,7 +189,8 @@ class ThemeForm(QtWidgets.QWizard, Ui_ThemeWizard, RegistryProperties):
|
||||
"""
|
||||
background_image = BackgroundType.to_string(BackgroundType.Image)
|
||||
if self.page(self.currentId()) == self.background_page and \
|
||||
self.theme.background_type == background_image and is_not_image_file(self.theme.background_filename):
|
||||
self.theme.background_type == background_image and \
|
||||
is_not_image_file(Path(self.theme.background_filename)):
|
||||
QtWidgets.QMessageBox.critical(self, translate('OpenLP.ThemeWizard', 'Background Image Empty'),
|
||||
translate('OpenLP.ThemeWizard', 'You have not selected a '
|
||||
'background image. Please select one before continuing.'))
|
||||
|
@ -25,6 +25,7 @@ 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
|
||||
@ -161,9 +162,9 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
Set up the theme path variables
|
||||
"""
|
||||
self.path = str(AppLocation.get_section_data_path(self.settings_section))
|
||||
check_directory_exists(self.path)
|
||||
check_directory_exists(Path(self.path))
|
||||
self.thumb_path = os.path.join(self.path, 'thumbnails')
|
||||
check_directory_exists(self.thumb_path)
|
||||
check_directory_exists(Path(self.thumb_path))
|
||||
|
||||
def check_list_state(self, item, field=None):
|
||||
"""
|
||||
@ -355,8 +356,8 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
"""
|
||||
self.theme_list.remove(theme)
|
||||
thumb = '{name}.png'.format(name=theme)
|
||||
delete_file(os.path.join(self.path, thumb))
|
||||
delete_file(os.path.join(self.thumb_path, thumb))
|
||||
delete_file(Path(self.path, thumb))
|
||||
delete_file(Path(self.thumb_path, thumb))
|
||||
try:
|
||||
# Windows is always unicode, so no need to encode filenames
|
||||
if is_win():
|
||||
@ -450,7 +451,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
for theme_file in files:
|
||||
theme_file = os.path.join(self.path, str(theme_file))
|
||||
self.unzip_theme(theme_file, self.path)
|
||||
delete_file(theme_file)
|
||||
delete_file(Path(theme_file))
|
||||
files = AppLocation.get_files(self.settings_section, '.png')
|
||||
# No themes have been found so create one
|
||||
if not files:
|
||||
@ -514,12 +515,12 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
:return: The theme object.
|
||||
"""
|
||||
self.log_debug('get theme data for theme {name}'.format(name=theme_name))
|
||||
theme_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.json')
|
||||
theme_data = get_text_file_string(theme_file)
|
||||
theme_file_path = Path(self.path, str(theme_name), '{file_name}.json'.format(file_name=theme_name))
|
||||
theme_data = get_text_file_string(theme_file_path)
|
||||
jsn = True
|
||||
if not theme_data:
|
||||
theme_file = os.path.join(self.path, str(theme_name), str(theme_name) + '.xml')
|
||||
theme_data = get_text_file_string(theme_file)
|
||||
theme_file_path = theme_file_path.with_suffix('.xml')
|
||||
theme_data = get_text_file_string(theme_file_path)
|
||||
jsn = False
|
||||
if not theme_data:
|
||||
self.log_debug('No theme data - using default theme')
|
||||
@ -592,7 +593,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
# is directory or preview file
|
||||
continue
|
||||
full_name = os.path.join(directory, out_name)
|
||||
check_directory_exists(os.path.dirname(full_name))
|
||||
check_directory_exists(Path(os.path.dirname(full_name)))
|
||||
if os.path.splitext(name)[1].lower() == '.xml' or os.path.splitext(name)[1].lower() == '.json':
|
||||
file_xml = str(theme_zip.read(name), 'utf-8')
|
||||
out_file = open(full_name, 'w', encoding='utf-8')
|
||||
@ -670,10 +671,10 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ThemeManage
|
||||
name = theme.theme_name
|
||||
theme_pretty = theme.export_theme()
|
||||
theme_dir = os.path.join(self.path, name)
|
||||
check_directory_exists(theme_dir)
|
||||
check_directory_exists(Path(theme_dir))
|
||||
theme_file = os.path.join(theme_dir, name + '.json')
|
||||
if self.old_background_image and image_to != self.old_background_image:
|
||||
delete_file(self.old_background_image)
|
||||
delete_file(Path(self.old_background_image))
|
||||
out_file = None
|
||||
try:
|
||||
out_file = open(theme_file, 'w', encoding='utf-8')
|
||||
|
@ -51,6 +51,7 @@ 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.lib.exceptions import ValidationError
|
||||
@ -100,7 +101,7 @@ class CSVBible(BibleImport):
|
||||
:return: An iterable yielding namedtuples of type results_tuple
|
||||
"""
|
||||
try:
|
||||
encoding = get_file_encoding(filename)['encoding']
|
||||
encoding = get_file_encoding(Path(filename))['encoding']
|
||||
with open(filename, 'r', encoding=encoding, newline='') as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=',', quotechar='"')
|
||||
return [results_tuple(*line) for line in csv_reader]
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from openlp.core.common import AppLocation, OpenLPMixin, RegistryProperties, Settings, translate, delete_file, UiStrings
|
||||
from openlp.plugins.bibles.lib import LanguageSelection, parse_reference
|
||||
@ -137,7 +138,7 @@ class BibleManager(OpenLPMixin, RegistryProperties):
|
||||
# Remove corrupted files.
|
||||
if name is None:
|
||||
bible.session.close_all()
|
||||
delete_file(os.path.join(self.path, filename))
|
||||
delete_file(Path(self.path, filename))
|
||||
continue
|
||||
log.debug('Bible Name: "{name}"'.format(name=name))
|
||||
self.db_cache[name] = bible
|
||||
@ -185,7 +186,7 @@ class BibleManager(OpenLPMixin, RegistryProperties):
|
||||
bible = self.db_cache[name]
|
||||
bible.session.close_all()
|
||||
bible.session = None
|
||||
return delete_file(os.path.join(bible.path, bible.file))
|
||||
return delete_file(Path(bible.path, bible.file))
|
||||
|
||||
def get_bibles(self):
|
||||
"""
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
@ -99,7 +100,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
self.list_view.setIndentation(self.list_view.default_indentation)
|
||||
self.list_view.allow_internal_dnd = True
|
||||
self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails')
|
||||
check_directory_exists(self.service_path)
|
||||
check_directory_exists(Path(self.service_path))
|
||||
# Load images from the database
|
||||
self.load_full_list(
|
||||
self.manager.get_all_objects(ImageFilenames, order_by_ref=ImageFilenames.filename), initial_load=True)
|
||||
@ -210,8 +211,8 @@ class ImageMediaItem(MediaManagerItem):
|
||||
"""
|
||||
images = self.manager.get_all_objects(ImageFilenames, ImageFilenames.group_id == image_group.id)
|
||||
for image in images:
|
||||
delete_file(os.path.join(self.service_path, os.path.split(image.filename)[1]))
|
||||
delete_file(self.generate_thumbnail_path(image))
|
||||
delete_file(Path(self.service_path, os.path.split(image.filename)[1]))
|
||||
delete_file(Path(self.generate_thumbnail_path(image)))
|
||||
self.manager.delete_object(ImageFilenames, image.id)
|
||||
image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == image_group.id)
|
||||
for group in image_groups:
|
||||
@ -233,8 +234,8 @@ class ImageMediaItem(MediaManagerItem):
|
||||
if row_item:
|
||||
item_data = row_item.data(0, QtCore.Qt.UserRole)
|
||||
if isinstance(item_data, ImageFilenames):
|
||||
delete_file(os.path.join(self.service_path, row_item.text(0)))
|
||||
delete_file(self.generate_thumbnail_path(item_data))
|
||||
delete_file(Path(self.service_path, row_item.text(0)))
|
||||
delete_file(Path(self.generate_thumbnail_path(item_data)))
|
||||
if item_data.group_id == 0:
|
||||
self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item))
|
||||
else:
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
@ -301,7 +302,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
"""
|
||||
self.list_view.clear()
|
||||
self.service_path = os.path.join(str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails')
|
||||
check_directory_exists(self.service_path)
|
||||
check_directory_exists(Path(self.service_path))
|
||||
self.load_list(Settings().value(self.settings_section + '/media files'))
|
||||
self.rebuild_players()
|
||||
|
||||
|
@ -26,6 +26,7 @@ The Media plugin
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
@ -165,8 +166,7 @@ def process_check_binary(program_path):
|
||||
:param program_path:The full path to the binary to check.
|
||||
:return: If exists or not
|
||||
"""
|
||||
program_type = None
|
||||
runlog = check_binary_exists(program_path)
|
||||
runlog = check_binary_exists(Path(program_path))
|
||||
# Analyse the output to see it the program is mediainfo
|
||||
for line in runlog.splitlines():
|
||||
decoded_line = line.decode()
|
||||
|
@ -34,6 +34,7 @@
|
||||
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
|
||||
|
||||
@ -275,7 +276,7 @@ class ImpressDocument(PresentationDocument):
|
||||
try:
|
||||
doc.storeToURL(url_path, properties)
|
||||
self.convert_thumbnail(path, index + 1)
|
||||
delete_file(path)
|
||||
delete_file(Path(path))
|
||||
except ErrorCodeIOException as exception:
|
||||
log.exception('ERROR! ErrorCodeIOException {error:d}'.format(error=exception.ErrCode))
|
||||
except:
|
||||
|
@ -23,6 +23,7 @@
|
||||
import os
|
||||
import logging
|
||||
import re
|
||||
from pathlib import Path
|
||||
from shutil import which
|
||||
from subprocess import check_output, CalledProcessError
|
||||
|
||||
@ -69,7 +70,7 @@ class PdfController(PresentationController):
|
||||
:return: Type of the binary, 'gs' if ghostscript, 'mudraw' if mudraw, None if invalid.
|
||||
"""
|
||||
program_type = None
|
||||
runlog = check_binary_exists(program_path)
|
||||
runlog = check_binary_exists(Path(program_path))
|
||||
# Analyse the output to see it the program is mudraw, ghostscript or neither
|
||||
for line in runlog.splitlines():
|
||||
decoded_line = line.decode()
|
||||
|
@ -23,6 +23,7 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
@ -98,7 +99,7 @@ class PresentationDocument(object):
|
||||
"""
|
||||
self.slide_number = 0
|
||||
self.file_path = name
|
||||
check_directory_exists(self.get_thumbnail_folder())
|
||||
check_directory_exists(Path(self.get_thumbnail_folder()))
|
||||
|
||||
def load_presentation(self):
|
||||
"""
|
||||
@ -419,8 +420,8 @@ class PresentationController(object):
|
||||
self.thumbnail_folder = os.path.join(
|
||||
str(AppLocation.get_section_data_path(self.settings_section)), 'thumbnails')
|
||||
self.thumbnail_prefix = 'slide'
|
||||
check_directory_exists(self.thumbnail_folder)
|
||||
check_directory_exists(self.temp_folder)
|
||||
check_directory_exists(Path(self.thumbnail_folder))
|
||||
check_directory_exists(Path(self.temp_folder))
|
||||
|
||||
def enabled(self):
|
||||
"""
|
||||
|
@ -125,7 +125,7 @@ class PresentationPlugin(Plugin):
|
||||
Check to see if we have any presentation software available. If not do not install the plugin.
|
||||
"""
|
||||
log.debug('check_pre_conditions')
|
||||
controller_dir = os.path.join('openlp', 'plugins', 'presentations', 'lib')
|
||||
controller_dir = os.path.join('plugins', 'presentations', 'lib')
|
||||
glob_pattern = os.path.join(controller_dir, '*controller.py')
|
||||
extension_loader(glob_pattern, ['presentationcontroller.py'])
|
||||
controller_classes = PresentationController.__subclasses__()
|
||||
|
@ -59,21 +59,22 @@ class RemotesPlugin(Plugin, OpenLPMixin):
|
||||
Create the internal file structure if it does not exist
|
||||
:return:
|
||||
"""
|
||||
check_directory_exists(os.path.join(AppLocation.get_section_data_path('remotes'), 'assets'))
|
||||
check_directory_exists(os.path.join(AppLocation.get_section_data_path('remotes'), 'images'))
|
||||
check_directory_exists(os.path.join(AppLocation.get_section_data_path('remotes'), 'static'))
|
||||
check_directory_exists(os.path.join(AppLocation.get_section_data_path('remotes'), 'static', 'index'))
|
||||
check_directory_exists(os.path.join(AppLocation.get_section_data_path('remotes'), 'templates'))
|
||||
check_directory_exists(AppLocation.get_section_data_path('remotes') / 'assets')
|
||||
check_directory_exists(AppLocation.get_section_data_path('remotes') / 'images')
|
||||
check_directory_exists(AppLocation.get_section_data_path('remotes') / 'static')
|
||||
check_directory_exists(AppLocation.get_section_data_path('remotes') / 'static', 'index')
|
||||
check_directory_exists(AppLocation.get_section_data_path('remotes') / 'templates')
|
||||
|
||||
@staticmethod
|
||||
def about():
|
||||
"""
|
||||
Information about this plugin
|
||||
"""
|
||||
about_text = translate('RemotePlugin', '<strong>Web Interface</strong>'
|
||||
'<br />The web interface plugin provides the ability develop web based '
|
||||
'interfaces using openlp web services. \nPredefined interfaces can be '
|
||||
'download as well as custom developed interfaces')
|
||||
about_text = translate(
|
||||
'RemotePlugin',
|
||||
'<strong>Web Interface</strong>'
|
||||
'<br />The web interface plugin provides the ability to develop web based interfaces using OpenLP web '
|
||||
'services.\nPredefined interfaces can be download as well as custom developed interfaces.')
|
||||
return about_text
|
||||
|
||||
def set_plugin_text_strings(self):
|
||||
|
@ -1071,7 +1071,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
|
||||
log.debug(audio_files)
|
||||
save_path = os.path.join(str(AppLocation.get_section_data_path(self.media_item.plugin.name)), 'audio',
|
||||
str(self.song.id))
|
||||
check_directory_exists(save_path)
|
||||
check_directory_exists(Path(save_path))
|
||||
self.song.media_files = []
|
||||
files = []
|
||||
for row in range(self.audio_list_widget.count()):
|
||||
|
@ -27,6 +27,7 @@ import os
|
||||
import re
|
||||
import base64
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
from openlp.plugins.songs.lib import VerseType
|
||||
from openlp.plugins.songs.lib.importers.songimport import SongImport
|
||||
@ -122,7 +123,7 @@ class SongBeamerImport(SongImport):
|
||||
file_name = os.path.split(import_file)[1]
|
||||
if os.path.isfile(import_file):
|
||||
# Detect the encoding
|
||||
self.input_file_encoding = get_file_encoding(import_file)['encoding']
|
||||
self.input_file_encoding = get_file_encoding(Path(import_file))['encoding']
|
||||
# The encoding should only be ANSI (cp1252), UTF-8, Unicode, Big-Endian-Unicode.
|
||||
# So if it doesn't start with 'u' we default to cp1252. See:
|
||||
# https://forum.songbeamer.com/viewtopic.php?p=419&sid=ca4814924e37c11e4438b7272a98b6f2
|
||||
|
@ -24,6 +24,7 @@ import logging
|
||||
import re
|
||||
import shutil
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore
|
||||
|
||||
@ -423,7 +424,7 @@ class SongImport(QtCore.QObject):
|
||||
if not hasattr(self, 'save_path'):
|
||||
self.save_path = os.path.join(str(AppLocation.get_section_data_path(self.import_wizard.plugin.name)),
|
||||
'audio', str(song_id))
|
||||
check_directory_exists(self.save_path)
|
||||
check_directory_exists(Path(self.save_path))
|
||||
if not filename.startswith(self.save_path):
|
||||
old_file, filename = filename, os.path.join(self.save_path, os.path.split(filename)[1])
|
||||
shutil.copyfile(old_file, filename)
|
||||
|
@ -23,6 +23,7 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from sqlalchemy.sql import and_, or_
|
||||
@ -89,7 +90,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
for i, bga in enumerate(item.background_audio):
|
||||
dest_file = os.path.join(
|
||||
str(AppLocation.get_section_data_path(self.plugin.name)), 'audio', str(song.id), os.path.split(bga)[1])
|
||||
check_directory_exists(os.path.split(dest_file)[0])
|
||||
check_directory_exists(Path(os.path.split(dest_file)[0]))
|
||||
shutil.copyfile(os.path.join(str(AppLocation.get_section_data_path('servicemanager')), bga), dest_file)
|
||||
song.media_files.append(MediaFile.populate(weight=i, file_name=dest_file))
|
||||
self.plugin.manager.save_object(song, True)
|
||||
@ -535,7 +536,7 @@ class SongMediaItem(MediaManagerItem):
|
||||
if len(old_song.media_files) > 0:
|
||||
save_path = os.path.join(
|
||||
str(AppLocation.get_section_data_path(self.plugin.name)), 'audio', str(new_song.id))
|
||||
check_directory_exists(save_path)
|
||||
check_directory_exists(Path(save_path))
|
||||
for media_file in old_song.media_files:
|
||||
new_media_file_name = os.path.join(save_path, os.path.basename(media_file.file_name))
|
||||
shutil.copyfile(media_file.file_name, new_media_file_name)
|
||||
|
@ -25,6 +25,7 @@ format.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from lxml import etree
|
||||
|
||||
@ -47,7 +48,7 @@ class OpenLyricsExport(RegistryProperties):
|
||||
self.manager = parent.plugin.manager
|
||||
self.songs = songs
|
||||
self.save_path = save_path
|
||||
check_directory_exists(self.save_path)
|
||||
check_directory_exists(Path(self.save_path))
|
||||
|
||||
def do_export(self):
|
||||
"""
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from sqlalchemy.sql import and_
|
||||
@ -78,7 +79,7 @@ class SongUsageDetailForm(QtWidgets.QDialog, Ui_SongUsageDetailDialog, RegistryP
|
||||
' song usage report. \nPlease select an existing path on your computer.')
|
||||
)
|
||||
return
|
||||
check_directory_exists(path)
|
||||
check_directory_exists(Path(path))
|
||||
file_name = translate('SongUsagePlugin.SongUsageDetailForm',
|
||||
'usage_detail_{old}_{new}.txt'
|
||||
).format(old=self.from_date_calendar.selectedDate().toString('ddMMyyyy'),
|
||||
|
@ -12,7 +12,7 @@ environment:
|
||||
|
||||
install:
|
||||
# Install dependencies from pypi
|
||||
- "%PYTHON%\\python.exe -m pip install sqlalchemy alembic chardet beautifulsoup4 Mako nose mock pyodbc==4.0.8 psycopg2 pypiwin32 pyenchant"
|
||||
- "%PYTHON%\\python.exe -m pip install sqlalchemy alembic chardet beautifulsoup4 Mako nose mock pyodbc==4.0.8 psycopg2 pypiwin32 pyenchant websockets asyncio waitress six webob"
|
||||
# Install mysql dependency
|
||||
- "%PYTHON%\\python.exe -m pip install http://cdn.mysql.com/Downloads/Connector-Python/mysql-connector-python-2.0.4.zip#md5=3df394d89300db95163f17c843ef49df"
|
||||
# Download and install lxml and pyicu (originally from http://www.lfd.uci.edu/~gohlke/pythonlibs/)
|
||||
|
@ -43,14 +43,12 @@ class TestAppLocation(TestCase):
|
||||
"""
|
||||
with patch('openlp.core.common.applocation.Settings') as mocked_class, \
|
||||
patch('openlp.core.common.AppLocation.get_directory') as mocked_get_directory, \
|
||||
patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists, \
|
||||
patch('openlp.core.common.applocation.os') as mocked_os:
|
||||
patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists:
|
||||
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
|
||||
mocked_settings = mocked_class.return_value
|
||||
mocked_settings.contains.return_value = False
|
||||
mocked_get_directory.return_value = os.path.join('test', 'dir')
|
||||
mocked_get_directory.return_value = Path('test', 'dir')
|
||||
mocked_check_directory_exists.return_value = True
|
||||
mocked_os.path.normpath.return_value = os.path.join('test', 'dir')
|
||||
|
||||
# WHEN: we call AppLocation.get_data_path()
|
||||
data_path = AppLocation.get_data_path()
|
||||
@ -58,8 +56,8 @@ class TestAppLocation(TestCase):
|
||||
# THEN: check that all the correct methods were called, and the result is correct
|
||||
mocked_settings.contains.assert_called_with('advanced/data path')
|
||||
mocked_get_directory.assert_called_with(AppLocation.DataDir)
|
||||
mocked_check_directory_exists.assert_called_with(os.path.join('test', 'dir'))
|
||||
self.assertEqual(os.path.join('test', 'dir'), data_path, 'Result should be "test/dir"')
|
||||
mocked_check_directory_exists.assert_called_with(Path('test', 'dir'))
|
||||
self.assertEqual(Path('test', 'dir'), data_path, 'Result should be "test/dir"')
|
||||
|
||||
def test_get_data_path_with_custom_location(self):
|
||||
"""
|
||||
@ -125,7 +123,7 @@ class TestAppLocation(TestCase):
|
||||
data_path = AppLocation.get_section_data_path('section')
|
||||
|
||||
# THEN: check that all the correct methods were called, and the result is correct
|
||||
mocked_check_directory_exists.assert_called_with(os.path.join('test', 'dir', 'section'))
|
||||
mocked_check_directory_exists.assert_called_with(Path('test', 'dir', 'section'))
|
||||
self.assertEqual(Path('test', 'dir', 'section'), data_path, 'Result should be "test/dir/section"')
|
||||
|
||||
def test_get_directory_for_app_dir(self):
|
||||
|
@ -35,44 +35,70 @@ class TestCommonFunctions(TestCase):
|
||||
"""
|
||||
A test suite to test out various functions in the openlp.core.common module.
|
||||
"""
|
||||
def test_check_directory_exists(self):
|
||||
def test_check_directory_exists_dir_exists(self):
|
||||
"""
|
||||
Test the check_directory_exists() function
|
||||
Test the check_directory_exists() function when the path already exists
|
||||
"""
|
||||
with patch('openlp.core.lib.os.path.exists') as mocked_exists, \
|
||||
patch('openlp.core.lib.os.makedirs') as mocked_makedirs:
|
||||
# GIVEN: A directory to check and a mocked out os.makedirs and os.path.exists
|
||||
directory_to_check = 'existing/directory'
|
||||
# GIVEN: A `Path` to check with patched out mkdir and exists methods
|
||||
with patch.object(Path, 'exists') as mocked_exists, \
|
||||
patch.object(Path, 'mkdir') as mocked_mkdir, \
|
||||
patch('openlp.core.common.log'):
|
||||
|
||||
# WHEN: os.path.exists returns True and we check to see if the directory exists
|
||||
# WHEN: `check_directory_exists` is called and the path exists
|
||||
mocked_exists.return_value = True
|
||||
check_directory_exists(directory_to_check)
|
||||
check_directory_exists(Path('existing', 'directory'))
|
||||
|
||||
# THEN: Only os.path.exists should have been called
|
||||
mocked_exists.assert_called_with(directory_to_check)
|
||||
self.assertIsNot(mocked_makedirs.called, 'os.makedirs should not have been called')
|
||||
# THEN: The function should not attempt to create the directory
|
||||
mocked_exists.assert_called_with()
|
||||
self.assertFalse(mocked_mkdir.called)
|
||||
|
||||
# WHEN: os.path.exists returns False and we check the directory exists
|
||||
def test_check_directory_exists_dir_doesnt_exists(self):
|
||||
"""
|
||||
Test the check_directory_exists() function when the path does not already exist
|
||||
"""
|
||||
# GIVEN: A `Path` to check with patched out mkdir and exists methods
|
||||
with patch.object(Path, 'exists') as mocked_exists, \
|
||||
patch.object(Path, 'mkdir') as mocked_mkdir, \
|
||||
patch('openlp.core.common.log'):
|
||||
|
||||
# WHEN: `check_directory_exists` is called and the path does not exist
|
||||
mocked_exists.return_value = False
|
||||
check_directory_exists(directory_to_check)
|
||||
check_directory_exists(Path('existing', 'directory'))
|
||||
|
||||
# THEN: Both the mocked functions should have been called
|
||||
mocked_exists.assert_called_with(directory_to_check)
|
||||
mocked_makedirs.assert_called_with(directory_to_check)
|
||||
# THEN: The directory should have been created
|
||||
mocked_exists.assert_called_with()
|
||||
mocked_mkdir.assert_called_with(parents=True)
|
||||
|
||||
# WHEN: os.path.exists raises an IOError
|
||||
def test_check_directory_exists_dir_io_error(self):
|
||||
"""
|
||||
Test the check_directory_exists() when an IOError is raised
|
||||
"""
|
||||
# GIVEN: A `Path` to check with patched out mkdir and exists methods
|
||||
with patch.object(Path, 'exists') as mocked_exists, \
|
||||
patch.object(Path, 'mkdir'), \
|
||||
patch('openlp.core.common.log') as mocked_logger:
|
||||
|
||||
# WHEN: An IOError is raised when checking the if the path exists.
|
||||
mocked_exists.side_effect = IOError()
|
||||
check_directory_exists(directory_to_check)
|
||||
check_directory_exists(Path('existing', 'directory'))
|
||||
|
||||
# THEN: We shouldn't get an exception though the mocked exists has been called
|
||||
mocked_exists.assert_called_with(directory_to_check)
|
||||
# THEN: The Error should have been logged
|
||||
mocked_logger.exception.assert_called_once_with('failed to check if directory exists or create directory')
|
||||
|
||||
def test_check_directory_exists_dir_value_error(self):
|
||||
"""
|
||||
Test the check_directory_exists() when an error other than IOError is raised
|
||||
"""
|
||||
# GIVEN: A `Path` to check with patched out mkdir and exists methods
|
||||
with patch.object(Path, 'exists') as mocked_exists, \
|
||||
patch.object(Path, 'mkdir'), \
|
||||
patch('openlp.core.common.log'):
|
||||
|
||||
# WHEN: Some other exception is raised
|
||||
mocked_exists.side_effect = ValueError()
|
||||
|
||||
# THEN: check_directory_exists raises an exception
|
||||
mocked_exists.assert_called_with(directory_to_check)
|
||||
self.assertRaises(ValueError, check_directory_exists, directory_to_check)
|
||||
# THEN: `check_directory_exists` raises an exception
|
||||
self.assertRaises(ValueError, check_directory_exists, Path('existing', 'directory'))
|
||||
|
||||
def test_extension_loader_no_files_found(self):
|
||||
"""
|
||||
@ -80,7 +106,7 @@ class TestCommonFunctions(TestCase):
|
||||
"""
|
||||
# GIVEN: A mocked `Path.glob` method which does not match any files
|
||||
with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \
|
||||
patch.object(common.Path, 'glob', return_value=[]), \
|
||||
patch.object(Path, 'glob', return_value=[]), \
|
||||
patch('openlp.core.common.importlib.import_module') as mocked_import_module:
|
||||
|
||||
# WHEN: Calling `extension_loader`
|
||||
@ -95,7 +121,7 @@ class TestCommonFunctions(TestCase):
|
||||
"""
|
||||
# GIVEN: A mocked `Path.glob` method which returns a list of files
|
||||
with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \
|
||||
patch.object(common.Path, 'glob', return_value=[
|
||||
patch.object(Path, 'glob', return_value=[
|
||||
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py'),
|
||||
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file2.py'),
|
||||
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file3.py'),
|
||||
@ -115,7 +141,7 @@ class TestCommonFunctions(TestCase):
|
||||
"""
|
||||
# GIVEN: A mocked `import_module` which raises an `ImportError`
|
||||
with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \
|
||||
patch.object(common.Path, 'glob', return_value=[
|
||||
patch.object(Path, 'glob', return_value=[
|
||||
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \
|
||||
patch('openlp.core.common.importlib.import_module', side_effect=ImportError()), \
|
||||
patch('openlp.core.common.log') as mocked_logger:
|
||||
@ -132,7 +158,7 @@ class TestCommonFunctions(TestCase):
|
||||
"""
|
||||
# GIVEN: A mocked `SourceFileLoader` which raises an `OSError`
|
||||
with patch('openlp.core.common.AppLocation.get_directory', return_value=Path('/', 'app', 'dir', 'openlp')), \
|
||||
patch.object(common.Path, 'glob', return_value=[
|
||||
patch.object(Path, 'glob', return_value=[
|
||||
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \
|
||||
patch('openlp.core.common.importlib.import_module', side_effect=OSError()), \
|
||||
patch('openlp.core.common.log') as mocked_logger:
|
||||
@ -174,7 +200,7 @@ class TestCommonFunctions(TestCase):
|
||||
Test `path_to_module` when supplied with a `Path` object
|
||||
"""
|
||||
# GIVEN: A `Path` object
|
||||
path = Path('openlp/core/ui/media/webkitplayer.py')
|
||||
path = Path('core', 'ui', 'media', 'webkitplayer.py')
|
||||
|
||||
# WHEN: Calling path_to_module with the `Path` object
|
||||
result = path_to_module(path)
|
||||
|
@ -24,6 +24,7 @@ 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
|
||||
|
||||
@ -296,10 +297,10 @@ class TestInit(TestCase, TestMixin):
|
||||
"""
|
||||
# GIVEN: A blank path
|
||||
# WEHN: Calling delete_file
|
||||
result = delete_file('')
|
||||
result = delete_file(None)
|
||||
|
||||
# THEN: delete_file should return False
|
||||
self.assertFalse(result, "delete_file should return False when called with ''")
|
||||
self.assertFalse(result, "delete_file should return False when called with None")
|
||||
|
||||
def test_delete_file_path_success(self):
|
||||
"""
|
||||
@ -309,84 +310,87 @@ class TestInit(TestCase, TestMixin):
|
||||
with patch('openlp.core.common.os', **{'path.exists.return_value': False}):
|
||||
|
||||
# WHEN: Calling delete_file with a file path
|
||||
result = delete_file('path/file.ext')
|
||||
result = delete_file(Path('path', 'file.ext'))
|
||||
|
||||
# THEN: delete_file should return True
|
||||
self.assertTrue(result, 'delete_file should return True when it successfully deletes a file')
|
||||
|
||||
def test_delete_file_path_no_file_exists(self):
|
||||
"""
|
||||
Test the delete_file function when the file to remove does not exist
|
||||
Test the `delete_file` function when the file to remove does not exist
|
||||
"""
|
||||
# GIVEN: A mocked os which returns False when os.path.exists is called
|
||||
with patch('openlp.core.common.os', **{'path.exists.return_value': False}):
|
||||
# GIVEN: A patched `exists` methods on the Path object, which returns False
|
||||
with patch.object(Path, 'exists', return_value=False), \
|
||||
patch.object(Path, 'unlink') as mocked_unlink:
|
||||
|
||||
# WHEN: Calling delete_file with a file path
|
||||
result = delete_file('path/file.ext')
|
||||
# WHEN: Calling `delete_file with` a file path
|
||||
result = delete_file(Path('path', 'file.ext'))
|
||||
|
||||
# THEN: delete_file should return True
|
||||
# THEN: The function should not attempt to delete the file and it should return True
|
||||
self.assertFalse(mocked_unlink.called)
|
||||
self.assertTrue(result, 'delete_file should return True when the file doesnt exist')
|
||||
|
||||
def test_delete_file_path_exception(self):
|
||||
"""
|
||||
Test the delete_file function when os.remove raises an exception
|
||||
Test the delete_file function when an exception is raised
|
||||
"""
|
||||
# GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is
|
||||
# GIVEN: A test `Path` object with a patched exists method which raises an OSError
|
||||
# called.
|
||||
with patch('openlp.core.common.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \
|
||||
with patch.object(Path, 'exists') as mocked_exists, \
|
||||
patch('openlp.core.common.log') as mocked_log:
|
||||
mocked_exists.side_effect = OSError
|
||||
|
||||
# WHEN: Calling delete_file with a file path
|
||||
result = delete_file('path/file.ext')
|
||||
# WHEN: Calling delete_file with a the test Path object
|
||||
result = delete_file(Path('path', 'file.ext'))
|
||||
|
||||
# THEN: delete_file should log and exception and return False
|
||||
self.assertEqual(mocked_log.exception.call_count, 1)
|
||||
self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError')
|
||||
# THEN: The exception should be logged and `delete_file` should return False
|
||||
self.assertTrue(mocked_log.exception.called)
|
||||
self.assertFalse(result, 'delete_file should return False when an OSError is raised')
|
||||
|
||||
def test_get_file_name_encoding_done_test(self):
|
||||
def test_get_file_encoding_done_test(self):
|
||||
"""
|
||||
Test get_file_encoding when the detector sets done to True
|
||||
"""
|
||||
# GIVEN: A mocked UniversalDetector instance with done attribute set to True after first iteration
|
||||
with patch('openlp.core.common.UniversalDetector') as mocked_universal_detector, \
|
||||
patch('builtins.open', return_value=BytesIO(b"data" * 260)) as mocked_open:
|
||||
patch.object(Path, 'open', return_value=BytesIO(b"data" * 260)) as mocked_open:
|
||||
encoding_result = {'encoding': 'UTF-8', 'confidence': 0.99}
|
||||
mocked_universal_detector_inst = MagicMock(result=encoding_result)
|
||||
type(mocked_universal_detector_inst).done = PropertyMock(side_effect=[False, True])
|
||||
mocked_universal_detector.return_value = mocked_universal_detector_inst
|
||||
|
||||
# WHEN: Calling get_file_encoding
|
||||
result = get_file_encoding('file name')
|
||||
result = get_file_encoding(Path('file name'))
|
||||
|
||||
# THEN: The feed method of UniversalDetector should only br called once before returning a result
|
||||
mocked_open.assert_called_once_with('file name', 'rb')
|
||||
mocked_open.assert_called_once_with('rb')
|
||||
self.assertEqual(mocked_universal_detector_inst.feed.mock_calls, [call(b"data" * 256)])
|
||||
mocked_universal_detector_inst.close.assert_called_once_with()
|
||||
self.assertEqual(result, encoding_result)
|
||||
|
||||
def test_get_file_name_encoding_eof_test(self):
|
||||
def test_get_file_encoding_eof_test(self):
|
||||
"""
|
||||
Test get_file_encoding when the end of the file is reached
|
||||
"""
|
||||
# GIVEN: A mocked UniversalDetector instance which isn't set to done and a mocked open, with 1040 bytes of test
|
||||
# data (enough to run the iterator twice)
|
||||
with patch('openlp.core.common.UniversalDetector') as mocked_universal_detector, \
|
||||
patch('builtins.open', return_value=BytesIO(b"data" * 260)) as mocked_open:
|
||||
patch.object(Path, 'open', return_value=BytesIO(b"data" * 260)) as mocked_open:
|
||||
encoding_result = {'encoding': 'UTF-8', 'confidence': 0.99}
|
||||
mocked_universal_detector_inst = MagicMock(mock=mocked_universal_detector,
|
||||
**{'done': False, 'result': encoding_result})
|
||||
mocked_universal_detector.return_value = mocked_universal_detector_inst
|
||||
|
||||
# WHEN: Calling get_file_encoding
|
||||
result = get_file_encoding('file name')
|
||||
result = get_file_encoding(Path('file name'))
|
||||
|
||||
# THEN: The feed method of UniversalDetector should have been called twice before returning a result
|
||||
mocked_open.assert_called_once_with('file name', 'rb')
|
||||
mocked_open.assert_called_once_with('rb')
|
||||
self.assertEqual(mocked_universal_detector_inst.feed.mock_calls, [call(b"data" * 256), call(b"data" * 4)])
|
||||
mocked_universal_detector_inst.close.assert_called_once_with()
|
||||
self.assertEqual(result, encoding_result)
|
||||
|
||||
def test_get_file_name_encoding_oserror_test(self):
|
||||
def test_get_file_encoding_oserror_test(self):
|
||||
"""
|
||||
Test get_file_encoding when the end of the file is reached
|
||||
"""
|
||||
@ -397,7 +401,7 @@ class TestInit(TestCase, TestMixin):
|
||||
patch('openlp.core.common.log') as mocked_log:
|
||||
|
||||
# WHEN: Calling get_file_encoding
|
||||
result = get_file_encoding('file name')
|
||||
result = get_file_encoding(Path('file name'))
|
||||
|
||||
# THEN: log.exception should be called and get_file_encoding should return None
|
||||
mocked_log.exception.assert_called_once_with('Error detecting file encoding')
|
||||
|
@ -24,6 +24,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
|
||||
@ -129,10 +130,10 @@ class TestDB(TestCase):
|
||||
# GIVEN: Mocked out AppLocation class and delete_file method, a test plugin name and a db location
|
||||
with patch('openlp.core.lib.db.AppLocation') as MockedAppLocation, \
|
||||
patch('openlp.core.lib.db.delete_file') as mocked_delete_file:
|
||||
MockedAppLocation.get_section_data_path.return_value = 'test-dir'
|
||||
MockedAppLocation.get_section_data_path.return_value = Path('test-dir')
|
||||
mocked_delete_file.return_value = True
|
||||
test_plugin = 'test'
|
||||
test_location = os.path.join('test-dir', test_plugin)
|
||||
test_location = Path('test-dir', test_plugin)
|
||||
|
||||
# WHEN: delete_database is run without a database file
|
||||
result = delete_database(test_plugin)
|
||||
@ -149,11 +150,11 @@ class TestDB(TestCase):
|
||||
# GIVEN: Mocked out AppLocation class and delete_file method, a test plugin name and a db location
|
||||
with patch('openlp.core.lib.db.AppLocation') as MockedAppLocation, \
|
||||
patch('openlp.core.lib.db.delete_file') as mocked_delete_file:
|
||||
MockedAppLocation.get_section_data_path.return_value = 'test-dir'
|
||||
MockedAppLocation.get_section_data_path.return_value = Path('test-dir')
|
||||
mocked_delete_file.return_value = False
|
||||
test_plugin = 'test'
|
||||
test_db_file = 'mydb.sqlite'
|
||||
test_location = os.path.join('test-dir', test_db_file)
|
||||
test_location = Path('test-dir', test_db_file)
|
||||
|
||||
# WHEN: delete_database is run without a database file
|
||||
result = delete_database(test_plugin, test_db_file)
|
||||
|
@ -1,45 +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 #
|
||||
###############################################################################
|
||||
"""
|
||||
Package to test the openlp.core.ui.lib.filedialog package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
|
||||
class TestFileDialog(TestCase):
|
||||
"""
|
||||
Test the functions in the :mod:`filedialog` module.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.os_patcher = patch('openlp.core.ui.lib.filedialog.os')
|
||||
self.qt_gui_patcher = patch('openlp.core.ui.lib.filedialog.QtWidgets')
|
||||
self.ui_strings_patcher = patch('openlp.core.ui.lib.filedialog.UiStrings')
|
||||
self.mocked_os = self.os_patcher.start()
|
||||
self.mocked_qt_gui = self.qt_gui_patcher.start()
|
||||
self.mocked_ui_strings = self.ui_strings_patcher.start()
|
||||
self.mocked_parent = MagicMock()
|
||||
|
||||
def tearDown(self):
|
||||
self.os_patcher.stop()
|
||||
self.qt_gui_patcher.stop()
|
||||
self.ui_strings_patcher.stop()
|
@ -24,6 +24,7 @@ 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
|
||||
|
||||
@ -148,35 +149,34 @@ class TestLib(TestCase):
|
||||
"""
|
||||
Test the get_text_file_string() function when a file does not exist
|
||||
"""
|
||||
with patch('openlp.core.lib.os.path.isfile') as mocked_isfile:
|
||||
# GIVEN: A mocked out isfile which returns true, and a text file name
|
||||
filename = 'testfile.txt'
|
||||
mocked_isfile.return_value = False
|
||||
# GIVEN: A patched is_file which returns False, and a file path
|
||||
with patch.object(Path, 'is_file', return_value=False):
|
||||
file_path = Path('testfile.txt')
|
||||
|
||||
# WHEN: get_text_file_string is called
|
||||
result = get_text_file_string(filename)
|
||||
result = get_text_file_string(file_path)
|
||||
|
||||
# THEN: The result should be False
|
||||
mocked_isfile.assert_called_with(filename)
|
||||
file_path.is_file.assert_called_with()
|
||||
self.assertFalse(result, 'False should be returned if no file exists')
|
||||
|
||||
def test_get_text_file_string_read_error(self):
|
||||
"""
|
||||
Test the get_text_file_string() method when a read error happens
|
||||
"""
|
||||
with patch('openlp.core.lib.os.path.isfile') as mocked_isfile, \
|
||||
patch('openlp.core.lib.open', create=True) as mocked_open:
|
||||
# GIVEN: A mocked-out open() which raises an exception and isfile returns True
|
||||
filename = 'testfile.txt'
|
||||
mocked_isfile.return_value = True
|
||||
mocked_open.side_effect = IOError()
|
||||
# GIVEN: A patched open which raises an exception and is_file which returns True
|
||||
with patch.object(Path, 'is_file'), \
|
||||
patch.object(Path, 'open'):
|
||||
file_path = Path('testfile.txt')
|
||||
file_path.is_file.return_value = True
|
||||
file_path.open.side_effect = IOError()
|
||||
|
||||
# WHEN: get_text_file_string is called
|
||||
result = get_text_file_string(filename)
|
||||
result = get_text_file_string(file_path)
|
||||
|
||||
# THEN: None should be returned
|
||||
mocked_isfile.assert_called_with(filename)
|
||||
mocked_open.assert_called_with(filename, 'r', encoding='utf-8')
|
||||
file_path.is_file.assert_called_once_with()
|
||||
file_path.open.assert_called_once_with('r', encoding='utf-8')
|
||||
self.assertIsNone(result, 'None should be returned if the file cannot be opened')
|
||||
|
||||
def test_get_text_file_string_decode_error(self):
|
||||
|
@ -25,6 +25,7 @@ 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
|
||||
|
||||
@ -116,7 +117,7 @@ class TestFirstTimeForm(TestCase, TestMixin):
|
||||
mocked_settings.value.return_value = True
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mocked_gettempdir.return_value = 'temp'
|
||||
expected_temp_path = os.path.join('temp', 'openlp')
|
||||
expected_temp_path = Path('temp', 'openlp')
|
||||
|
||||
# WHEN: The set_defaults() method is run
|
||||
frw.set_defaults()
|
||||
|
@ -90,7 +90,7 @@ class TestThemeManager(TestCase):
|
||||
# theme, check_directory_exists and thememanager-attributes.
|
||||
with patch('builtins.open') as mocked_open, \
|
||||
patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \
|
||||
patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists:
|
||||
patch('openlp.core.ui.thememanager.check_directory_exists'):
|
||||
mocked_open.return_value = MagicMock()
|
||||
theme_manager = ThemeManager(None)
|
||||
theme_manager.old_background_image = None
|
||||
@ -118,7 +118,7 @@ class TestThemeManager(TestCase):
|
||||
# theme, check_directory_exists and thememanager-attributes.
|
||||
with patch('builtins.open') as mocked_open, \
|
||||
patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \
|
||||
patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists:
|
||||
patch('openlp.core.ui.thememanager.check_directory_exists'):
|
||||
mocked_open.return_value = MagicMock()
|
||||
theme_manager = ThemeManager(None)
|
||||
theme_manager.old_background_image = None
|
||||
|
@ -22,6 +22,7 @@
|
||||
"""
|
||||
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
|
||||
|
||||
@ -50,7 +51,6 @@ class TestManager(TestCase):
|
||||
"""
|
||||
# GIVEN: An instance of BibleManager and a mocked bible
|
||||
with patch.object(BibleManager, 'reload_bibles'), \
|
||||
patch('openlp.plugins.bibles.lib.manager.os.path.join', side_effect=lambda x, y: '{}/{}'.format(x, y)),\
|
||||
patch('openlp.plugins.bibles.lib.manager.delete_file', return_value=True) as mocked_delete_file:
|
||||
instance = BibleManager(MagicMock())
|
||||
# We need to keep a reference to the mock for close_all as it gets set to None later on!
|
||||
@ -66,4 +66,4 @@ class TestManager(TestCase):
|
||||
self.assertTrue(result)
|
||||
mocked_close_all.assert_called_once_with()
|
||||
self.assertIsNone(mocked_bible.session)
|
||||
mocked_delete_file.assert_called_once_with('bibles/KJV.sqlite')
|
||||
mocked_delete_file.assert_called_once_with(Path('bibles', 'KJV.sqlite'))
|
||||
|
@ -38,20 +38,18 @@ class MediaPluginTest(TestCase, TestMixin):
|
||||
def setUp(self):
|
||||
Registry.create()
|
||||
|
||||
@patch(u'openlp.plugins.media.mediaplugin.Plugin.initialise')
|
||||
@patch('openlp.plugins.media.mediaplugin.Plugin.initialise')
|
||||
def test_initialise(self, mocked_initialise):
|
||||
"""
|
||||
Test that the initialise() method overwrites the built-in one, but still calls it
|
||||
"""
|
||||
# GIVEN: A media plugin instance and a mocked settings object
|
||||
# GIVEN: A media plugin instance
|
||||
media_plugin = MediaPlugin()
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.get_files_from_config.return_value = True # Not the real value, just need something "true-ish"
|
||||
|
||||
# WHEN: initialise() is called
|
||||
media_plugin.initialise()
|
||||
|
||||
# THEN: The settings should be upgraded and the base initialise() method should be called
|
||||
# THEN: The the base initialise() method should be called
|
||||
mocked_initialise.assert_called_with()
|
||||
|
||||
def test_about_text(self):
|
||||
|
@ -24,6 +24,7 @@ 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
|
||||
|
||||
@ -38,7 +39,8 @@ class TestPresentationController(TestCase):
|
||||
"""
|
||||
def setUp(self):
|
||||
self.get_thumbnail_folder_patcher = \
|
||||
patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder')
|
||||
patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder',
|
||||
return_value=Path())
|
||||
self.get_thumbnail_folder_patcher.start()
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.settings_section = 'presentations'
|
||||
@ -225,7 +227,7 @@ class TestPresentationDocument(TestCase):
|
||||
PresentationDocument(self.mock_controller, 'Name')
|
||||
|
||||
# THEN: check_directory_exists should have been called with 'returned/path/'
|
||||
self.mock_check_directory_exists.assert_called_once_with('returned/path/')
|
||||
self.mock_check_directory_exists.assert_called_once_with(Path('returned', 'path'))
|
||||
|
||||
self._setup_patcher.start()
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
"""
|
||||
Functional tests to test the AppLocation class and related methods.
|
||||
"""
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
from openlp.core.common import is_not_image_file
|
||||
@ -59,7 +59,7 @@ class TestUtils(TestCase, TestMixin):
|
||||
Test the method handles an image file
|
||||
"""
|
||||
# Given and empty string
|
||||
file_name = os.path.join(TEST_RESOURCES_PATH, 'church.jpg')
|
||||
file_name = Path(TEST_RESOURCES_PATH, 'church.jpg')
|
||||
|
||||
# WHEN testing for it
|
||||
result = is_not_image_file(file_name)
|
||||
@ -72,7 +72,7 @@ class TestUtils(TestCase, TestMixin):
|
||||
Test the method handles a non image file
|
||||
"""
|
||||
# Given and empty string
|
||||
file_name = os.path.join(TEST_RESOURCES_PATH, 'serviceitem_custom_1.osj')
|
||||
file_name = Path(TEST_RESOURCES_PATH, 'serviceitem_custom_1.osj')
|
||||
|
||||
# WHEN testing for it
|
||||
result = is_not_image_file(file_name)
|
||||
|
Loading…
Reference in New Issue
Block a user