Re: [Openlp-core] [Merge] lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp

2019-07-02 Thread Tomas Groth
Review: Approve


-- 
https://code.launchpad.net/~raoul-snyman/openlp/fix-presentations-cleanup-bug/+merge/369624
Your team OpenLP Core is subscribed to branch lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] macOS Test Results: Passed

2019-07-02 Thread Raoul Snyman
macOS tests passed!
-- 
https://code.launchpad.net/~raoul-snyman/openlp/fix-presentations-cleanup-bug/+merge/369624
Your team OpenLP Core is requested to review the proposed merge of 
lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] Linting: Passed

2019-07-02 Thread Raoul Snyman
Linting passed!
-- 
https://code.launchpad.net/~raoul-snyman/openlp/fix-presentations-cleanup-bug/+merge/369624
Your team OpenLP Core is requested to review the proposed merge of 
lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] Linux Test Results: Passed

2019-07-02 Thread Raoul Snyman
Linux tests passed!
-- 
https://code.launchpad.net/~raoul-snyman/openlp/fix-presentations-cleanup-bug/+merge/369624
Your team OpenLP Core is requested to review the proposed merge of 
lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] [Merge] lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp

2019-07-02 Thread Raoul Snyman
Raoul Snyman has proposed merging 
lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp.

Commit message:
Fix a bug when cleaning up thumbnails where all presentation controllers, 
whether enabled or not, would be cycled through.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/fix-presentations-cleanup-bug/+merge/369624

Fix a bug when cleaning up thumbnails where all presentation controllers, 
whether enabled or not, would be cycled through.
-- 
Your team OpenLP Core is requested to review the proposed merge of 
lp:~raoul-snyman/openlp/fix-presentations-cleanup-bug into lp:openlp.
=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py	2019-05-22 06:47:00 +
+++ openlp/plugins/presentations/lib/mediaitem.py	2019-07-03 04:00:28 +
@@ -246,6 +246,9 @@
 :rtype: None
 """
 for cidx in self.controllers:
+if not self.controllers[cidx].enabled():
+# skip presentation controllers that are not enabled
+continue
 file_ext = file_path.suffix[1:]
 if file_ext in self.controllers[cidx].supports or file_ext in self.controllers[cidx].also_supports:
 doc = self.controllers[cidx].add_document(file_path)

=== modified file 'tests/functional/openlp_plugins/presentations/test_mediaitem.py'
--- tests/functional/openlp_plugins/presentations/test_mediaitem.py	2019-05-22 06:47:00 +
+++ tests/functional/openlp_plugins/presentations/test_mediaitem.py	2019-07-03 04:00:28 +
@@ -24,7 +24,7 @@
 """
 from pathlib import Path
 from unittest import TestCase
-from unittest.mock import MagicMock, call, patch
+from unittest.mock import MagicMock, PropertyMock, call, patch
 
 from openlp.core.common.registry import Registry
 from openlp.plugins.presentations.lib.mediaitem import PresentationMediaItem
@@ -94,17 +94,23 @@
 Test that the clean_up_thumbnails method works as expected when files exists.
 """
 # GIVEN: A mocked controller, and mocked os.path.getmtime
-mocked_controller = MagicMock()
+mocked_disabled_controller = MagicMock()
+mocked_disabled_controller.enabled.return_value = False
+mocked_disabled_supports = PropertyMock()
+type(mocked_disabled_controller).supports = mocked_disabled_supports
+mocked_enabled_controller = MagicMock()
+mocked_enabled_controller.enabled.return_value = True
 mocked_doc = MagicMock(**{'get_thumbnail_path.return_value': Path()})
-mocked_controller.add_document.return_value = mocked_doc
-mocked_controller.supports = ['tmp']
+mocked_enabled_controller.add_document.return_value = mocked_doc
+mocked_enabled_controller.supports = ['tmp']
 self.media_item.controllers = {
-'Mocked': mocked_controller
+'Enabled': mocked_enabled_controller,
+'Disabled': mocked_disabled_controller
 }
 
-thmub_path = MagicMock(st_mtime=100)
+thumb_path = MagicMock(st_mtime=100)
 file_path = MagicMock(st_mtime=400)
-with patch.object(Path, 'stat', side_effect=[thmub_path, file_path]), \
+with patch.object(Path, 'stat', side_effect=[thumb_path, file_path]), \
 patch.object(Path, 'exists', return_value=True):
 presentation_file = Path('file.tmp')
 
@@ -114,6 +120,7 @@
 # THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than
 #   the presentation_file's mtime.
 mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
+assert mocked_disabled_supports.call_count == 0
 
 def test_clean_up_thumbnails_missing_file(self):
 """

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] Linux Test Results: Failed

