This commit is contained in:
Raoul Snyman 2018-01-13 17:55:21 -07:00
commit 7490c7ad1e
576 changed files with 5702 additions and 5253 deletions

View File

@ -47,4 +47,5 @@ htmlcov
node_modules
openlp-test-projectordb.sqlite
package-lock.json
.cache
test

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -5,7 +5,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -39,7 +39,7 @@ def set_up_fault_handling():
"""
# Create the cache directory if it doesn't exist, and enable the fault handler to log to an error log file
create_paths(AppLocation.get_directory(AppLocation.CacheDir))
faulthandler.enable(open(str(AppLocation.get_directory(AppLocation.CacheDir) / 'error.log'), 'wb'))
faulthandler.enable((AppLocation.get_directory(AppLocation.CacheDir) / 'error.log').open('wb'))
if __name__ == '__main__':

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -20,9 +20,9 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.api.http import register_endpoint, requires_auth
from openlp.core.api.tab import ApiTab
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.api.poll import Poller
from openlp.core.api.tab import ApiTab
__all__ = ['Endpoint', 'ApiTab', 'register_endpoint', 'requires_auth']

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -25,8 +25,8 @@ Download and "install" the remote web client
from zipfile import ZipFile
from openlp.core.common.applocation import AppLocation
from openlp.core.common.httputils import download_file, get_web_page, get_url_file_size
from openlp.core.common.registry import Registry
from openlp.core.common.httputils import url_get_file, get_web_page, get_url_file_size
def deploy_zipfile(app_root_path, zip_name):
@ -65,7 +65,7 @@ def download_and_check(callback=None):
sha256, version = download_sha256()
file_size = get_url_file_size('https://get.openlp.org/webclient/site.zip')
callback.setRange(0, file_size)
if url_get_file(callback, 'https://get.openlp.org/webclient/site.zip',
AppLocation.get_section_data_path('remotes') / 'site.zip',
sha256=sha256):
if download_file(callback, 'https://get.openlp.org/webclient/site.zip',
AppLocation.get_section_data_path('remotes') / 'site.zip',
sha256=sha256):
deploy_zipfile(AppLocation.get_section_data_path('remotes'), 'site.zip')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -19,14 +19,14 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import json
import logging
import os
import urllib.request
import urllib.error
import json
import urllib.request
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.api.http import requires_auth
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.common.applocation import AppLocation
from openlp.core.common.path import Path
from openlp.core.common.registry import Registry

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -27,11 +27,10 @@ import os
from openlp.core.api.http import requires_auth
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.common.registry import Registry
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry
from openlp.core.lib import PluginStatus, StringContent, image_to_byte
template_dir = 'templates'
static_dir = 'static'
blank_dir = os.path.join(static_dir, 'index')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -21,9 +21,8 @@
###############################################################################
import logging
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.api.endpoint.core import TRANSLATED_STRINGS
from openlp.core.api.http.endpoint import Endpoint
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -19,14 +19,13 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import logging
import json
import logging
from openlp.core.api.http import requires_auth
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.common.registry import Registry
log = logging.getLogger(__name__)
service_endpoint = Endpoint('service')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -22,10 +22,11 @@
import base64
from functools import wraps
from webob import Response
from openlp.core.common.settings import Settings
from openlp.core.api.http.wsgiapp import WSGIApplication
from openlp.core.common.settings import Settings
from .errors import NotFound, ServerError, HttpError
application = WSGIApplication('api')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -27,40 +27,33 @@ import logging
import time
from PyQt5 import QtCore, QtWidgets
from waitress import serve
from waitress.server import create_server
from openlp.core.api.deploy import download_and_check, download_sha256
from openlp.core.api.endpoint.controller import controller_endpoint, api_controller_endpoint
from openlp.core.api.endpoint.core import chords_endpoint, stage_endpoint, blank_endpoint, main_endpoint
from openlp.core.api.endpoint.service import service_endpoint, api_service_endpoint
from openlp.core.api.endpoint.remote import remote_endpoint
from openlp.core.api.http import register_endpoint
from openlp.core.api.endpoint.service import service_endpoint, api_service_endpoint
from openlp.core.api.http import application
from openlp.core.api.http import register_endpoint
from openlp.core.api.poll import Poller
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings
from openlp.core.common.i18n import translate
from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.path import create_paths
from openlp.core.common.registry import Registry, RegistryBase
from openlp.core.common.settings import Settings
from openlp.core.common.i18n import translate
from openlp.core.threading import ThreadWorker, run_thread
log = logging.getLogger(__name__)
class HttpWorker(QtCore.QObject):
class HttpWorker(ThreadWorker):
"""
A special Qt thread class to allow the HTTP server to run at the same time as the UI.
"""
def __init__(self):
"""
Constructor for the thread class.
:param server: The http server class.
"""
super(HttpWorker, self).__init__()
def run(self):
def start(self):
"""
Run the thread.
"""
@ -68,12 +61,21 @@ class HttpWorker(QtCore.QObject):
port = Settings().value('api/port')
Registry().execute('get_website_version')
try:
serve(application, host=address, port=port)
self.server = create_server(application, host=address, port=port)
self.server.run()
except OSError:
log.exception('An error occurred when serving the application.')
self.quit.emit()
def stop(self):
pass
"""
A method to stop the worker
"""
if hasattr(self, 'server'):
# Loop through all the channels and close them to stop the server
for channel in self.server._map.values():
if hasattr(channel, 'close'):
channel.close()
class HttpServer(RegistryBase, RegistryProperties, LogMixin):
@ -85,12 +87,9 @@ class HttpServer(RegistryBase, RegistryProperties, LogMixin):
Initialise the http server, and start the http server
"""
super(HttpServer, self).__init__(parent)
if Registry().get_flag('no_web_server'):
self.worker = HttpWorker()
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.thread.start()
if not Registry().get_flag('no_web_server'):
worker = HttpWorker()
run_thread(worker, 'http_server')
Registry().register_function('download_website', self.first_time)
Registry().register_function('get_website_version', self.website_version)
Registry().set_flag('website_version', '0.0')
@ -167,7 +166,7 @@ class DownloadProgressDialog(QtWidgets.QProgressDialog):
self.was_cancelled = False
self.previous_size = 0
def _download_progress(self, count, block_size):
def update_progress(self, count, block_size):
"""
Calculate and display the download progress.
"""

View File

