forked from openlp/openlp
HEAD
This commit is contained in:
commit
7490c7ad1e
@ -47,4 +47,5 @@ htmlcov
|
||||
node_modules
|
||||
openlp-test-projectordb.sqlite
|
||||
package-lock.json
|
||||
.cache
|
||||
test
|
||||
|
@ -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 #
|
||||
|
@ -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__':
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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']
|
||||
|
@ -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')
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -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 #
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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')
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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.
|
||||
"""
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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__)
|
||||
|
||||
|
||||
|
@ -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')
|
||||
|
@ -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__)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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__)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
"""
|
||||
|
@ -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 #
|
||||
|
@ -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(
|
||||
|
@ -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 #
|
||||
|
@ -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 = []
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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__)
|
||||
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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')
|
||||
|
@ -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
@ -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__)
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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'))
|
||||
|
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 = ''
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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):
|
||||
|
@ -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 #
|
||||
|
@ -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())
|
||||
|
@ -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 #
|
||||
|
@ -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__)
|
||||
|
@ -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:
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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()
|
||||
|
2
openlp/core/ui/media/vendor/__init__.py
vendored
2
openlp/core/ui/media/vendor/__init__.py
vendored
@ -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 #
|
||||
|
@ -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 #
|
||||
|
5
openlp/core/ui/media/vendor/vlc.py
vendored
5
openlp/core/ui/media/vendor/vlc.py
vendored
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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 #
|
||||
|
@ -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); ' \
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user