2019-07-02 Thread Raoul Snyman
Linux tests failed, please see https://ci.openlp.io/job/MP-02-Linux_Tests/203/ 
for more details
-- 
https://code.launchpad.net/~raoul-snyman/openlp/zeroconf/+merge/369623
Your team OpenLP Core is subscribed to branch lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] [Merge] lp:~raoul-snyman/openlp/zeroconf into lp:openlp

2019-07-02 Thread Raoul Snyman
The proposal to merge lp:~raoul-snyman/openlp/zeroconf into lp:openlp has been 
updated.

Status: Needs review => Superseded

For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/zeroconf/+merge/369554
-- 
Your team OpenLP Core is subscribed to branch lp:openlp.

___
Mailing list: https://launchpad.net/~openlp-core
Post to : openlp-core@lists.launchpad.net
Unsubscribe : https://launchpad.net/~openlp-core
More help   : https://help.launchpad.net/ListHelp


[Openlp-core] [Merge] lp:~raoul-snyman/openlp/zeroconf into lp:openlp

2019-07-02 Thread Raoul Snyman
Raoul Snyman has proposed merging lp:~raoul-snyman/openlp/zeroconf into 
lp:openlp.

Commit message:
Add Zeroconf services to OpenLP so that external devices can find OpenLP on the 
network.

Requested reviews:
  Tomas Groth (tomasgroth)

For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/zeroconf/+merge/369623

Add Zeroconf services to OpenLP so that external devices can find OpenLP on the 
network.
-- 
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/api/tab.py'
--- openlp/core/api/tab.py	2019-04-13 13:00:22 +
+++ openlp/core/api/tab.py	2019-07-03 03:07:13 +
@@ -24,7 +24,7 @@
 """
 from PyQt5 import QtCore, QtGui, QtWidgets
 
-from openlp.core.common import get_local_ip4
+from openlp.core.common import get_network_interfaces
 from openlp.core.common.i18n import UiStrings, translate
 from openlp.core.common.registry import Registry
 from openlp.core.common.settings import Settings
@@ -194,8 +194,7 @@
 http_url_temp = http_url + 'main'
 self.live_url.setText('{url}'.format(url=http_url_temp))
 
-@staticmethod
-def get_ip_address(ip_address):
+def get_ip_address(self, ip_address):
 """
 returns the IP address in dependency of the passed address
 ip_address == 0.0.0.0: return the IP address of the first valid interface
