diff --git a/openlp/core/api/tab.py b/openlp/core/api/tab.py index 9b741696b..ff57d5d9a 100644 --- a/openlp/core/api/tab.py +++ b/openlp/core/api/tab.py @@ -188,11 +188,6 @@ class ApiTab(SettingsTab): self.server_websocket_state = QtWidgets.QLabel(self.server_state_group_box) self.server_websocket_state.setObjectName('server_websocket_state') self.server_state_layout.addRow(self.server_websocket_state_title, self.server_websocket_state) - self.server_zeroconf_state_title = QtWidgets.QLabel(self.server_state_group_box) - self.server_zeroconf_state_title.setObjectName('server_zeroconf_state_title') - self.server_zeroconf_state = QtWidgets.QLabel(self.server_state_group_box) - self.server_zeroconf_state.setObjectName('server_zeroconf_state') - self.server_state_layout.addRow(self.server_zeroconf_state_title, self.server_zeroconf_state) self.left_layout.addStretch() self.right_layout.addStretch() @@ -233,7 +228,6 @@ class ApiTab(SettingsTab): self.server_state_group_box.setTitle(translate('RemotePlugin.RemoteTab', 'Server Status')) self.server_http_state_title.setText(translate('RemotePlugin.RemoteTab', 'HTTP Server:')) self.server_websocket_state_title.setText(translate('RemotePlugin.RemoteTab', 'Websocket Server:')) - self.server_zeroconf_state_title.setText(translate('RemotePlugin.RemoteTab', 'Zeroconf Server:')) self._server_up = translate('RemotePlugin.RemoteTab', 'Active', 'Server is active') self._server_down = translate('RemotePlugin.RemoteTab', 'Failed', 'Server failed') self._server_disabled = translate('RemotePlugin.RemoteTab', 'Disabled', 'Server is disabled') @@ -316,13 +310,6 @@ class ApiTab(SettingsTab): else: self.server_websocket_state.setText(self._server_down) - if not is_thread_finished('api_zeroconf'): - self.server_zeroconf_state.setText(self._server_up) - elif Registry().get_flag('no_web_server'): - self.server_zeroconf_state.setText(self._server_disabled) - else: - self.server_zeroconf_state.setText(self._server_down) - def get_ip_address(self, ip_address): """ returns the IP address in dependency of the passed address diff --git a/openlp/core/api/zeroconf.py b/openlp/core/api/zeroconf.py deleted file mode 100644 index f2d65c350..000000000 --- a/openlp/core/api/zeroconf.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- - -########################################################################## -# OpenLP - Open Source Lyrics Projection # -# ---------------------------------------------------------------------- # -# Copyright (c) 2008-2022 OpenLP Developers # -# ---------------------------------------------------------------------- # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -########################################################################## -""" -The :mod:`~openlp.core.api.zeroconf` module runs a Zerconf server so that OpenLP can advertise the -RESTful API for devices on the network to discover. -""" -import socket -from time import sleep - -from zeroconf import ServiceInfo, Zeroconf, Error, NonUniqueNameException - -from openlp.core.common import get_network_interfaces -from openlp.core.common.i18n import UiStrings -from openlp.core.common.registry import Registry -from openlp.core.threading import ThreadWorker, run_thread - - -def _get_error_message(exc): - """ - Zeroconf doesn't have error messages, so we have to make up our own - """ - error_message = UiStrings().ZeroconfErrorIntro + '\n\n' - if isinstance(exc, NonUniqueNameException): - error_message += UiStrings().ZeroconfNonUniqueError - else: - error_message += UiStrings().ZeroconfGenericError - return error_message - - -class ZeroconfWorker(ThreadWorker): - """ - This thread worker runs a Zeroconf service - """ - ip_address = None - http_port = 4316 - ws_port = 4317 - _can_run = False - - def __init__(self, addresses, http_port=4316, ws_port=4317): - """ - Create the worker for the Zeroconf service - """ - super().__init__() - self.addresses = addresses - self.http_port = http_port - self.ws_port = ws_port - - def can_run(self): - """ - Check if the worker can continue to run. This is mostly so that we can override this method - and test the class. - """ - return self._can_run - - def start(self): - """ - Start the service - """ - addresses = [socket.inet_aton(addr) for addr in self.addresses] - http_info = ServiceInfo('_http._tcp.local.', 'OpenLP._http._tcp.local.', - addresses=addresses, port=self.http_port, properties={}) - ws_info = ServiceInfo('_ws._tcp.local.', 'OpenLP._ws._tcp.local.', - addresses=addresses, port=self.ws_port, properties={}) - zc = None - try: - zc = Zeroconf() - zc.register_service(http_info) - zc.register_service(ws_info) - self._can_run = True - while self.can_run(): - sleep(0.1) - except Error as e: - self.error.emit('Cannot start Zeroconf service', _get_error_message(e)) - except OSError as e: - self.error.emit('Cannot start Zeroconf service', str(e)) - finally: - if zc is not None: - zc.unregister_all_services() - zc.close() - self.quit.emit() - - def stop(self): - """ - Stop the service - """ - self._can_run = False - - -def start_zeroconf(): - """ - Start the Zeroconf service - """ - # When we're running tests, just skip this set up if this flag is set - if Registry().get_flag('no_web_server'): - return - http_port = Registry().get('settings_thread').value('api/port') - ws_port = Registry().get('settings_thread').value('api/websocket port') - worker = ZeroconfWorker([iface['ip'] for iface in get_network_interfaces().values()], http_port, ws_port) - run_thread(worker, 'api_zeroconf') diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 190841908..932a13b16 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -30,7 +30,6 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.api.http.server import HttpServer from openlp.core.api.websockets import WebSocketServer -from openlp.core.api.zeroconf import start_zeroconf from openlp.core.common import add_actions from openlp.core.common.actions import ActionList, CategoryOrder from openlp.core.common.applocation import AppLocation @@ -484,7 +483,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert self.ws_server = WebSocketServer() self.ws_server.start() self.http_server = HttpServer(self) - start_zeroconf() SettingsForm(self) self.formatting_tag_form = FormattingTagForm(self) self.shortcut_form = ShortcutListForm(self) diff --git a/tests/openlp_core/api/test_tab.py b/tests/openlp_core/api/test_tab.py index 31b6af8da..b538bf157 100644 --- a/tests/openlp_core/api/test_tab.py +++ b/tests/openlp_core/api/test_tab.py @@ -243,7 +243,6 @@ def test_set_server_states_up(mock_is_thread_finished, registry, settings, api_t # THEN: The servers should all be "up" assert api_tab.server_http_state.text() == 'Active' assert api_tab.server_websocket_state.text() == 'Active' - assert api_tab.server_zeroconf_state.text() == 'Active' @patch('openlp.core.api.tab.is_thread_finished') @@ -259,7 +258,6 @@ def test_set_server_states_disabled(mock_is_thread_finished, registry, settings, # THEN: The servers should all be "up" assert api_tab.server_http_state.text() == 'Disabled' assert api_tab.server_websocket_state.text() == 'Disabled' - assert api_tab.server_zeroconf_state.text() == 'Disabled' @patch('openlp.core.api.tab.is_thread_finished') @@ -275,7 +273,6 @@ def test_set_server_states_down(mock_is_thread_finished, registry, settings, api # THEN: The servers should all be "up" assert api_tab.server_http_state.text() == 'Failed' assert api_tab.server_websocket_state.text() == 'Failed' - assert api_tab.server_zeroconf_state.text() == 'Failed' @patch('openlp.core.api.tab.download_version_info') diff --git a/tests/openlp_core/api/test_zeroconf.py b/tests/openlp_core/api/test_zeroconf.py deleted file mode 100644 index acb97c64e..000000000 --- a/tests/openlp_core/api/test_zeroconf.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- - -########################################################################## -# OpenLP - Open Source Lyrics Projection # -# ---------------------------------------------------------------------- # -# Copyright (c) 2008-2022 OpenLP Developers # -# ---------------------------------------------------------------------- # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -########################################################################## -from unittest.mock import MagicMock, call, patch - -from openlp.core.api.zeroconf import ZeroconfWorker, start_zeroconf - - -def test_zeroconf_worker_constructor(): - """Test creating the Zeroconf worker object""" - # GIVEN: A ZeroconfWorker class - # WHEN: An instance of the ZeroconfWorker is created - worker = ZeroconfWorker(['127.0.0.1'], 8000, 8001) - - # THEN: The inet_aton function should have been called and the attrs should be set - assert worker.addresses == ['127.0.0.1'] - assert worker.http_port == 8000 - assert worker.ws_port == 8001 - - -@patch('openlp.core.api.zeroconf.ServiceInfo') -@patch('openlp.core.api.zeroconf.Zeroconf') -def test_zeroconf_worker_start(MockedZeroconf, MockedServiceInfo): - """Test the start() method of ZeroconfWorker""" - # GIVEN: A few mocks and a ZeroconfWorker instance with a mocked can_run method - mocked_http_info = MagicMock() - mocked_ws_info = MagicMock() - mocked_zc = MagicMock() - MockedServiceInfo.side_effect = [mocked_http_info, mocked_ws_info] - MockedZeroconf.return_value = mocked_zc - worker = ZeroconfWorker(['127.0.0.1'], 8000, 8001) - - # WHEN: The start() method is called - with patch.object(worker, 'can_run') as mocked_can_run: - mocked_can_run.side_effect = [True, False] - worker.start() - - # THEN: The correct calls are made - assert MockedServiceInfo.call_args_list == [ - call('_http._tcp.local.', 'OpenLP._http._tcp.local.', addresses=[b'\x7f\x00\x00\x01'], port=8000, - properties={}), - call('_ws._tcp.local.', 'OpenLP._ws._tcp.local.', addresses=[b'\x7f\x00\x00\x01'], port=8001, - properties={}) - ] - assert MockedZeroconf.call_count == 1 - assert mocked_zc.register_service.call_args_list == [call(mocked_http_info), call(mocked_ws_info)] - assert mocked_can_run.call_count == 2 - mocked_zc.unregister_all_services.assert_called_once_with() - mocked_zc.close.assert_called_once_with() - - -def test_zeroconf_worker_stop(): - """Test that the ZeroconfWorker.stop() method correctly stops the service""" - # GIVEN: A worker object with _can_run set to True - worker = ZeroconfWorker(['127.0.0.1'], 8000, 8001) - worker._can_run = True - - # WHEN: stop() is called - worker.stop() - - # THEN: _can_run should be False - assert worker.can_run() is False - - -@patch('openlp.core.api.zeroconf.get_network_interfaces') -@patch('openlp.core.api.zeroconf.Registry') -@patch('openlp.core.api.zeroconf.ZeroconfWorker') -@patch('openlp.core.api.zeroconf.run_thread') -def test_start_zeroconf(mocked_run_thread, MockedZeroconfWorker, MockedRegistry, mocked_get_network_interfaces): - """Test the start_zeroconf() function""" - # GIVEN: A whole bunch of stuff that's mocked out - mocked_get_network_interfaces.return_value = { - 'eth0': { - 'ip': '192.168.1.191', - 'broadcast': '192.168.1.255', - 'netmask': '255.255.255.0', - 'prefix': 24, - 'localnet': '192.168.1.0' - } - } - MockedRegistry.return_value.get_flag.return_value = False - MockedRegistry.settings.return_value.value.side_effect = [8000, 8001] - mocked_worker = MagicMock() - MockedZeroconfWorker.return_value = mocked_worker - - # WHEN: start_zeroconf() is called - start_zeroconf() - - # THEN: A worker is added to the list of threads - mocked_run_thread.assert_called_once_with(mocked_worker, 'api_zeroconf') diff --git a/tests/openlp_core/ui/test_mainwindow.py b/tests/openlp_core/ui/test_mainwindow.py index a17711ccc..1ef4570b0 100644 --- a/tests/openlp_core/ui/test_mainwindow.py +++ b/tests/openlp_core/ui/test_mainwindow.py @@ -99,7 +99,6 @@ def main_window_reduced(settings, state): patch('openlp.core.ui.mainwindow.ProjectorManager'), \ patch('openlp.core.ui.mainwindow.HttpServer'), \ patch('openlp.core.ui.mainwindow.WebSocketServer'), \ - patch('openlp.core.ui.mainwindow.start_zeroconf'), \ patch('openlp.core.ui.mainwindow.PluginForm'): return MainWindow()