@ -5,7 +5,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -30,9 +30,8 @@ import re
from webob import Request, Response
from webob.static import DirectoryApp
from openlp.core.common.applocation import AppLocation
from openlp.core.api.http.errors import HttpError, NotFound, ServerError
from openlp.core.common.applocation import AppLocation
ARGS_REGEX = re.compile(r'''\{(\w+)(?::([^}]+))?\}''', re.VERBOSE)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,41 +24,92 @@ The :mod:`http` module contains the API web server. This is a lightweight web se
with OpenLP. It uses JSON to communicate with the remotes.
"""
import asyncio
import websockets
import json
import logging
import time
from PyQt5 import QtCore
from websockets import serve
from openlp.core.common.mixins import LogMixin, RegistryProperties
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.threading import ThreadWorker, run_thread
log = logging.getLogger(__name__)
class WebSocketWorker(QtCore.QObject):
async def handle_websocket(request, path):
"""
Handle web socket requests and return the poll information
Check every 0.2 seconds to get the latest position and send if it changed. This only gets triggered when the first
client connects.
:param request: request from client
:param path: determines the endpoints supported
"""
log.debug('WebSocket handler registered with client')
previous_poll = None
previous_main_poll = None
poller = Registry().get('poller')
if path == '/state':
while True:
current_poll = poller.poll()
if current_poll != previous_poll:
await request.send(json.dumps(current_poll).encode())
previous_poll = current_poll
await asyncio.sleep(0.2)
elif path == '/live_changed':
while True:
main_poll = poller.main_poll()
if main_poll != previous_main_poll:
await request.send(main_poll)
previous_main_poll = main_poll
await asyncio.sleep(0.2)
class WebSocketWorker(ThreadWorker, RegistryProperties, LogMixin):
"""
A special Qt thread class to allow the WebSockets server to run at the same time as the UI.
"""
def __init__(self, server):
def start(self):
"""
Constructor for the thread class.
:param server: The http server class.
Run the worker.
"""
self.ws_server = server
super(WebSocketWorker, self).__init__()
def run(self):
"""
Run the thread.
"""
self.ws_server.start_server()
address = Settings().value('api/ip address')
port = Settings().value('api/websocket port')
# Start the event loop
self.event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.event_loop)
# Create the websocker server
loop = 1
self.server = None
while not self.server:
try:
self.server = serve(handle_websocket, address, port)
log.debug('WebSocket server started on {addr}:{port}'.format(addr=address, port=port))
except Exception:
log.exception('Failed to start WebSocket server')
loop += 1
time.sleep(0.1)
if not self.server and loop > 3:
log.error('Unable to start WebSocket server {addr}:{port}, giving up'.format(addr=address, port=port))
if self.server:
# If the websocket server exists, start listening
self.event_loop.run_until_complete(self.server)
self.event_loop.run_forever()
self.quit.emit()
def stop(self):
self.ws_server.stop = True
"""
Stop the websocket server
"""
if hasattr(self.server, 'ws_server'):
self.server.ws_server.close()
elif hasattr(self.server, 'server'):
self.server.server.close()
self.event_loop.stop()
self.event_loop.close()
class WebSocketServer(RegistryProperties, LogMixin):
@ -70,74 +121,6 @@ class WebSocketServer(RegistryProperties, LogMixin):
Initialise and start the WebSockets server
"""
super(WebSocketServer, self).__init__()
if Registry().get_flag('no_web_server'):
self.settings_section = 'api'
self.worker = WebSocketWorker(self)
self.thread = QtCore.QThread()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.thread.start()
def start_server(self):
"""
Start the correct server and save the handler
"""
address = Settings().value(self.settings_section + '/ip address')
port = Settings().value(self.settings_section + '/websocket port')
self.start_websocket_instance(address, port)
# If web socket server start listening
if hasattr(self, 'ws_server') and self.ws_server:
event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(event_loop)
event_loop.run_until_complete(self.ws_server)
event_loop.run_forever()
else:
log.debug('Failed to start ws server on port {port}'.format(port=port))
def start_websocket_instance(self, address, port):
"""
Start the server
:param address: The server address
:param port: The run port
"""
loop = 1
while loop < 4:
try:
self.ws_server = websockets.serve(self.handle_websocket, address, port)
log.debug("Web Socket Server started for class {address} {port}".format(address=address, port=port))
break
except Exception as e:
log.error('Failed to start ws server {why}'.format(why=e))
loop += 1
time.sleep(0.1)
@staticmethod
async def handle_websocket(request, path):
"""
Handle web socket requests and return the poll information.
Check ever 0.2 seconds to get the latest position and send if changed.
Only gets triggered when 1st client attaches
:param request: request from client
:param path: determines the endpoints supported
:return:
"""
log.debug("web socket handler registered with client")
previous_poll = None
previous_main_poll = None
poller = Registry().get('poller')
if path == '/state':
while True:
current_poll = poller.poll()
if current_poll != previous_poll:
await request.send(json.dumps(current_poll).encode())
previous_poll = current_poll
await asyncio.sleep(0.2)
elif path == '/live_changed':
while True:
main_poll = poller.main_poll()
if main_poll != previous_main_poll:
await request.send(main_poll)
previous_main_poll = main_poll
await asyncio.sleep(0.2)
if not Registry().get_flag('no_web_server'):
worker = WebSocketWorker()
run_thread(worker, 'websocket_server')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -52,7 +52,6 @@ from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.style import get_application_stylesheet
from openlp.core.version import check_for_update, get_version
__all__ = ['OpenLP', 'main']
@ -64,8 +63,8 @@ class OpenLP(QtWidgets.QApplication, LogMixin):
The core application class. This class inherits from Qt's QApplication
class in order to provide the core of the application.
"""
args = []
worker_threads = {}
def exec(self):
"""
@ -305,8 +304,7 @@ def parse_options(args=None):
'off a USB flash drive (not implemented).')
parser.add_argument('-d', '--dev-version', dest='dev_version', action='store_true',
help='Ignore the version file and pull the version directly from Bazaar')
parser.add_argument('-s', '--style', dest='style', help='Set the Qt5 style (passed directly to Qt5).')
parser.add_argument('-w', '--no-web-server', dest='no_web_server', action='store_false',
parser.add_argument('-w', '--no-web-server', dest='no_web_server', action='store_true',
help='Turn off the Web and Socket Server ')
parser.add_argument('rargs', nargs='?', default=[])
# Parse command line options and deal with them. Use args supplied pragmatically if possible.
@ -344,8 +342,6 @@ def main(args=None):
log.setLevel(logging.WARNING)
else:
log.setLevel(logging.INFO)
if args and args.style:
qt_args.extend(['-style', args.style])
# Throw the rest of the arguments at Qt, just in case.
qt_args.extend(args.rargs)
# Bug #1018855: Set the WM_CLASS property in X11
@ -359,7 +355,7 @@ def main(args=None):
application.setOrganizationDomain('openlp.org')
application.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
application.setAttribute(QtCore.Qt.AA_DontCreateNativeWidgetSiblings, True)
if args and args.portable:
if args.portable:
application.setApplicationName('OpenLPPortable')
Settings.setDefaultFormat(Settings.IniFormat)
# Get location OpenLPPortable.ini

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -30,13 +30,13 @@ import os
import re
import sys
import traceback
from chardet.universaldetector import UniversalDetector
from ipaddress import IPv4Address, IPv6Address, AddressValueError
from shutil import which
from subprocess import check_output, CalledProcessError, STDOUT
from PyQt5 import QtGui
from PyQt5.QtCore import QCryptographicHash as QHash
from chardet.universaldetector import UniversalDetector
log = logging.getLogger(__name__ + '.__init__')
@ -80,6 +80,7 @@ def extension_loader(glob_pattern, excluded_files=[]):
extension_path = extension_path.relative_to(app_dir)
if extension_path.name in excluded_files:
continue
log.debug('Attempting to import %s', extension_path)
module_name = path_to_module(extension_path)
try:
importlib.import_module(module_name)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -29,7 +29,6 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common.settings import Settings
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -157,7 +157,7 @@ def _get_os_dir_path(dir_type):
return directory
return Path('/usr', 'share', 'openlp')
if XDG_BASE_AVAILABLE:
if dir_type == AppLocation.DataDir or dir_type == AppLocation.CacheDir:
if dir_type == AppLocation.DataDir:
return Path(BaseDirectory.xdg_data_home, 'openlp')
elif dir_type == AppLocation.CacheDir:
return Path(BaseDirectory.xdg_cache_home, 'openlp')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -27,7 +27,6 @@ from copy import deepcopy
import sqlalchemy
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP.
The :mod:`openlp.core.common.httputils` module provides the utility methods for downloading stuff.
"""
import hashlib
import logging
@ -104,7 +104,7 @@ def get_web_page(url, headers=None, update_openlp=False, proxies=None):
if retries >= CONNECTION_RETRIES:
raise ConnectionError('Unable to connect to {url}, see log for details'.format(url=url))
retries += 1
except:
except: # noqa
# Don't know what's happening, so reraise the original
log.exception('Unknown error when trying to connect to {url}'.format(url=url))
raise
@ -136,12 +136,12 @@ def get_url_file_size(url):
continue
def url_get_file(callback, url, file_path, sha256=None):
def download_file(update_object, url, file_path, sha256=None):
""""
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
point. Returns False on download error.
:param callback: the class which needs to be updated
:param update_object: the object which needs to be updated
:param url: URL to download
:param file_path: Destination file
:param sha256: The check sum value to be checked against the download value
@ -158,13 +158,14 @@ def url_get_file(callback, url, file_path, sha256=None):
hasher = hashlib.sha256()
# Download until finished or canceled.
for chunk in response.iter_content(chunk_size=block_size):
if callback.was_cancelled:
if hasattr(update_object, 'was_cancelled') and update_object.was_cancelled:
break
saved_file.write(chunk)
if sha256:
hasher.update(chunk)
block_count += 1
callback._download_progress(block_count, block_size)
if hasattr(update_object, 'update_progress'):
update_object.update_progress(block_count, block_size)
response.close()
if sha256 and hasher.hexdigest() != sha256:
log.error('sha256 sums did not match for file %s, got %s, expected %s', file_path, hasher.hexdigest(),
@ -183,7 +184,7 @@ def url_get_file(callback, url, file_path, sha256=None):
retries += 1
time.sleep(0.1)
continue
if callback.was_cancelled and file_path.exists():
if hasattr(update_object, 'was_cancelled') and update_object.was_cancelled and file_path.exists():
file_path.unlink()
return True

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -22,8 +22,8 @@
"""
Provide Error Handling and login Services
"""
import logging
import inspect
import logging
from openlp.core.common import is_win, trace_error_handler
from openlp.core.common.registry import Registry

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -26,9 +26,9 @@ from contextlib import suppress
from openlp.core.common import is_win
if is_win():
from pathlib import WindowsPath as PathVariant
from pathlib import WindowsPath as PathVariant # pragma: nocover
else:
from pathlib import PosixPath as PathVariant
from pathlib import PosixPath as PathVariant # pragma: nocover
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,8 +23,8 @@
This class contains the core default settings.
"""
import datetime
import logging
import json
import logging
import os
from tempfile import gettempdir

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,13 +23,14 @@
The :mod:`screen` module provides management functionality for a machines'
displays.
"""
import copy
import logging
from PyQt5 import QtCore
from openlp.core.common.i18n import translate
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.common.i18n import translate
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,7 +24,7 @@ The :mod:`lib` module contains most of the components and libraries that make
OpenLP work.
"""
import logging
import os
import re
from PyQt5 import QtCore, QtGui, QtWidgets

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,8 +24,8 @@ Provide HTML Tag management and Formatting Tag access class
"""
import json
from openlp.core.common.settings import Settings
from openlp.core.common.i18n import translate
from openlp.core.common.settings import Settings
class FormattingTags(object):

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -407,7 +407,6 @@ is the function which has to be called from outside. The generated and returned
</html>
"""
import logging
from string import Template
from PyQt5 import QtWebEngine

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -26,8 +26,8 @@ wait for the conversion to happen.
"""
import logging
import os
import time
import queue
import time
from PyQt5 import QtCore
@ -35,13 +35,14 @@ from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.display.screens import ScreenList
from openlp.core.lib import resize_image, image_to_byte
from openlp.core.threading import ThreadWorker, run_thread
log = logging.getLogger(__name__)
class ImageThread(QtCore.QThread):
class ImageWorker(ThreadWorker):
"""
A special Qt thread class to speed up the display of images. This is threaded so it loads the frames and generates
A thread worker class to speed up the display of images. This is threaded so it loads the frames and generates
byte stream in background.
"""
def __init__(self, manager):
@ -51,14 +52,21 @@ class ImageThread(QtCore.QThread):
``manager``
The image manager.
"""
super(ImageThread, self).__init__(None)
super().__init__()
self.image_manager = manager
def run(self):
def start(self):
"""
Run the thread.
Start the worker
"""
self.image_manager.process()
self.quit.emit()
def stop(self):
"""
Stop the worker
"""
self.image_manager.stop_manager = True
class Priority(object):
@ -130,7 +138,7 @@ class Image(object):
class PriorityQueue(queue.PriorityQueue):
"""
Customised ``Queue.PriorityQueue``.
Customised ``queue.PriorityQueue``.
Each item in the queue must be a tuple with three values. The first value is the :class:`Image`'s ``priority``
attribute, the second value the :class:`Image`'s ``secondary_priority`` attribute. The last value the :class:`Image`
@ -179,7 +187,6 @@ class ImageManager(QtCore.QObject):
self.width = current_screen.display_geometry.width()
self.height = current_screen.display_geometry.height()
self._cache = {}
self.image_thread = ImageThread(self)
self._conversion_queue = PriorityQueue()
self.stop_manager = False
Registry().register_function('images_regenerate', self.process_updates)
@ -230,9 +237,13 @@ class ImageManager(QtCore.QObject):
"""
Flush the queue to updated any data to update
"""
# We want only one thread.
if not self.image_thread.isRunning():
self.image_thread.start()
try:
worker = ImageWorker(self)
run_thread(worker, 'image_manager')
except KeyError:
# run_thread() will throw a KeyError if this thread already exists, so ignore it so that we don't
# try to start another thread when one is already running
pass
def get_image(self, path, source, width=-1, height=-1):
"""
@ -305,9 +316,7 @@ class ImageManager(QtCore.QObject):
if image.path == path and image.timestamp != os.stat(path).st_mtime:
image.timestamp = os.stat(path).st_mtime
self._reset_image(image)
# We want only one thread.
if not self.image_thread.isRunning():
self.image_thread.start()
self.process_updates()
def process(self):
"""

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,14 +23,13 @@
Provides the generic functions for interfacing plugins with the Media Manager.
"""
import logging
import os
import re
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import path_to_str, str_to_path
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.lib import ServiceItem, StringContent, ServiceItemContext
@ -332,8 +331,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
"""
new_file_paths = []
error_shown = False
for file_name in data['files']:
file_path = str_to_path(file_name)
for file_path in data['file_paths']:
if file_path.suffix[1:].lower() not in self.on_new_file_masks:
if not error_shown:
critical_error_message_box(

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -71,7 +71,7 @@ class PluginManager(RegistryBase, LogMixin, RegistryProperties):
"""
Scan a directory for objects inheriting from the ``Plugin`` class.
"""
glob_pattern = os.path.join('plugins', '*', '*plugin.py')
glob_pattern = os.path.join('plugins', '*', '[!.]*plugin.py')
extension_loader(glob_pattern)
plugin_classes = Plugin.__subclasses__()
plugin_objects = []

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -26,9 +26,9 @@ type and capability of an item.
import datetime
import html
import logging
import ntpath
import os
import uuid
import ntpath
from PyQt5 import QtGui

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -32,7 +32,6 @@ from openlp.core.common.i18n import UiStrings, translate
from openlp.core.common.registry import Registry
from openlp.core.lib import build_icon
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -32,9 +32,128 @@ log.debug('projector_constants loaded')
# Set common constants.
CR = chr(0x0D) # \r
LF = chr(0x0A) # \n
PJLINK_PORT = 4352
TIMEOUT = 30.0
PJLINK_CLASS = '1' # Default to class 1 until we query the projector
PJLINK_MAX_PACKET = 136
PJLINK_PREFIX = '%'
PJLINK_PORT = 4352
PJLINK_SUFFIX = CR
PJLINK_TIMEOUT = 30.0
# Error and status codes
S_OK = E_OK = 0 # E_OK included since I sometimes forget
# Error codes. Start at 200 so we don't duplicate system error codes.
E_GENERAL = 200 # Unknown error
E_NOT_CONNECTED = 201
E_UNDEFINED = 202 # PJLink ERR1
E_PARAMETER = 203 # PJLink ERR2
E_UNAVAILABLE = 204 # PJLink ERR3
E_PROJECTOR = 205 # PJLink ERR4
E_AUTHENTICATION = 206 # PJLink ERRA
E_NO_AUTHENTICATION = 207 # PJLink authentication mismatch between projector and program
E_PREFIX = 208 # PJLink invalid prefix for packet
E_CLASS = 209 # PJLink class version mismatch
E_INVALID_DATA = 210
E_WARN = 211
E_ERROR = 212
E_FAN = 213
E_LAMP = 214
E_TEMP = 215
E_COVER = 216
E_FILTER = 217
E_UNKNOWN = 218
# Remap Qt socket error codes to local error codes
E_CONNECTION_REFUSED = 230
E_REMOTE_HOST_CLOSED_CONNECTION = 231
E_HOST_NOT_FOUND = 232
E_SOCKET_ACCESS = 233
E_SOCKET_RESOURCE = 234
E_SOCKET_TIMEOUT = 235
E_DATAGRAM_TOO_LARGE = 236
E_NETWORK = 237
E_ADDRESS_IN_USE = 238
E_SOCKET_ADDRESS_NOT_AVAILABLE = 239
E_UNSUPPORTED_SOCKET_OPERATION = 240
E_PROXY_AUTHENTICATION_REQUIRED = 241
E_SLS_HANDSHAKE_FAILED = 242
E_UNFINISHED_SOCKET_OPERATION = 243
E_PROXY_CONNECTION_REFUSED = 244
E_PROXY_CONNECTION_CLOSED = 245
E_PROXY_CONNECTION_TIMEOUT = 246
E_PROXY_NOT_FOUND = 247
E_PROXY_PROTOCOL = 248
E_UNKNOWN_SOCKET_ERROR = 249
# Status codes start at 300
# Remap Qt socket states to local status codes
S_NOT_CONNECTED = 300
S_HOST_LOOKUP = 301
S_CONNECTING = 302
S_CONNECTED = 303
S_BOUND = 304
S_LISTENING = 305 # Listed as internal use only in QAbstractSocket
S_CLOSING = 306
# Projector states
S_INITIALIZE = 310
S_STATUS = 311
S_OFF = 312
S_STANDBY = 313
S_WARMUP = 314
S_ON = 315
S_COOLDOWN = 316
S_INFO = 317
# Information that does not affect status
S_NETWORK_IDLE = 400
S_NETWORK_SENDING = 401
S_NETWORK_RECEIVING = 402
# Map PJlink errors to local status
PJLINK_ERRORS = {
'ERRA': E_AUTHENTICATION, # Authentication error
'ERR1': E_UNDEFINED, # Undefined command error
'ERR2': E_PARAMETER, # Invalid parameter error
'ERR3': E_UNAVAILABLE, # Projector busy
'ERR4': E_PROJECTOR, # Projector or display failure
E_AUTHENTICATION: 'ERRA',
E_UNDEFINED: 'ERR1',
E_PARAMETER: 'ERR2',
E_UNAVAILABLE: 'ERR3',
E_PROJECTOR: 'ERR4'
}
# Map QAbstractSocketState enums to local status
QSOCKET_STATE = {
0: S_NOT_CONNECTED, # 'UnconnectedState',
1: S_HOST_LOOKUP, # 'HostLookupState',
2: S_CONNECTING, # 'ConnectingState',
3: S_CONNECTED, # 'ConnectedState',
4: S_BOUND, # 'BoundState',
5: S_LISTENING, # 'ListeningState' - Noted as "Internal Use Only" on Qt website
6: S_CLOSING, # 'ClosingState',
S_NOT_CONNECTED: 0,
S_HOST_LOOKUP: 1,
S_CONNECTING: 2,
S_CONNECTED: 3,
S_BOUND: 4,
S_LISTENING: 5,
S_CLOSING: 6
}
PROJECTOR_STATE = [
S_INITIALIZE,
S_STATUS,
S_OFF,
S_STANDBY,
S_WARMUP,
S_ON,
S_COOLDOWN,
S_INFO
]
# NOTE: Changed format to account for some commands are both class 1 and 2
PJLINK_VALID_CMD = {
'ACKN': {'version': ['2', ],
@ -144,227 +263,140 @@ PJLINK_VALID_CMD = {
}
}
# QAbstractSocketState enums converted to string
S_QSOCKET_STATE = {
0: 'QSocketState - UnconnectedState',
1: 'QSocketState - HostLookupState',
2: 'QSocketState - ConnectingState',
3: 'QSocketState - ConnectedState',
4: 'QSocketState - BoundState',
5: 'QSocketState - ListeningState (internal use only)',
6: 'QSocketState - ClosingState',
'UnconnectedState': 0,
'HostLookupState': 1,
'ConnectingState': 2,
'ConnectedState': 3,
'BoundState': 4,
'ListeningState': 5,
'ClosingState': 6
}
CONNECTION_ERRORS = [
E_ADDRESS_IN_USE,
E_CONNECTION_REFUSED,
E_DATAGRAM_TOO_LARGE,
E_HOST_NOT_FOUND,
E_NETWORK,
E_NOT_CONNECTED,
E_PROXY_AUTHENTICATION_REQUIRED,
E_PROXY_CONNECTION_CLOSED,
E_PROXY_CONNECTION_REFUSED,
E_PROXY_CONNECTION_TIMEOUT,
E_PROXY_NOT_FOUND,
E_PROXY_PROTOCOL,
E_REMOTE_HOST_CLOSED_CONNECTION,
E_SLS_HANDSHAKE_FAILED,
E_SOCKET_ACCESS,
E_SOCKET_ADDRESS_NOT_AVAILABLE,
E_SOCKET_RESOURCE,
E_SOCKET_TIMEOUT,
E_UNFINISHED_SOCKET_OPERATION,
E_UNKNOWN_SOCKET_ERROR,
E_UNSUPPORTED_SOCKET_OPERATION
]
# Error and status codes
S_OK = E_OK = 0 # E_OK included since I sometimes forget
# Error codes. Start at 200 so we don't duplicate system error codes.
E_GENERAL = 200 # Unknown error
E_NOT_CONNECTED = 201
E_FAN = 202
E_LAMP = 203
E_TEMP = 204
E_COVER = 205
E_FILTER = 206
E_NO_AUTHENTICATION = 207 # PIN set and no authentication set on projector
E_UNDEFINED = 208 # ERR1
E_PARAMETER = 209 # ERR2
E_UNAVAILABLE = 210 # ERR3
E_PROJECTOR = 211 # ERR4
E_INVALID_DATA = 212
E_WARN = 213
E_ERROR = 214
E_AUTHENTICATION = 215 # ERRA
E_CLASS = 216
E_PREFIX = 217
PROJECTOR_ERRORS = [
E_AUTHENTICATION,
E_CLASS,
E_INVALID_DATA,
E_NO_AUTHENTICATION,
E_PARAMETER,
E_PREFIX,
E_PROJECTOR,
E_UNAVAILABLE,
E_UNDEFINED,
E_UNKNOWN
]
# Remap Qt socket error codes to projector error codes
E_CONNECTION_REFUSED = 230
E_REMOTE_HOST_CLOSED_CONNECTION = 231
E_HOST_NOT_FOUND = 232
E_SOCKET_ACCESS = 233
E_SOCKET_RESOURCE = 234
E_SOCKET_TIMEOUT = 235
E_DATAGRAM_TOO_LARGE = 236
E_NETWORK = 237
E_ADDRESS_IN_USE = 238
E_SOCKET_ADDRESS_NOT_AVAILABLE = 239
E_UNSUPPORTED_SOCKET_OPERATION = 240
E_PROXY_AUTHENTICATION_REQUIRED = 241
E_SLS_HANDSHAKE_FAILED = 242
E_UNFINISHED_SOCKET_OPERATION = 243
E_PROXY_CONNECTION_REFUSED = 244
E_PROXY_CONNECTION_CLOSED = 245
E_PROXY_CONNECTION_TIMEOUT = 246
E_PROXY_NOT_FOUND = 247
E_PROXY_PROTOCOL = 248
E_UNKNOWN_SOCKET_ERROR = -1
# Status codes start at 300
S_NOT_CONNECTED = 300
S_CONNECTING = 301
S_CONNECTED = 302
S_INITIALIZE = 303
S_STATUS = 304
S_OFF = 305
S_STANDBY = 306
S_WARMUP = 307
S_ON = 308
S_COOLDOWN = 309
S_INFO = 310
# Information that does not affect status
S_NETWORK_SENDING = 400
S_NETWORK_RECEIVED = 401
CONNECTION_ERRORS = {
E_NOT_CONNECTED, E_NO_AUTHENTICATION, E_AUTHENTICATION, E_CLASS,
E_PREFIX, E_CONNECTION_REFUSED, E_REMOTE_HOST_CLOSED_CONNECTION,
E_HOST_NOT_FOUND, E_SOCKET_ACCESS, E_SOCKET_RESOURCE, E_SOCKET_TIMEOUT,
E_DATAGRAM_TOO_LARGE, E_NETWORK, E_ADDRESS_IN_USE, E_SOCKET_ADDRESS_NOT_AVAILABLE,
E_UNSUPPORTED_SOCKET_OPERATION, E_PROXY_AUTHENTICATION_REQUIRED,
E_SLS_HANDSHAKE_FAILED, E_UNFINISHED_SOCKET_OPERATION, E_PROXY_CONNECTION_REFUSED,
E_PROXY_CONNECTION_CLOSED, E_PROXY_CONNECTION_TIMEOUT, E_PROXY_NOT_FOUND,
E_PROXY_PROTOCOL, E_UNKNOWN_SOCKET_ERROR
}
PJLINK_ERRORS = {
'ERRA': E_AUTHENTICATION, # Authentication error
'ERR1': E_UNDEFINED, # Undefined command error
'ERR2': E_PARAMETER, # Invalid parameter error
'ERR3': E_UNAVAILABLE, # Projector busy
'ERR4': E_PROJECTOR, # Projector or display failure
E_AUTHENTICATION: 'ERRA',
E_UNDEFINED: 'ERR1',
E_PARAMETER: 'ERR2',
E_UNAVAILABLE: 'ERR3',
E_PROJECTOR: 'ERR4'
}
# Map error/status codes to string
ERROR_STRING = {
0: 'S_OK',
E_GENERAL: 'E_GENERAL',
E_NOT_CONNECTED: 'E_NOT_CONNECTED',
E_FAN: 'E_FAN',
E_LAMP: 'E_LAMP',
E_TEMP: 'E_TEMP',
E_COVER: 'E_COVER',
E_FILTER: 'E_FILTER',
E_AUTHENTICATION: 'E_AUTHENTICATION',
E_NO_AUTHENTICATION: 'E_NO_AUTHENTICATION',
E_UNDEFINED: 'E_UNDEFINED',
E_PARAMETER: 'E_PARAMETER',
E_UNAVAILABLE: 'E_UNAVAILABLE',
E_PROJECTOR: 'E_PROJECTOR',
E_INVALID_DATA: 'E_INVALID_DATA',
E_WARN: 'E_WARN',
E_ERROR: 'E_ERROR',
E_CLASS: 'E_CLASS',
E_PREFIX: 'E_PREFIX', # Last projector error
E_CONNECTION_REFUSED: 'E_CONNECTION_REFUSED', # First QtSocket error
E_REMOTE_HOST_CLOSED_CONNECTION: 'E_REMOTE_HOST_CLOSED_CONNECTION',
E_HOST_NOT_FOUND: 'E_HOST_NOT_FOUND',
E_SOCKET_ACCESS: 'E_SOCKET_ACCESS',
E_SOCKET_RESOURCE: 'E_SOCKET_RESOURCE',
E_SOCKET_TIMEOUT: 'E_SOCKET_TIMEOUT',
E_DATAGRAM_TOO_LARGE: 'E_DATAGRAM_TOO_LARGE',
E_NETWORK: 'E_NETWORK',
# Show status code as string
STATUS_CODE = {
E_ADDRESS_IN_USE: 'E_ADDRESS_IN_USE',
E_SOCKET_ADDRESS_NOT_AVAILABLE: 'E_SOCKET_ADDRESS_NOT_AVAILABLE',
E_UNSUPPORTED_SOCKET_OPERATION: 'E_UNSUPPORTED_SOCKET_OPERATION',
E_AUTHENTICATION: 'E_AUTHENTICATION',
E_CLASS: 'E_CLASS',
E_CONNECTION_REFUSED: 'E_CONNECTION_REFUSED',
E_COVER: 'E_COVER',
E_DATAGRAM_TOO_LARGE: 'E_DATAGRAM_TOO_LARGE',
E_ERROR: 'E_ERROR',
E_FAN: 'E_FAN',
E_FILTER: 'E_FILTER',
E_GENERAL: 'E_GENERAL',
E_HOST_NOT_FOUND: 'E_HOST_NOT_FOUND',
E_INVALID_DATA: 'E_INVALID_DATA',
E_LAMP: 'E_LAMP',
E_NETWORK: 'E_NETWORK',
E_NO_AUTHENTICATION: 'E_NO_AUTHENTICATION',
E_NOT_CONNECTED: 'E_NOT_CONNECTED',
E_PARAMETER: 'E_PARAMETER',
E_PREFIX: 'E_PREFIX',
E_PROJECTOR: 'E_PROJECTOR',
E_PROXY_AUTHENTICATION_REQUIRED: 'E_PROXY_AUTHENTICATION_REQUIRED',
E_SLS_HANDSHAKE_FAILED: 'E_SLS_HANDSHAKE_FAILED',
E_UNFINISHED_SOCKET_OPERATION: 'E_UNFINISHED_SOCKET_OPERATION',
E_PROXY_CONNECTION_REFUSED: 'E_PROXY_CONNECTION_REFUSED',
E_PROXY_CONNECTION_CLOSED: 'E_PROXY_CONNECTION_CLOSED',
E_PROXY_CONNECTION_REFUSED: 'E_PROXY_CONNECTION_REFUSED',
E_PROXY_CONNECTION_TIMEOUT: 'E_PROXY_CONNECTION_TIMEOUT',
E_PROXY_NOT_FOUND: 'E_PROXY_NOT_FOUND',
E_PROXY_PROTOCOL: 'E_PROXY_PROTOCOL',
E_UNKNOWN_SOCKET_ERROR: 'E_UNKNOWN_SOCKET_ERROR'
}
STATUS_STRING = {
S_NOT_CONNECTED: 'S_NOT_CONNECTED',
S_CONNECTING: 'S_CONNECTING',
S_CONNECTED: 'S_CONNECTED',
S_STATUS: 'S_STATUS',
S_OFF: 'S_OFF',
S_INITIALIZE: 'S_INITIALIZE',
S_STANDBY: 'S_STANDBY',
S_WARMUP: 'S_WARMUP',
S_ON: 'S_ON',
E_REMOTE_HOST_CLOSED_CONNECTION: 'E_REMOTE_HOST_CLOSED_CONNECTION',
E_SLS_HANDSHAKE_FAILED: 'E_SLS_HANDSHAKE_FAILED',
E_SOCKET_ACCESS: 'E_SOCKET_ACCESS',
E_SOCKET_ADDRESS_NOT_AVAILABLE: 'E_SOCKET_ADDRESS_NOT_AVAILABLE',
E_SOCKET_RESOURCE: 'E_SOCKET_RESOURCE',
E_SOCKET_TIMEOUT: 'E_SOCKET_TIMEOUT',
E_TEMP: 'E_TEMP',
E_UNAVAILABLE: 'E_UNAVAILABLE',
E_UNDEFINED: 'E_UNDEFINED',
E_UNFINISHED_SOCKET_OPERATION: 'E_UNFINISHED_SOCKET_OPERATION',
E_UNKNOWN: 'E_UNKNOWN',
E_UNKNOWN_SOCKET_ERROR: 'E_UNKNOWN_SOCKET_ERROR',
E_UNSUPPORTED_SOCKET_OPERATION: 'E_UNSUPPORTED_SOCKET_OPERATION',
E_WARN: 'E_WARN',
S_BOUND: 'S_BOUND',
S_COOLDOWN: 'S_COOLDOWN',
S_CLOSING: 'S_CLOSING',
S_CONNECTED: 'S_CONNECTED',
S_CONNECTING: 'S_CONNECTING',
S_HOST_LOOKUP: 'S_HOST_LOOKUP',
S_INFO: 'S_INFO',
S_INITIALIZE: 'S_INITIALIZE',
S_LISTENING: 'S_LISTENING',
S_NETWORK_RECEIVING: 'S_NETWORK_RECEIVING',
S_NETWORK_SENDING: 'S_NETWORK_SENDING',
S_NETWORK_RECEIVED: 'S_NETWORK_RECEIVED'
S_NETWORK_IDLE: 'S_NETWORK_IDLE',
S_NOT_CONNECTED: 'S_NOT_CONNECTED',
S_OFF: 'S_OFF',
S_OK: 'S_OK', # S_OK or E_OK
S_ON: 'S_ON',
S_STANDBY: 'S_STANDBY',
S_STATUS: 'S_STATUS',
S_WARMUP: 'S_WARMUP',
}
# Map error/status codes to message strings
ERROR_MSG = {
E_OK: translate('OpenLP.ProjectorConstants', 'OK'), # E_OK | S_OK
E_GENERAL: translate('OpenLP.ProjectorConstants', 'General projector error'),
E_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not connected error'),
E_LAMP: translate('OpenLP.ProjectorConstants', 'Lamp error'),
E_FAN: translate('OpenLP.ProjectorConstants', 'Fan error'),
E_TEMP: translate('OpenLP.ProjectorConstants', 'High temperature detected'),
E_COVER: translate('OpenLP.ProjectorConstants', 'Cover open detected'),
E_FILTER: translate('OpenLP.ProjectorConstants', 'Check filter'),
E_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'Authentication Error'),
E_UNDEFINED: translate('OpenLP.ProjectorConstants', 'Undefined Command'),
E_PARAMETER: translate('OpenLP.ProjectorConstants', 'Invalid Parameter'),
E_UNAVAILABLE: translate('OpenLP.ProjectorConstants', 'Projector Busy'),
E_PROJECTOR: translate('OpenLP.ProjectorConstants', 'Projector/Display Error'),
E_INVALID_DATA: translate('OpenLP.ProjectorConstants', 'Invalid packet received'),
E_WARN: translate('OpenLP.ProjectorConstants', 'Warning condition detected'),
E_ERROR: translate('OpenLP.ProjectorConstants', 'Error condition detected'),
E_CLASS: translate('OpenLP.ProjectorConstants', 'PJLink class not supported'),
E_PREFIX: translate('OpenLP.ProjectorConstants', 'Invalid prefix character'),
E_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants',
'The connection was refused by the peer (or timed out)'),
E_REMOTE_HOST_CLOSED_CONNECTION: translate('OpenLP.ProjectorConstants',
'The remote host closed the connection'),
E_HOST_NOT_FOUND: translate('OpenLP.ProjectorConstants', 'The host address was not found'),
E_SOCKET_ACCESS: translate('OpenLP.ProjectorConstants',
'The socket operation failed because the application '
'lacked the required privileges'),
E_SOCKET_RESOURCE: translate('OpenLP.ProjectorConstants',
'The local system ran out of resources (e.g., too many sockets)'),
E_SOCKET_TIMEOUT: translate('OpenLP.ProjectorConstants',
'The socket operation timed out'),
E_DATAGRAM_TOO_LARGE: translate('OpenLP.ProjectorConstants',
'The datagram was larger than the operating system\'s limit'),
E_NETWORK: translate('OpenLP.ProjectorConstants',
'An error occurred with the network (Possibly someone pulled the plug?)'),
# Map status codes to message strings
STATUS_MSG = {
E_ADDRESS_IN_USE: translate('OpenLP.ProjectorConstants',
'The address specified with socket.bind() '
'is already in use and was set to be exclusive'),
E_SOCKET_ADDRESS_NOT_AVAILABLE: translate('OpenLP.ProjectorConstants',
'The address specified to socket.bind() '
'does not belong to the host'),
E_UNSUPPORTED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants',
'The requested socket operation is not supported by the local '
'operating system (e.g., lack of IPv6 support)'),
E_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERRA: Authentication Error"'),
E_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants',
'The connection was refused by the peer (or timed out)'),
E_COVER: translate('OpenLP.ProjectorConstants', 'Projector cover open detected'),
E_CLASS: translate('OpenLP.ProjectorConstants', 'PJLink class not supported'),
E_DATAGRAM_TOO_LARGE: translate('OpenLP.ProjectorConstants',
"The datagram was larger than the operating system's limit"),
E_ERROR: translate('OpenLP.ProjectorConstants', 'Error condition detected'),
E_FAN: translate('OpenLP.ProjectorConstants', 'Projector fan error'),
E_FILTER: translate('OpenLP.ProjectorConstants', 'Projector check filter'),
E_GENERAL: translate('OpenLP.ProjectorConstants', 'General projector error'),
E_HOST_NOT_FOUND: translate('OpenLP.ProjectorConstants', 'The host address was not found'),
E_INVALID_DATA: translate('OpenLP.ProjectorConstants', 'PJLink invalid packet received'),
E_LAMP: translate('OpenLP.ProjectorConstants', 'Projector lamp error'),
E_NETWORK: translate('OpenLP.ProjectorConstants',
'An error occurred with the network (Possibly someone pulled the plug?)'),
E_NO_AUTHENTICATION: translate('OpenLP.ProjectorConstants', 'PJlink authentication Mismatch Error'),
E_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Projector not connected error'),
E_PARAMETER: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR2: Invalid Parameter"'),
E_PREFIX: translate('OpenLP.ProjectorConstants', 'PJLink Invalid prefix character'),
E_PROJECTOR: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR4: Projector/Display Error"'),
E_PROXY_AUTHENTICATION_REQUIRED: translate('OpenLP.ProjectorConstants',
'The socket is using a proxy, '
'and the proxy requires authentication'),
E_SLS_HANDSHAKE_FAILED: translate('OpenLP.ProjectorConstants',
'The SSL/TLS handshake failed'),
E_UNFINISHED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants',
'The last operation attempted has not finished yet '
'(still in progress in the background)'),
E_PROXY_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants',
'Could not contact the proxy server because the connection '
'to that server was denied'),
E_PROXY_CONNECTION_CLOSED: translate('OpenLP.ProjectorConstants',
'The connection to the proxy server was closed unexpectedly '
'(before the connection to the final peer was established)'),
E_PROXY_CONNECTION_REFUSED: translate('OpenLP.ProjectorConstants',
'Could not contact the proxy server because the connection '
'to that server was denied'),
E_PROXY_CONNECTION_TIMEOUT: translate('OpenLP.ProjectorConstants',
'The connection to the proxy server timed out or the proxy '
'server stopped responding in the authentication phase.'),
@ -373,51 +405,91 @@ ERROR_MSG = {
E_PROXY_PROTOCOL: translate('OpenLP.ProjectorConstants',
'The connection negotiation with the proxy server failed because the '
'response from the proxy server could not be understood'),
E_UNKNOWN_SOCKET_ERROR: translate('OpenLP.ProjectorConstants', 'An unidentified error occurred'),
S_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not connected'),
S_CONNECTING: translate('OpenLP.ProjectorConstants', 'Connecting'),
E_REMOTE_HOST_CLOSED_CONNECTION: translate('OpenLP.ProjectorConstants',
'The remote host closed the connection'),
E_SLS_HANDSHAKE_FAILED: translate('OpenLP.ProjectorConstants',
'The SSL/TLS handshake failed'),
E_SOCKET_ADDRESS_NOT_AVAILABLE: translate('OpenLP.ProjectorConstants',
'The address specified to socket.bind() '
'does not belong to the host'),
E_SOCKET_ACCESS: translate('OpenLP.ProjectorConstants',
'The socket operation failed because the application '
'lacked the required privileges'),
E_SOCKET_RESOURCE: translate('OpenLP.ProjectorConstants',
'The local system ran out of resources (e.g., too many sockets)'),
E_SOCKET_TIMEOUT: translate('OpenLP.ProjectorConstants',
'The socket operation timed out'),
E_TEMP: translate('OpenLP.ProjectorConstants', 'Projector high temperature detected'),
E_UNAVAILABLE: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR3: Busy"'),
E_UNDEFINED: translate('OpenLP.ProjectorConstants', 'PJLink returned "ERR1: Undefined Command"'),
E_UNFINISHED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants',
'The last operation attempted has not finished yet '
'(still in progress in the background)'),
E_UNKNOWN: translate('OpenLP.ProjectorConstants', 'Unknown condiction detected'),
E_UNKNOWN_SOCKET_ERROR: translate('OpenLP.ProjectorConstants', 'An unidentified socket error occurred'),
E_UNSUPPORTED_SOCKET_OPERATION: translate('OpenLP.ProjectorConstants',
'The requested socket operation is not supported by the local '
'operating system (e.g., lack of IPv6 support)'),
E_WARN: translate('OpenLP.ProjectorConstants', 'Warning condition detected'),
S_BOUND: translate('OpenLP.ProjectorConstants', 'Socket is bount to an address or port'),
S_CLOSING: translate('OpenLP.ProjectorConstants', 'Socket is about to close'),
S_CONNECTED: translate('OpenLP.ProjectorConstants', 'Connected'),
S_STATUS: translate('OpenLP.ProjectorConstants', 'Getting status'),
S_OFF: translate('OpenLP.ProjectorConstants', 'Off'),
S_INITIALIZE: translate('OpenLP.ProjectorConstants', 'Initialize in progress'),
S_STANDBY: translate('OpenLP.ProjectorConstants', 'Power in standby'),
S_WARMUP: translate('OpenLP.ProjectorConstants', 'Warmup in progress'),
S_ON: translate('OpenLP.ProjectorConstants', 'Power is on'),
S_CONNECTING: translate('OpenLP.ProjectorConstants', 'Connecting'),
S_COOLDOWN: translate('OpenLP.ProjectorConstants', 'Cooldown in progress'),
S_HOST_LOOKUP: translate('OpenLP.ProjectorConstants', 'Performing a host name lookup'),
S_INFO: translate('OpenLP.ProjectorConstants', 'Projector Information available'),
S_INITIALIZE: translate('OpenLP.ProjectorConstants', 'Initialize in progress'),
S_LISTENING: translate('OpenLP.ProjectorConstants', 'Socket it listening (internal use only)'),
S_NETWORK_IDLE: translate('OpenLP.ProjectorConstants', 'No network activity at this time'),
S_NETWORK_RECEIVING: translate('OpenLP.ProjectorConstants', 'Received data'),
S_NETWORK_SENDING: translate('OpenLP.ProjectorConstants', 'Sending data'),
S_NETWORK_RECEIVED: translate('OpenLP.ProjectorConstants', 'Received data')
S_NOT_CONNECTED: translate('OpenLP.ProjectorConstants', 'Not Connected'),
S_OFF: translate('OpenLP.ProjectorConstants', 'Off'),
S_OK: translate('OpenLP.ProjectorConstants', 'OK'),
S_ON: translate('OpenLP.ProjectorConstants', 'Power is on'),
S_STANDBY: translate('OpenLP.ProjectorConstants', 'Power in standby'),
S_STATUS: translate('OpenLP.ProjectorConstants', 'Getting status'),
S_WARMUP: translate('OpenLP.ProjectorConstants', 'Warmup in progress'),
}
# Map ERST return code positions to equipment
# Map ERST reply positions to equipment
PJLINK_ERST_LIST = {
"FAN": translate('OpenLP.PJLink', 'Fan'),
"LAMP": translate('OpenLP.PJLink', 'Lamp'),
"TEMP": translate('OpenLP.PJLink', 'Temperature'),
"COVER": translate('OpenLP.PJLink', 'Cover'),
"FILTER": translate('OpenLP.PJLink', 'Filter'),
"OTHER": translate('OpenPL.PJLink', 'Other')
}
# Map projector item to ERST data position
PJLINK_ERST_DATA = {
'DATA_LENGTH': 6,
0: 'FAN',
1: 'LAMP',
2: 'TEMP',
3: 'COVER',
4: 'FILTER',
5: 'OTHER',
'DATA_LENGTH': 6, # Zero based so enums are 0-5
'FAN': 0,
'LAMP': 1,
'TEMP': 2,
'COVER': 3,
'FILTER': 4,
'OTHER': 5
'OTHER': 5,
0: 'FAN',
1: 'LAMP',
2: 'TEMP',
3: 'COVER',
4: 'FILTER',
5: 'OTHER'
}
# Map for ERST return codes to string
# Map ERST reply codes to string
PJLINK_ERST_STATUS = {
'0': 'OK',
'1': ERROR_STRING[E_WARN],
'2': ERROR_STRING[E_ERROR],
'OK': '0',
E_OK: '0',
'0': S_OK,
'1': E_WARN,
'2': E_ERROR,
S_OK: '0',
E_WARN: '1',
E_ERROR: '2'
}
# Map for POWR return codes to status code
# Map POWR return codes to status code
PJLINK_POWR_STATUS = {
'0': S_STANDBY,
'1': S_ON,

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -152,6 +152,7 @@ class Projector(Base, CommonMixin):
location: Column(String(30))
notes: Column(String(200))
pjlink_name: Column(String(128)) # From projector
pjlink_class Column(String(5)) # From projector
manufacturer: Column(String(128)) # From projector
model: Column(String(128)) # From projector
other: Column(String(128)) # From projector
@ -168,7 +169,7 @@ class Projector(Base, CommonMixin):
Return basic representation of Source table entry.
"""
return '< Projector(id="{data}", ip="{ip}", port="{port}", mac_adx="{mac}", pin="{pin}", name="{name}", ' \
'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", ' \
'location="{location}", notes="{notes}", pjlink_name="{pjlink_name}", pjlink_class="{pjlink_class}", ' \
'manufacturer="{manufacturer}", model="{model}", serial_no="{serial}", other="{other}", ' \
'sources="{sources}", source_list="{source_list}", model_filter="{mfilter}", ' \
'model_lamp="{mlamp}", sw_version="{sw_ver}") >'.format(data=self.id,
@ -180,6 +181,7 @@ class Projector(Base, CommonMixin):
location=self.location,
notes=self.notes,
pjlink_name=self.pjlink_name,
pjlink_class=self.pjlink_class,
manufacturer=self.manufacturer,
model=self.model,
other=self.other,
@ -197,6 +199,7 @@ class Projector(Base, CommonMixin):
location = Column(String(30))
notes = Column(String(200))
pjlink_name = Column(String(128))
pjlink_class = Column(String(5))
manufacturer = Column(String(128))
model = Column(String(128))
other = Column(String(128))

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -30,8 +30,8 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common import verify_ip_address
from openlp.core.common.i18n import translate
from openlp.core.lib import build_icon
from openlp.core.projectors.db import Projector
from openlp.core.projectors.constants import PJLINK_PORT
from openlp.core.projectors.db import Projector
log = logging.getLogger(__name__)
log.debug('editform loaded')

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -35,12 +35,28 @@ from openlp.core.common.registry import RegistryBase
from openlp.core.common.settings import Settings
from openlp.core.lib.ui import create_widget_action
from openlp.core.projectors import DialogSourceStyle
from openlp.core.projectors.constants import ERROR_MSG, ERROR_STRING, E_AUTHENTICATION, E_ERROR, \
E_NETWORK, E_NOT_CONNECTED, E_UNKNOWN_SOCKET_ERROR, STATUS_STRING, S_CONNECTED, S_CONNECTING, S_COOLDOWN, \
S_INITIALIZE, S_NOT_CONNECTED, S_OFF, S_ON, S_STANDBY, S_WARMUP
from openlp.core.projectors.constants import \
E_AUTHENTICATION, \
E_ERROR, \
E_NETWORK, \
E_NOT_CONNECTED, \
E_UNKNOWN_SOCKET_ERROR, \
S_CONNECTED, \
S_CONNECTING, \
S_COOLDOWN, \
S_INITIALIZE, \
S_NOT_CONNECTED, \
S_OFF, \
S_ON, \
S_STANDBY, \
S_WARMUP, \
STATUS_CODE, \
STATUS_MSG, \
QSOCKET_STATE
from openlp.core.projectors.db import ProjectorDB
from openlp.core.projectors.pjlink import PJLink, PJLinkUDP
from openlp.core.projectors.editform import ProjectorEditForm
from openlp.core.projectors.pjlink import PJLink, PJLinkUDP
from openlp.core.projectors.sourceselectform import SourceSelectTabs, SourceSelectSingle
from openlp.core.widgets.toolbar import OpenLPToolbar
@ -292,8 +308,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
self.settings_section = 'projector'
self.projectordb = projectordb
self.projector_list = []
self.pjlink_udp = PJLinkUDP()
self.pjlink_udp.projector_list = self.projector_list
self.pjlink_udp = PJLinkUDP(self.projector_list)
self.source_select_form = None
def bootstrap_initialise(self):
@ -440,11 +455,12 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
:param opt: Needed by PyQt5
"""
projector = item.data(QtCore.Qt.UserRole)
if projector.link.state() != projector.link.ConnectedState:
if QSOCKET_STATE[projector.link.state()] != S_CONNECTED:
try:
log.debug('ProjectorManager: Calling connect_to_host() on "{ip}"'.format(ip=projector.link.ip))
projector.link.connect_to_host()
except:
pass
log.debug('ProjectorManager: "{ip}" already connected - skipping'.format(ip=projector.link.ip))
return
def on_connect_projector(self, opt=None):
@ -506,8 +522,8 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
except (AttributeError, TypeError):
pass
try:
projector.timer.stop()
projector.timer.timeout.disconnect(projector.link.poll_loop)
projector.poll_timer.stop()
projector.poll_timer.timeout.disconnect(projector.link.poll_loop)
except (AttributeError, TypeError):
pass
try:
@ -515,7 +531,6 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
projector.socket_timer.timeout.disconnect(projector.link.socket_abort)
except (AttributeError, TypeError):
pass
projector.thread.quit()
new_list = []
for item in self.projector_list:
if item.link.db_item.id == projector.link.db_item.id:
@ -647,7 +662,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
'Other info'),
data=projector.link.other_info)
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Power status'),
data=ERROR_MSG[projector.link.power])
data=STATUS_MSG[projector.link.power])
message += '<b>{title}</b>: {data}<br />'.format(title=translate('OpenLP.ProjectorManager', 'Shutter is'),
data=translate('OpenLP.ProjectorManager', 'Closed')
if projector.link.shutter
@ -692,7 +707,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
else:
message += '<b>{data}</b>'.format(data=translate('OpenLP.ProjectorManager', 'Current errors/warnings'))
for (key, val) in projector.link.projector_errors.items():
message += '<b>{key}</b>: {data}<br />'.format(key=key, data=ERROR_MSG[val])
message += '<b>{key}</b>: {data}<br />'.format(key=key, data=STATUS_MSG[val])
QtWidgets.QMessageBox.information(self, translate('OpenLP.ProjectorManager', 'Projector Information'), message)
def _add_projector(self, projector):
@ -717,39 +732,18 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
"""
item = ProjectorItem(link=self._add_projector(projector))
item.db_item = projector
icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[S_NOT_CONNECTED]))
item.icon = icon
widget = QtWidgets.QListWidgetItem(icon,
item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[S_NOT_CONNECTED]))
widget = QtWidgets.QListWidgetItem(item.icon,
item.link.name,
self.projector_list_widget
)
widget.setData(QtCore.Qt.UserRole, item)
item.link.db_item = item.db_item
item.widget = widget
thread = QtCore.QThread(parent=self)
thread.my_parent = self
item.moveToThread(thread)
thread.started.connect(item.link.thread_started)
thread.finished.connect(item.link.thread_stopped)
thread.finished.connect(thread.deleteLater)
item.link.changeStatus.connect(self.update_status)
item.link.projectorAuthentication.connect(self.authentication_error)
item.link.projectorNoAuthentication.connect(self.no_authentication_error)
item.link.projectorUpdateIcons.connect(self.update_icons)
timer = QtCore.QTimer(self)
timer.setInterval(self.poll_time)
timer.timeout.connect(item.link.poll_loop)
item.timer = timer
# Timeout in case of brain-dead projectors or cable disconnected
socket_timer = QtCore.QTimer(self)
socket_timer.setInterval(11000)
socket_timer.timeout.connect(item.link.socket_abort)
item.socket_timer = socket_timer
thread.start()
item.thread = thread
item.link.timer = timer
item.link.socket_timer = socket_timer
item.link.widget = item.widget
self.projector_list.append(item)
if start:
item.link.connect_to_host()
@ -817,31 +811,18 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
if ip == list_item.link.ip:
item = list_item
break
message = translate('OpenLP.ProjectorManager', 'No message') if msg is None else msg
if status in STATUS_STRING:
status_code = STATUS_STRING[status]
message = ERROR_MSG[status] if msg is None else msg
elif status in ERROR_STRING:
status_code = ERROR_STRING[status]
message = ERROR_MSG[status] if msg is None else msg
else:
status_code = status
message = ERROR_MSG[status] if msg is None else msg
log.debug('({name}) updateStatus(status={status}) message: "{message}"'.format(name=item.link.name,
status=status_code,
message=message))
if status in STATUS_ICONS:
if item.status == status:
return
item.status = status
item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status]))
if status in ERROR_STRING:
status_code = ERROR_STRING[status]
elif status in STATUS_STRING:
status_code = STATUS_STRING[status]
log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=status_code))
item.widget.setIcon(item.icon)
self.update_icons()
if item is None:
log.error('ProjectorManager: Unknown item "{ip}" - not updating status'.format(ip=ip))
return
elif item.status == status:
log.debug('ProjectorManager: No status change for "{ip}" - not updating status'.format(ip=ip))
return
item.status = status
item.icon = QtGui.QIcon(QtGui.QPixmap(STATUS_ICONS[status]))
log.debug('({name}) Updating icon with {code}'.format(name=item.link.name, code=STATUS_CODE[status]))
item.widget.setIcon(item.icon)
return self.update_icons()
def get_toolbar_item(self, name, enabled=False, hidden=False):
item = self.one_toolbar.findChild(QtWidgets.QAction, name)
@ -877,7 +858,7 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM
self.get_toolbar_item('show_projector_multiple', hidden=True)
elif count == 1:
projector = self.projector_list_widget.selectedItems()[0].data(QtCore.Qt.UserRole)
connected = projector.link.state() == projector.link.ConnectedState
connected = QSOCKET_STATE[projector.link.state()] == S_CONNECTED
power = projector.link.power == S_ON
self.get_toolbar_item('connect_projector_multiple', hidden=True)
self.get_toolbar_item('disconnect_projector_multiple', hidden=True)

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -31,8 +31,8 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common import is_macosx
from openlp.core.common.i18n import translate
from openlp.core.lib import build_icon
from openlp.core.projectors.db import ProjectorSource
from openlp.core.projectors.constants import PJLINK_DEFAULT_SOURCES, PJLINK_DEFAULT_CODES
from openlp.core.projectors.db import ProjectorSource
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -33,7 +33,7 @@ from openlp.core.lib.db import get_upgrade_op
log = logging.getLogger(__name__)
# Initial projector DB was unversioned
__version__ = 2
__version__ = 3
log.debug('Projector DB upgrade module loading')
@ -71,3 +71,23 @@ def upgrade_2(session, metadata):
new_op.add_column('projector', Column('model_filter', types.String(30), server_default=null()))
new_op.add_column('projector', Column('model_lamp', types.String(30), server_default=null()))
log.debug('{status} projector DB upgrade to version 2'.format(status='Updated' if upgrade_db else 'Skipping'))
def upgrade_3(session, metadata):
"""
Version 3 upgrade.
Update Projector() table to inlcude PJLink class as part of record.
pjlink_version: Column(String(1))
:param session: DB Session instance
:param metadata: Metadata of current DB
"""
log.debug('Checking projector DB upgrade to version 3')
projector_table = Table('projector', metadata, autoload=True)
upgrade_db = 'pjlink_class' not in [col.name for col in projector_table.c.values()]
if upgrade_db:
new_op = get_upgrade_op(session)
new_op.add_column('projector', Column('pjlink_class', types.String(5), server_default=null()))
log.debug('{status} projector DB upgrade to version 3'.format(status='Updated' if upgrade_db else 'Skipping'))

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,26 +24,41 @@ The :mod:`openlp.core.threading` module contains some common threading code
"""
from PyQt5 import QtCore
from openlp.core.common.registry import Registry
def run_thread(parent, worker, prefix='', auto_start=True):
class ThreadWorker(QtCore.QObject):
"""
The :class:`~openlp.core.threading.ThreadWorker` class provides a base class for all worker objects
"""
quit = QtCore.pyqtSignal()
def start(self):
"""
The start method is how the worker runs. Basically, put your code here.
"""
raise NotImplementedError('Your base class needs to override this method and run self.quit.emit() at the end.')
def run_thread(worker, thread_name, can_start=True):
"""
Create a thread and assign a worker to it. This removes a lot of boilerplate code from the codebase.
:param object parent: The parent object so that the thread and worker are not orphaned.
:param QObject worker: A QObject-based worker object which does the actual work.
:param str prefix: A prefix to be applied to the attribute names.
:param bool auto_start: Automatically start the thread. Defaults to True.
:param str thread_name: The name of the thread, used to keep track of the thread.
:param bool can_start: Start the thread. Defaults to True.
"""
# Set up attribute names
thread_name = 'thread'
worker_name = 'worker'
if prefix:
thread_name = '_'.join([prefix, thread_name])
worker_name = '_'.join([prefix, worker_name])
if not thread_name:
raise ValueError('A thread_name is required when calling the "run_thread" function')
application = Registry().get('application')
if thread_name in application.worker_threads:
raise KeyError('A thread with the name "{}" has already been created, please use another'.format(thread_name))
# Create the thread and add the thread and the worker to the parent
thread = QtCore.QThread()
setattr(parent, thread_name, thread)
setattr(parent, worker_name, worker)
application.worker_threads[thread_name] = {
'thread': thread,
'worker': worker
}
# Move the worker into the thread's context
worker.moveToThread(thread)
# Connect slots and signals
@ -51,5 +66,50 @@ def run_thread(parent, worker, prefix='', auto_start=True):
worker.quit.connect(thread.quit)
worker.quit.connect(worker.deleteLater)
thread.finished.connect(thread.deleteLater)
if auto_start:
thread.finished.connect(make_remove_thread(thread_name))
if can_start:
thread.start()
def get_thread_worker(thread_name):
"""
Get the worker by the thread name
:param str thread_name: The name of the thread
:returns: The worker for this thread name
"""
thread_info = Registry().get('application').worker_threads.get(thread_name)
if not thread_info:
raise KeyError('No thread named "{}" exists'.format(thread_name))
return thread_info.get('worker')
def is_thread_finished(thread_name):
"""
Check if a thread is finished running.
:param str thread_name: The name of the thread
:returns: True if the thread is finished, False if it is still running
"""
app = Registry().get('application')
return thread_name not in app.worker_threads or app.worker_threads[thread_name]['thread'].isFinished()
def make_remove_thread(thread_name):
"""
Create a function to remove the thread once the thread is finished.
:param str thread_name: The name of the thread which should be removed from the thread registry.
:returns: A function which will remove the thread from the thread registry.
"""
def remove_thread(): # pragma: nocover
"""
Stop and remove a registered thread
:param str thread_name: The name of the thread to stop and remove
"""
application = Registry().get('application')
if thread_name in application.worker_threads:
del application.worker_threads[thread_name]
return remove_thread

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -26,8 +26,8 @@ import webbrowser
from PyQt5 import QtCore, QtWidgets
from openlp.core.version import get_version
from openlp.core.common.i18n import translate
from openlp.core.version import get_version
from .aboutdialog import UiAboutDialog

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,12 +23,10 @@
This module contains the first time wizard.
"""
import logging
import os
import socket
import time
import urllib.request
import urllib.parse
import urllib.error
import urllib.parse
import urllib.request
from configparser import ConfigParser, MissingSectionHeaderError, NoOptionError, NoSectionError
from tempfile import gettempdir
@ -36,54 +34,55 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common import clean_button_text, trace_error_handler
from openlp.core.common.applocation import AppLocation
from openlp.core.common.httputils import get_web_page, get_url_file_size, download_file
from openlp.core.common.i18n import translate
from openlp.core.common.path import Path, create_paths
from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import Path, create_paths
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
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
from .firsttimewizard import UiFirstTimeWizard, FirstTimePage
from openlp.core.threading import ThreadWorker, run_thread, get_thread_worker, is_thread_finished
from openlp.core.ui.firsttimewizard import UiFirstTimeWizard, FirstTimePage
log = logging.getLogger(__name__)
class ThemeScreenshotWorker(QtCore.QObject):
class ThemeScreenshotWorker(ThreadWorker):
"""
This thread downloads a theme's screenshot
"""
screenshot_downloaded = QtCore.pyqtSignal(str, str, str)
finished = QtCore.pyqtSignal()
def __init__(self, themes_url, title, filename, sha256, screenshot):
"""
Set up the worker object
"""
self.was_download_cancelled = False
self.was_cancelled = False
self.themes_url = themes_url
self.title = title
self.filename = filename
self.sha256 = sha256
self.screenshot = screenshot
socket.setdefaulttimeout(CONNECTION_TIMEOUT)
super(ThemeScreenshotWorker, self).__init__()
super().__init__()
def run(self):
def start(self):
"""
Overridden method to run the thread.
Run the worker
"""
if self.was_download_cancelled:
if self.was_cancelled:
return
try:
urllib.request.urlretrieve('{host}{name}'.format(host=self.themes_url, name=self.screenshot),
os.path.join(gettempdir(), 'openlp', self.screenshot))
# Signal that the screenshot has been downloaded
self.screenshot_downloaded.emit(self.title, self.filename, self.sha256)
except:
download_path = Path(gettempdir()) / 'openlp' / self.screenshot
is_success = download_file(self, '{host}{name}'.format(host=self.themes_url, name=self.screenshot),
download_path)
if is_success and not self.was_cancelled:
# Signal that the screenshot has been downloaded
self.screenshot_downloaded.emit(self.title, self.filename, self.sha256)
except: # noqa
log.exception('Unable to download screenshot')
finally:
self.finished.emit()
self.quit.emit()
@QtCore.pyqtSlot(bool)
def set_download_canceled(self, toggle):
@ -145,12 +144,13 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
return FirstTimePage.Progress
elif self.currentId() == FirstTimePage.Themes:
self.application.set_busy_cursor()
while not all([thread.isFinished() for thread in self.theme_screenshot_threads]):
while not all([is_thread_finished(thread_name) for thread_name in self.theme_screenshot_threads]):
time.sleep(0.1)
self.application.process_events()
# Build the screenshot icons, as this can not be done in the thread.
self._build_theme_screenshots()
self.application.set_normal_cursor()
self.theme_screenshot_threads = []
return FirstTimePage.Defaults
else:
return self.get_next_page_id()
@ -171,7 +171,6 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
self.screens = screens
self.was_cancelled = False
self.theme_screenshot_threads = []
self.theme_screenshot_workers = []
self.has_run_wizard = False
def _download_index(self):
@ -256,14 +255,10 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
sha256 = self.config.get('theme_{theme}'.format(theme=theme), 'sha256', fallback='')
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
worker = ThemeScreenshotWorker(self.themes_url, title, filename, sha256, screenshot)
self.theme_screenshot_workers.append(worker)
worker.screenshot_downloaded.connect(self.on_screenshot_downloaded)
thread = QtCore.QThread(self)
self.theme_screenshot_threads.append(thread)
thread.started.connect(worker.run)
worker.finished.connect(thread.quit)
worker.moveToThread(thread)
thread.start()
thread_name = 'theme_screenshot_{title}'.format(title=title)
run_thread(worker, thread_name)
self.theme_screenshot_threads.append(thread_name)
self.application.process_events()
def set_defaults(self):
@ -353,12 +348,14 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
Process the triggering of the cancel button.
"""
self.was_cancelled = True
if self.theme_screenshot_workers:
for worker in self.theme_screenshot_workers:
worker.set_download_canceled(True)
if self.theme_screenshot_threads:
for thread_name in self.theme_screenshot_threads:
worker = get_thread_worker(thread_name)
if worker:
worker.set_download_canceled(True)
# Was the thread created.
if self.theme_screenshot_threads:
while any([thread.isRunning() for thread in self.theme_screenshot_threads]):
while any([not is_thread_finished(thread_name) for thread_name in self.theme_screenshot_threads]):
time.sleep(0.1)
self.application.set_normal_cursor()
@ -401,7 +398,7 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
screenshot = self.config.get('theme_{theme}'.format(theme=theme), 'screenshot')
item = self.themes_list_widget.item(index)
if item:
item.setIcon(build_icon(os.path.join(gettempdir(), 'openlp', screenshot)))
item.setIcon(build_icon(Path(gettempdir(), 'openlp', screenshot)))
def _download_progress(self, count, block_size):
"""
@ -550,9 +547,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
Download selected songs, bibles and themes. Returns False on download error
"""
# Build directories for downloads
songs_destination = os.path.join(gettempdir(), 'openlp')
bibles_destination = str(AppLocation.get_section_data_path('bibles'))
themes_destination = str(AppLocation.get_section_data_path('themes'))
songs_destination_path = Path(gettempdir(), 'openlp')
bibles_destination_path = AppLocation.get_section_data_path('bibles')
themes_destination_path = AppLocation.get_section_data_path('themes')
missed_files = []
# Download songs
for i in range(self.songs_list_widget.count()):
@ -561,9 +558,9 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
filename, sha256 = item.data(QtCore.Qt.UserRole)
self._increment_progress_bar(self.downloading.format(name=filename), 0)
self.previous_size = 0
destination = Path(songs_destination, str(filename))
if not url_get_file(self, '{path}{name}'.format(path=self.songs_url, name=filename),
destination, sha256):
destination = songs_destination_path / str(filename)
if not download_file(self, '{path}{name}'.format(path=self.songs_url, name=filename),
destination, sha256):
missed_files.append('Song: {name}'.format(name=filename))
# Download Bibles
bibles_iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget)
@ -573,9 +570,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
bible, sha256 = item.data(0, QtCore.Qt.UserRole)
self._increment_progress_bar(self.downloading.format(name=bible), 0)
self.previous_size = 0
if not url_get_file(self, '{path}{name}'.format(path=self.bibles_url, name=bible),
Path(bibles_destination, bible),
sha256):
if not download_file(self, '{path}{name}'.format(path=self.bibles_url, name=bible),
bibles_destination_path / bible, sha256):
missed_files.append('Bible: {name}'.format(name=bible))
bibles_iterator += 1
# Download themes
@ -585,9 +581,8 @@ class FirstTimeForm(QtWidgets.QWizard, UiFirstTimeWizard, RegistryProperties):
theme, sha256 = item.data(QtCore.Qt.UserRole)
self._increment_progress_bar(self.downloading.format(name=theme), 0)
self.previous_size = 0
if not url_get_file(self, '{path}{name}'.format(path=self.themes_url, name=theme),
Path(themes_destination, theme),
sha256):
if not download_file(self, '{path}{name}'.format(path=self.themes_url, name=theme),
themes_destination_path / theme, sha256):
missed_files.append('Theme: {name}'.format(name=theme))
if missed_files:
file_list = ''

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -28,8 +28,8 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common.i18n import translate
from openlp.core.lib import FormattingTags
from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog
from openlp.core.ui.formattingtagcontroller import FormattingTagController
from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog
class EditColumn(object):

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,10 +23,7 @@
This is the main window, where all the action happens.
"""
import logging
import os
import shutil
import sys
import time
from datetime import datetime
from distutils import dir_util
from distutils.errors import DistutilsFileError
@ -40,8 +37,8 @@ from openlp.core.common import is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
from openlp.core.common.path import Path, copyfile, create_paths
from openlp.core.common.mixins import RegistryProperties
from openlp.core.common.path import Path, copyfile, create_paths
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.display.screens import ScreenList
@ -59,7 +56,6 @@ from openlp.core.version import get_version
from openlp.core.widgets.dialogs import FileDialog
from openlp.core.widgets.docks import OpenLPDockWidget, MediaDockManager
log = logging.getLogger(__name__)
@ -481,8 +477,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
"""
super(MainWindow, self).__init__()
Registry().register('main_window', self)
self.version_thread = None
self.version_worker = None
self.clipboard = self.application.clipboard()
self.arguments = ''.join(self.application.args)
# Set up settings sections for the main application (not for use by plugins).
@ -504,8 +498,8 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
Settings().set_up_default_values()
self.about_form = AboutForm(self)
MediaController()
websockets.WebSocketServer()
server.HttpServer()
self.ws_server = websockets.WebSocketServer()
self.http_server = server.HttpServer(self)
SettingsForm(self)
self.formatting_tag_form = FormattingTagForm(self)
self.shortcut_form = ShortcutListForm(self)
@ -551,6 +545,41 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
# Reset the cursor
self.application.set_normal_cursor()
def _wait_for_threads(self):
"""
Wait for the threads
"""
# Sometimes the threads haven't finished, let's wait for them
wait_dialog = QtWidgets.QProgressDialog('Waiting for some things to finish...', '', 0, 0, self)
wait_dialog.setWindowModality(QtCore.Qt.WindowModal)
wait_dialog.setAutoClose(False)
wait_dialog.setCancelButton(None)
wait_dialog.show()
for thread_name in self.application.worker_threads.keys():
log.debug('Waiting for thread %s', thread_name)
self.application.processEvents()
thread = self.application.worker_threads[thread_name]['thread']
worker = self.application.worker_threads[thread_name]['worker']
try:
if worker and hasattr(worker, 'stop'):
# If the worker has a stop method, run it
worker.stop()
if thread and thread.isRunning():
# If the thread is running, let's wait 5 seconds for it
retry = 0
while thread.isRunning() and retry < 50:
# Make the GUI responsive while we wait
self.application.processEvents()
thread.wait(100)
retry += 1
if thread.isRunning():
# If the thread is still running after 5 seconds, kill it
thread.terminate()
except RuntimeError:
# Ignore the RuntimeError that is thrown when Qt has already deleted the C++ thread object
pass
wait_dialog.close()
def bootstrap_post_set_up(self):
"""
process the bootstrap post setup request
@ -697,7 +726,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
# Update the theme widget
self.theme_manager_contents.load_themes()
# Check if any Bibles downloaded. If there are, they will be processed.
Registry().execute('bibles_load_list', True)
Registry().execute('bibles_load_list')
self.application.set_normal_cursor()
def is_display_blank(self):
@ -1002,39 +1031,14 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
if not self.application.is_event_loop_active:
event.ignore()
return
# Sometimes the version thread hasn't finished, let's wait for it
try:
if self.version_thread and self.version_thread.isRunning():
wait_dialog = QtWidgets.QProgressDialog('Waiting for some things to finish...', '', 0, 0, self)
wait_dialog.setWindowModality(QtCore.Qt.WindowModal)
wait_dialog.setAutoClose(False)
wait_dialog.setCancelButton(None)
wait_dialog.show()
retry = 0
while self.version_thread.isRunning() and retry < 50:
self.application.processEvents()
self.version_thread.wait(100)
retry += 1
if self.version_thread.isRunning():
self.version_thread.terminate()
wait_dialog.close()
except RuntimeError:
# Ignore the RuntimeError that is thrown when Qt has already deleted the C++ thread object
pass
# If we just did a settings import, close without saving changes.
if self.settings_imported:
self.clean_up(False)
event.accept()
if self.service_manager_contents.is_modified():
ret = self.service_manager_contents.save_modified_service()
if ret == QtWidgets.QMessageBox.Save:
if self.service_manager_contents.decide_save_method():
self.clean_up()
event.accept()
else:
event.ignore()
elif ret == QtWidgets.QMessageBox.Discard:
self.clean_up()
event.accept()
else:
event.ignore()
@ -1050,13 +1054,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
close_button.setText(translate('OpenLP.MainWindow', '&Exit OpenLP'))
msg_box.setDefaultButton(QtWidgets.QMessageBox.Close)
if msg_box.exec() == QtWidgets.QMessageBox.Close:
self.clean_up()
event.accept()
else:
event.ignore()
else:
self.clean_up()
event.accept()
if event.isAccepted():
# Wait for all the threads to complete
self._wait_for_threads()
# If we just did a settings import, close without saving changes.
self.clean_up(save_settings=not self.settings_imported)
def clean_up(self, save_settings=True):
"""
@ -1064,9 +1071,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, RegistryProperties):
:param save_settings: Switch to prevent saving settings. Defaults to **True**.
"""
self.image_manager.stop_manager = True
while self.image_manager.image_thread.isRunning():
time.sleep(0.1)
if save_settings:
if Settings().value('advanced/save current plugin'):
Settings().setValue('advanced/current media plugin', self.media_tool_box.currentIndex())

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,8 +24,8 @@ The :mod:`~openlp.core.api.endpoint` module contains various API endpoints
"""
import logging
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.api.http import requires_auth
from openlp.core.api.http.endpoint import Endpoint
from openlp.core.common.registry import Registry
log = logging.getLogger(__name__)

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -23,9 +23,10 @@
The :mod:`~openlp.core.ui.media.mediacontroller` module contains a base class for media components and other widgets
related to playing media, such as sliders.
"""
import datetime
import logging
import os
import datetime
from PyQt5 import QtCore, QtWidgets
from openlp.core.api.http import register_endpoint
@ -37,14 +38,13 @@ from openlp.core.common.settings import Settings
from openlp.core.lib import ItemCapabilities
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import DisplayControllerType
from openlp.core.ui.media.endpoint import media_endpoint
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
from openlp.core.ui.media.mediaplayer import MediaPlayer
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players,\
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players, \
parse_optical_path
from openlp.core.ui.media.endpoint import media_endpoint
from openlp.core.ui.media.mediaplayer import MediaPlayer
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
from openlp.core.widgets.toolbar import OpenLPToolbar
log = logging.getLogger(__name__)
TICK_TIME = 200
@ -181,7 +181,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
"""
log.debug('_check_available_media_players')
controller_dir = os.path.join('core', 'ui', 'media')
glob_pattern = os.path.join(controller_dir, '*player.py')
# Find all files that do not begin with '.' (lp:#1738047) and end with player.py
glob_pattern = os.path.join(controller_dir, '[!.]*player.py')
extension_loader(glob_pattern, ['mediaplayer.py'])
player_classes = MediaPlayer.__subclasses__()
for player_class in player_classes:

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -31,7 +31,7 @@ from PyQt5 import QtCore, QtMultimedia, QtMultimediaWidgets
from openlp.core.common.i18n import translate
from openlp.core.ui.media import MediaState
from openlp.core.ui.media.mediaplayer import MediaPlayer
from openlp.core.threading import ThreadWorker, run_thread, is_thread_finished
log = logging.getLogger(__name__)
@ -294,39 +294,38 @@ class SystemPlayer(MediaPlayer):
:param path: Path to file to be checked
:return: True if file can be played otherwise False
"""
thread = QtCore.QThread()
check_media_worker = CheckMediaWorker(path)
check_media_worker.setVolume(0)
check_media_worker.moveToThread(thread)
check_media_worker.finished.connect(thread.quit)
thread.started.connect(check_media_worker.play)
thread.start()
while thread.isRunning():
run_thread(check_media_worker, 'check_media')
while not is_thread_finished('check_media'):
self.application.processEvents()
return check_media_worker.result
class CheckMediaWorker(QtMultimedia.QMediaPlayer):
class CheckMediaWorker(QtMultimedia.QMediaPlayer, ThreadWorker):
"""
Class used to check if a media file is playable
"""
finished = QtCore.pyqtSignal()
def __init__(self, path):
super(CheckMediaWorker, self).__init__(None, QtMultimedia.QMediaPlayer.VideoSurface)
self.result = None
self.path = path
def start(self):
"""
Start the thread worker
"""
self.result = None
self.error.connect(functools.partial(self.signals, 'error'))
self.mediaStatusChanged.connect(functools.partial(self.signals, 'media'))
self.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(path)))
self.setMedia(QtMultimedia.QMediaContent(QtCore.QUrl.fromLocalFile(self.path)))
self.play()
def signals(self, origin, status):
if origin == 'media' and status == self.BufferedMedia:
self.result = True
self.stop()
self.finished.emit()
self.quit.emit()
elif origin == 'error' and status != self.NoError:
self.result = False
self.stop()
self.finished.emit()
self.quit.emit()

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -40,11 +40,10 @@ C{get_instance} method of L{MediaPlayer} and L{MediaListPlayer}.
"""
import ctypes
from ctypes.util import find_library
import functools
import os
import sys
import functools
from ctypes.util import find_library
# Used by EventManager in override.py
from inspect import getargspec

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -22,13 +22,14 @@
"""
The :mod:`~openlp.core.ui.media.vlcplayer` module contains our VLC component wrapper
"""
from datetime import datetime
from distutils.version import LooseVersion
import ctypes
import logging
import os
import threading
import sys
import ctypes
import threading
from datetime import datetime
from distutils.version import LooseVersion
from PyQt5 import QtWidgets
from openlp.core.common import is_win, is_macosx, is_linux

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -24,8 +24,8 @@ The actual print service dialog
"""
import datetime
import html
import lxml.html
import lxml.html
from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport
from openlp.core.common.applocation import AppLocation

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -370,7 +370,7 @@ class ServiceManager(QtWidgets.QWidget, RegistryBase, Ui_ServiceManager, LogMixi
:rtype: None
"""
self._service_path = file_path
self.main_window.set_service_modified(self.is_modified(), file_path.name)
self.set_modified(self.is_modified())
Settings().setValue('servicemanager/last file', file_path)
if file_path and file_path.suffix == '.oszl':
self._save_lite = True

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #
@ -43,7 +43,6 @@ from openlp.core.display.window import DisplayWindow
from openlp.core.widgets.toolbar import OpenLPToolbar
from openlp.core.widgets.views import ListPreviewWidget
# Threshold which has to be trespassed to toggle.
HIDE_MENU_THRESHOLD = 27
AUDIO_TIME_LABEL_STYLESHEET = 'background-color: palette(background); ' \

View File

@ -4,7 +4,7 @@
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2017 OpenLP Developers #
# Copyright (c) 2008-2018 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 #

Some files were not shown because too many files have changed in this diff Show More