@@ -203,9 +202,8 @@
 """
 if ip_address == ZERO_URL:
 # In case we have more than one interface
-ifaces = get_local_ip4()
-for key in iter(ifaces):
-ip_address = ifaces.get(key)['ip']
+for _, interface in get_network_interfaces().items():
+ip_address = interface['ip']
 # We only want the first interface returned
 break
 return ip_address

=== added file 'openlp/core/api/zeroconf.py'
--- openlp/core/api/zeroconf.py	1970-01-01 00:00:00 +
+++ openlp/core/api/zeroconf.py	2019-07-03 03:07:13 +
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+##
+# OpenLP - Open Source Lyrics Projection #
+# -- #
+# Copyright (c) 2008-2019 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
+
+from openlp.core.common import get_network_interfaces
+from openlp.core.common.registry import Registry
+from openlp.core.common.settings import Settings
+from openlp.core.threading import ThreadWorker, run_thread
+
+
+class ZeroconfWorker(ThreadWorker):
+"""
+This thread worker runs a Zeroconf service
+"""
+address = None
+http_port = 4316
+ws_port = 4317
+_can_run = False
+
+def __init__(self, ip_address, http_port=4316, ws_port=4317):
+"""
+Create the worker for the Zeroconf service
+"""
+super().__init__()
+self.address = socket.inet_aton(ip_address)
+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
+"""
+http_info = ServiceInfo('_http._tcp.local.', 'OpenLP._http._tcp.local.',
+address=self.address, port=self.http_port, properties={})
+ws_info = ServiceInfo('_ws._tcp.local.', 'OpenLP._ws._tcp.local.',
+  

Re: [Openlp-core] [Merge] lp:~raoul-snyman/openlp/zeroconf into lp:openlp

2019-07-02 Thread Raoul Snyman
See inline

Diff comments:

> === added file 'openlp/core/api/zeroconf.py'
> --- openlp/core/api/zeroconf.py   1970-01-01 00:00:00 +
> +++ openlp/core/api/zeroconf.py   2019-07-01 22:53:54 +
> @@ -0,0 +1,101 @@
> +# -*- coding: utf-8 -*-
> +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 
> softtabstop=4
> +
> +##
> +# OpenLP - Open Source Lyrics Projection #
> +# -- #
> +# Copyright (c) 2008-2019 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
> +
> +from openlp.core.common import get_local_ip4
> +from openlp.core.common.registry import Registry
> +from openlp.core.common.settings import Settings
> +from openlp.core.threading import ThreadWorker, run_thread
> +
> +
> +class ZeroconfWorker(ThreadWorker):
> +"""
> +This thread worker runs a Zeroconf service
> +"""
> +address = None
> +http_port = 4316
> +ws_port = 4317
> +_can_run = False
> +
> +def __init__(self, ip_address, http_port=4316, ws_port=4317):
> +"""
> +Create the worker for the Zeroconf service
> +"""
> +super().__init__()
> +self.address = socket.inet_aton(ip_address)
> +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
> +"""
> +http_info = ServiceInfo('_http._tcp.local.', 
> 'OpenLP._http._tcp.local.',
> +address=self.address, port=self.http_port, 
> properties={})
> +ws_info = ServiceInfo('_ws._tcp.local.', 'OpenLP._ws._tcp.local.',
> +  address=self.address, port=self.ws_port, 
> properties={})
> +zc = Zeroconf()
> +zc.register_service(http_info)
> +zc.register_service(ws_info)
> +self._can_run = True
> +while self.can_run():
> +sleep(0.1)
> +zc.unregister_service(http_info)
> +zc.unregister_service(ws_info)
> +zc.close()
> +
> +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
> +ifaces = get_local_ip4()
> +for key in iter(ifaces):
> +address = ifaces.get(key)['ip']
> +break

My computer:
{
  'wlp3s0': {'ip': '192.168.1.179', 'broadcast': '192.168.1.255', 'netmask': 
'255.255.255.0', 'prefix': 24, 'localnet': '192.168.1.0'},
  'docker0': {'ip': '172.17.0.1', 'broadcast': '172.17.255.255', 'netmask': 
'255.255.0.0', 'prefix': 16, 'localnet': '172.17.0.0'},
  'tun0': {'ip': '10.3.117.251', 'broadcast': '10.3.119.255', 'netmask': 
'255.255.252.0', 'prefix': 22, 'localnet': '10.3.116.0'}
}
The first one is definitely the only valid one.

> +http_port = Settings().value('api/port')
> +ws_port = Settings().value('api/websocket port')
> +worker = ZeroconfWorker(address, http_port, ws_port)
> +run_thread(worker, 'api_zeroconf')


-- 
https://code.launchpad.net/~raoul-snyman/openlp/zeroconf/+merge/369554
Your team OpenLP Core is subscribed to 

Re: [Openlp-core] [Merge] lp:~raoul-snyman/openlp/zeroconf into lp:openlp

2019-07-02 Thread Raoul Snyman



Diff comments:

> === added file 'openlp/core/api/zeroconf.py'
> --- openlp/core/api/zeroconf.py   1970-01-01 00:00:00 +
> +++ openlp/core/api/zeroconf.py   2019-07-01 22:53:54 +
> @@ -0,0 +1,101 @@
> +# -*- coding: utf-8 -*-
> +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 
> softtabstop=4
> +
> +##
> +# OpenLP - Open Source Lyrics Projection #
> +# -- #
> +# Copyright (c) 2008-2019 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
> +
> +from openlp.core.common import get_local_ip4
> +from openlp.core.common.registry import Registry
> +from openlp.core.common.settings import Settings
> +from openlp.core.threading import ThreadWorker, run_thread
> +
> +
> +class ZeroconfWorker(ThreadWorker):
> +"""
> +This thread worker runs a Zeroconf service
> +"""
> +address = None
> +http_port = 4316
> +ws_port = 4317
> +_can_run = False
> +
> +def __init__(self, ip_address, http_port=4316, ws_port=4317):
> +"""
> +Create the worker for the Zeroconf service
> +"""
> +super().__init__()
> +self.address = socket.inet_aton(ip_address)
> +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
> +"""
> +http_info = ServiceInfo('_http._tcp.local.', 
> 'OpenLP._http._tcp.local.',
> +address=self.address, port=self.http_port, 
> properties={})
> +ws_info = ServiceInfo('_ws._tcp.local.', 'OpenLP._ws._tcp.local.',
> +  address=self.address, port=self.ws_port, 
> properties={})
> +zc = Zeroconf()
> +zc.register_service(http_info)
> +zc.register_service(ws_info)
> +self._can_run = True
> +while self.can_run():
> +sleep(0.1)
> +zc.unregister_service(http_info)
> +zc.unregister_service(ws_info)
> +zc.close()
> +
> +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
> +ifaces = get_local_ip4()
> +for key in iter(ifaces):
> +address = ifaces.get(key)['ip']
> +break

I could do that. I think I first want to see what actually comes out of that 
function, I kinda just copied and pasted it from the API tab.

> +http_port = Settings().value('api/port')
> +ws_port = Settings().value('api/websocket port')
> +worker = ZeroconfWorker(address, http_port, ws_port)
> +run_thread(worker, 'api_zeroconf')
> 
> === modified file 'scripts/check_dependencies.py'
> --- scripts/check_dependencies.py 2019-06-11 05:01:02 +
> +++ scripts/check_dependencies.py 2019-07-01 22:53:54 +
> @@ -90,7 +90,8 @@
>  'requests',
>  'qtawesome',
>  'pymediainfo',
> -'vlc'
> +'vlc',
> +'zeroconf'
>  ]

