diff --git a/openlp/core/ui/pluginform.py b/openlp/core/ui/pluginform.py
index 91b98b97a..78bdee4a5 100644
--- a/openlp/core/ui/pluginform.py
+++ b/openlp/core/ui/pluginform.py
@@ -30,7 +30,6 @@
The actual plugin view form
"""
import logging
-import os
from PyQt4 import QtGui
diff --git a/openlp/plugins/remotes/lib/httprouter.py b/openlp/plugins/remotes/lib/httprouter.py
index 5a10a14ae..4241b34dc 100644
--- a/openlp/plugins/remotes/lib/httprouter.py
+++ b/openlp/plugins/remotes/lib/httprouter.py
@@ -149,11 +149,11 @@ class HttpRouter(RegistryProperties):
"""
Initialise the router stack and any other variables.
"""
- authcode = "%s:%s" % (Settings().value('remotes/user id'), Settings().value('remotes/password'))
+ auth_code = "%s:%s" % (Settings().value('remotes/user id'), Settings().value('remotes/password'))
try:
- self.auth = base64.b64encode(authcode)
+ self.auth = base64.b64encode(auth_code)
except TypeError:
- self.auth = base64.b64encode(authcode.encode()).decode()
+ self.auth = base64.b64encode(auth_code.encode()).decode()
self.routes = [
('^/$', {'function': self.serve_file, 'secure': False}),
('^/(stage)$', {'function': self.serve_file, 'secure': False}),
@@ -376,7 +376,6 @@ class HttpRouter(RegistryProperties):
Examines the extension of the file and determines what the content_type should be, defaults to text/plain
Returns the extension and the content_type
"""
- content_type = 'text/plain'
ext = os.path.splitext(file_name)[1]
content_type = FILE_TYPES.get(ext, 'text/plain')
return ext, content_type
@@ -439,7 +438,7 @@ class HttpRouter(RegistryProperties):
if plugin.status == PluginStatus.Active:
try:
text = json.loads(self.request_data)['request']['text']
- except KeyError as ValueError:
+ except KeyError:
return self.do_http_error()
text = urllib.parse.unquote(text)
self.alerts_manager.emit(QtCore.SIGNAL('alerts_text'), [text])
@@ -453,6 +452,7 @@ class HttpRouter(RegistryProperties):
"""
Perform an action on the slide controller.
"""
+ log.debug("controller_text var = %s" % var)
current_item = self.live_controller.service_item
data = []
if current_item:
@@ -488,7 +488,7 @@ class HttpRouter(RegistryProperties):
if self.request_data:
try:
data = json.loads(self.request_data)['request']['id']
- except KeyError as ValueError:
+ except KeyError:
return self.do_http_error()
log.info(data)
# This slot expects an int within a list.
@@ -547,7 +547,7 @@ class HttpRouter(RegistryProperties):
"""
try:
text = json.loads(self.request_data)['request']['text']
- except KeyError as ValueError:
+ except KeyError:
return self.do_http_error()
text = urllib.parse.unquote(text)
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
@@ -563,12 +563,12 @@ class HttpRouter(RegistryProperties):
Go live on an item of type ``plugin``.
"""
try:
- id = json.loads(self.request_data)['request']['id']
- except KeyError as ValueError:
+ request_id = json.loads(self.request_data)['request']['id']
+ except KeyError:
return self.do_http_error()
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
if plugin.status == PluginStatus.Active and plugin.media_item:
- plugin.media_item.emit(QtCore.SIGNAL('%s_go_live' % plugin_name), [id, True])
+ plugin.media_item.emit(QtCore.SIGNAL('%s_go_live' % plugin_name), [request_id, True])
return self.do_http_success()
def add_to_service(self, plugin_name):
@@ -576,11 +576,11 @@ class HttpRouter(RegistryProperties):
Add item of type ``plugin_name`` to the end of the service.
"""
try:
- id = json.loads(self.request_data)['request']['id']
- except KeyError as ValueError:
+ request_id = json.loads(self.request_data)['request']['id']
+ except KeyError:
return self.do_http_error()
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
if plugin.status == PluginStatus.Active and plugin.media_item:
- item_id = plugin.media_item.create_item_from_id(id)
+ item_id = plugin.media_item.create_item_from_id(request_id)
plugin.media_item.emit(QtCore.SIGNAL('%s_add_to_service' % plugin_name), [item_id, True])
self.do_http_success()
diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py
index 22d0349f8..9a904090d 100644
--- a/openlp/plugins/remotes/lib/httpserver.py
+++ b/openlp/plugins/remotes/lib/httpserver.py
@@ -40,7 +40,7 @@ import time
from PyQt4 import QtCore
-from openlp.core.common import AppLocation, Settings
+from openlp.core.common import AppLocation, Settings, RegistryProperties
from openlp.plugins.remotes.lib import HttpRouter
@@ -94,13 +94,18 @@ class HttpThread(QtCore.QThread):
"""
self.http_server.start_server()
+ def stop(self):
+ log.debug("stop called")
+ self.http_server.stop = True
-class OpenLPServer():
+
+class OpenLPServer(RegistryProperties):
def __init__(self):
"""
Initialise the http server, and start the server of the correct type http / https
"""
- log.debug('Initialise httpserver')
+ super(OpenLPServer, self).__init__()
+ log.debug('Initialise OpenLP')
self.settings_section = 'remotes'
self.http_thread = HttpThread(self)
self.http_thread.start()
@@ -110,32 +115,49 @@ class OpenLPServer():
Start the correct server and save the handler
"""
address = Settings().value(self.settings_section + '/ip address')
- if Settings().value(self.settings_section + '/https enabled'):
+ self.address = address
+ self.is_secure = Settings().value(self.settings_section + '/https enabled')
+ self.needs_authentication = Settings().value(self.settings_section + '/authentication enabled')
+ if self.is_secure:
port = Settings().value(self.settings_section + '/https port')
- self.httpd = HTTPSServer((address, port), CustomHandler)
- log.debug('Started ssl httpd...')
+ self.port = port
+ self.start_server_instance(address, port, HTTPSServer)
else:
port = Settings().value(self.settings_section + '/port')
- loop = 1
- while loop < 3:
- try:
- self.httpd = ThreadingHTTPServer((address, port), CustomHandler)
- except OSError:
- loop += 1
- time.sleep(0.1)
- except:
- log.error('Failed to start server ')
- log.debug('Started non ssl httpd...')
+ self.port = port
+ self.start_server_instance(address, port, ThreadingHTTPServer)
if hasattr(self, 'httpd') and self.httpd:
self.httpd.serve_forever()
else:
log.debug('Failed to start server')
+ def start_server_instance(self, address, port, server_class):
+ """
+ Start the server
+
+ :param address: The server address
+ :param port: The run port
+ :param server_class: the class to start
+ """
+ loop = 1
+ while loop < 4:
+ try:
+ self.httpd = server_class((address, port), CustomHandler)
+ log.debug("Server started for class %s %s %d" % (server_class, address, port))
+ except OSError:
+ log.debug("failed to start http server thread state %d %s" %
+ (loop, self.http_thread.isRunning()))
+ loop += 1
+ time.sleep(0.1)
+ except:
+ log.error('Failed to start server ')
+
def stop_server(self):
"""
Stop the server
"""
- self.http_thread.exit(0)
+ if self.http_thread.isRunning():
+ self.http_thread.stop()
self.httpd = None
log.debug('Stopped the server.')
diff --git a/openlp/plugins/remotes/lib/remotetab.py b/openlp/plugins/remotes/lib/remotetab.py
index d6b96cc1c..4db25cfc2 100644
--- a/openlp/plugins/remotes/lib/remotetab.py
+++ b/openlp/plugins/remotes/lib/remotetab.py
@@ -32,7 +32,7 @@ import os.path
from PyQt4 import QtCore, QtGui, QtNetwork
from openlp.core.common import AppLocation, Settings, translate
-from openlp.core.lib import SettingsTab
+from openlp.core.lib import SettingsTab, build_icon
ZERO_URL = '0.0.0.0'
@@ -234,6 +234,7 @@ class RemoteTab(SettingsTab):
"""
Load the configuration and update the server configuration if necessary
"""
+ self.is_secure = Settings().value(self.settings_section + '/https enabled')
self.port_spin_box.setValue(Settings().value(self.settings_section + '/port'))
self.https_port_spin_box.setValue(Settings().value(self.settings_section + '/https port'))
self.address_edit.setText(Settings().value(self.settings_section + '/ip address'))
@@ -263,9 +264,7 @@ class RemoteTab(SettingsTab):
Settings().value(self.settings_section + '/port') != self.port_spin_box.value() or \
Settings().value(self.settings_section + '/https port') != self.https_port_spin_box.value() or \
Settings().value(self.settings_section + '/https enabled') != \
- self.https_settings_group_box.isChecked() or \
- Settings().value(self.settings_section + '/authentication enabled') != \
- self.user_login_group_box.isChecked():
+ self.https_settings_group_box.isChecked():
self.settings_form.register_post_process('remotes_config_updated')
Settings().setValue(self.settings_section + '/port', self.port_spin_box.value())
Settings().setValue(self.settings_section + '/https port', self.https_port_spin_box.value())
@@ -275,6 +274,7 @@ class RemoteTab(SettingsTab):
Settings().setValue(self.settings_section + '/authentication enabled', self.user_login_group_box.isChecked())
Settings().setValue(self.settings_section + '/user id', self.user_id.text())
Settings().setValue(self.settings_section + '/password', self.password.text())
+ self.generate_icon()
def on_twelve_hour_check_box_changed(self, check_state):
"""
@@ -290,3 +290,25 @@ class RemoteTab(SettingsTab):
Invert the HTTP group box based on Https group settings
"""
self.http_settings_group_box.setEnabled(not self.https_settings_group_box.isChecked())
+
+ def generate_icon(self):
+ """
+ Generate icon for main window
+ """
+ self.remote_server_icon.hide()
+ icon = QtGui.QImage(':/remote/network_server.png')
+ icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
+ if self.is_secure:
+ overlay = QtGui.QImage(':/remote/network_ssl.png')
+ overlay = overlay.scaled(60, 60, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
+ painter = QtGui.QPainter(icon)
+ painter.drawImage(0, 0, overlay)
+ painter.end()
+ if Settings().value(self.settings_section + '/authentication enabled'):
+ overlay = QtGui.QImage(':/remote/network_auth.png')
+ overlay = overlay.scaled(60, 60, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
+ painter = QtGui.QPainter(icon)
+ painter.drawImage(20, 0, overlay)
+ painter.end()
+ self.remote_server_icon.setPixmap(QtGui.QPixmap.fromImage(icon))
+ self.remote_server_icon.show()
diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py
index d3dc6e58a..582192df4 100644
--- a/openlp/plugins/remotes/remoteplugin.py
+++ b/openlp/plugins/remotes/remoteplugin.py
@@ -28,7 +28,8 @@
###############################################################################
import logging
-import time
+
+from PyQt4 import QtGui
from openlp.core.lib import Plugin, StringContent, translate, build_icon
from openlp.plugins.remotes.lib import RemoteTab, OpenLPServer
@@ -67,6 +68,21 @@ class RemotesPlugin(Plugin):
log.debug('initialise')
super(RemotesPlugin, self).initialise()
self.server = OpenLPServer()
+ if not hasattr(self, 'remote_server_icon'):
+ self.remote_server_icon = QtGui.QLabel(self.main_window.status_bar)
+ size_policy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+ size_policy.setHorizontalStretch(0)
+ size_policy.setVerticalStretch(0)
+ size_policy.setHeightForWidth(self.remote_server_icon.sizePolicy().hasHeightForWidth())
+ self.remote_server_icon.setSizePolicy(size_policy)
+ self.remote_server_icon.setFrameShadow(QtGui.QFrame.Plain)
+ self.remote_server_icon.setLineWidth(1)
+ self.remote_server_icon.setScaledContents(True)
+ self.remote_server_icon.setFixedSize(20, 20)
+ self.remote_server_icon.setObjectName('remote_server_icon')
+ self.main_window.status_bar.insertPermanentWidget(2, self.remote_server_icon)
+ self.settings_tab.remote_server_icon = self.remote_server_icon
+ self.settings_tab.generate_icon()
def finalise(self):
"""
@@ -104,9 +120,11 @@ class RemotesPlugin(Plugin):
def config_update(self):
"""
- Called when Config is changed to restart the server on new address or port
+ Called when Config is changed to requests a restart with the server on new address or port
"""
log.debug('remote config changed')
- self.finalise()
- time.sleep(0.5)
- self.initialise()
+ QtGui.QMessageBox.information(self.main_window,
+ translate('RemotePlugin', 'Server Config Change'),
+ translate('RemotePlugin', 'Server configuration changes will require a restart '
+ 'to take effect.'),
+ QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
diff --git a/resources/images/network_auth.png b/resources/images/network_auth.png
new file mode 100644
index 000000000..45e7a5c17
Binary files /dev/null and b/resources/images/network_auth.png differ
diff --git a/resources/images/network_server.png b/resources/images/network_server.png
new file mode 100644
index 000000000..25b95f3b0
Binary files /dev/null and b/resources/images/network_server.png differ
diff --git a/resources/images/network_ssl.png b/resources/images/network_ssl.png
new file mode 100644
index 000000000..1169de67a
Binary files /dev/null and b/resources/images/network_ssl.png differ
diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc
index 6af0e77a5..79036f08f 100644
--- a/resources/images/openlp-2.qrc
+++ b/resources/images/openlp-2.qrc
@@ -149,6 +149,11 @@
messagebox_info.png
messagebox_warning.png
+
+ network_server.png
+ network_ssl.png
+ network_auth.png
+
song_usage_active.png
song_usage_inactive.png
diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py
index aaee9a71b..eeafbfe23 100644
--- a/scripts/jenkins_script.py
+++ b/scripts/jenkins_script.py
@@ -148,7 +148,7 @@ class JenkinsTrigger(object):
def get_repo_name():
"""
- This returns the name of branch of the wokring directory. For example it returns *lp:~googol/openlp/render*.
+ This returns the name of branch of the working directory. For example it returns *lp:~googol/openlp/render*.
"""
# Run the bzr command.
bzr = Popen(('bzr', 'info'), stdout=PIPE, stderr=PIPE)
@@ -198,7 +198,7 @@ def main():
jenkins_trigger = JenkinsTrigger(token)
try:
jenkins_trigger.trigger_build()
- except HTTPError as e:
+ except HTTPError:
print('Wrong token.')
return
# Open the browser before printing the output.
diff --git a/tests/functional/openlp_core_lib/test_file_dialog.py b/tests/functional/openlp_core_lib/test_file_dialog.py
index 3120f48fa..ab7663a83 100644
--- a/tests/functional/openlp_core_lib/test_file_dialog.py
+++ b/tests/functional/openlp_core_lib/test_file_dialog.py
@@ -53,8 +53,8 @@ class TestFileDialog(TestCase):
self.mocked_os.rest()
self.mocked_qt_gui.reset()
- # GIVEN: A List of known values as a return value from QFileDialog.getOpenFileNames and a list of valid
- # file names.
+ # GIVEN: A List of known values as a return value from QFileDialog.getOpenFileNames and a list of valid file
+ # names.
self.mocked_qt_gui.QFileDialog.getOpenFileNames.return_value = [
'/Valid File', '/url%20encoded%20file%20%231', '/non-existing']
self.mocked_os.path.exists.side_effect = lambda file_name: file_name in [