Oh yes, and setup.py.

>  
>  


-- 
https://code.launchpad.net/~raoul-snyman/openlp/zeroconf/+merge/369554
Your team OpenLP Core is 

Re: [Openlp-core] [Merge] lp:~raoul-snyman/openlp/zeroconf into lp:openlp

2019-07-02 Thread Tomas Groth
Review: Needs Fixing

Please see inline comments.

Diff comments:

> === added file 'openlp/core/api/zeroconf.py'
> --- openlp/core/api/zeroconf.py   1970-01-01 00:00:00 +
> +++ openlp/core/api/zeroconf.py   2019-07-01 22:53:54 +
> @@ -0,0 +1,101 @@
> +# -*- coding: utf-8 -*-
> +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 
> softtabstop=4
> +
> +##
> +# OpenLP - Open Source Lyrics Projection #
> +# -- #
> +# Copyright (c) 2008-2019 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
> +
> +from openlp.core.common import get_local_ip4
> +from openlp.core.common.registry import Registry
> +from openlp.core.common.settings import Settings
> +from openlp.core.threading import ThreadWorker, run_thread
> +
> +
> +class ZeroconfWorker(ThreadWorker):
> +"""
> +This thread worker runs a Zeroconf service
> +"""
> +address = None
> +http_port = 4316
> +ws_port = 4317
> +_can_run = False
> +
> +def __init__(self, ip_address, http_port=4316, ws_port=4317):
> +"""
> +Create the worker for the Zeroconf service
> +"""
> +super().__init__()
> +self.address = socket.inet_aton(ip_address)
> +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
> +"""
> +http_info = ServiceInfo('_http._tcp.local.', 
> 'OpenLP._http._tcp.local.',
> +address=self.address, port=self.http_port, 
> properties={})
> +ws_info = ServiceInfo('_ws._tcp.local.', 'OpenLP._ws._tcp.local.',
> +  address=self.address, port=self.ws_port, 
> properties={})
> +zc = Zeroconf()
> +zc.register_service(http_info)
> +zc.register_service(ws_info)
> +self._can_run = True
> +while self.can_run():
> +sleep(0.1)
> +zc.unregister_service(http_info)
> +zc.unregister_service(ws_info)
> +zc.close()
> +
> +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
> +ifaces = get_local_ip4()
> +for key in iter(ifaces):
> +address = ifaces.get(key)['ip']
> +break

So if you have active connections on both LAN and WLAN (or other multiple 
connections scenarios), only the first is used? Why not start a worker per 
active connection?

> +http_port = Settings().value('api/port')
> +ws_port = Settings().value('api/websocket port')
> +worker = ZeroconfWorker(address, http_port, ws_port)
> +run_thread(worker, 'api_zeroconf')
> 
> === modified file 'scripts/check_dependencies.py'
> --- scripts/check_dependencies.py 2019-06-11 05:01:02 +
> +++ scripts/check_dependencies.py 2019-07-01 22:53:54 +
> @@ -90,7 +90,8 @@
>  'requests',
>  'qtawesome',
>  'pymediainfo',
> -'vlc'
> +'vlc',
> +'zeroconf'
>  ]

Please also add install of zeroconf to appveyor.yml

>