From 421e7c82fae639e848104650fd4a44b99ef48ae0 Mon Sep 17 00:00:00 2001 From: Charles Haley <> Date: Fri, 8 Feb 2013 10:36:57 +0100 Subject: [PATCH] Put get_all_ips onto a thread. Cache the result when we get it. --- .../devices/smart_device_app/driver.py | 10 +++- src/calibre/gui2/actions/device.py | 1 + src/calibre/utils/mdns.py | 49 +++++++++++++------ 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/calibre/devices/smart_device_app/driver.py b/src/calibre/devices/smart_device_app/driver.py index b925909c50..285cd14680 100644 --- a/src/calibre/devices/smart_device_app/driver.py +++ b/src/calibre/devices/smart_device_app/driver.py @@ -54,6 +54,8 @@ def synchronous(tlockname): class ConnectionListener (Thread): + all_ip_addresses = dict() + NOT_SERVICED_COUNT = 6 def __init__(self, driver): @@ -61,6 +63,7 @@ class ConnectionListener (Thread): self.daemon = True self.driver = driver self.keep_running = True + all_ip_addresses = dict() def stop(self): self.keep_running = False @@ -78,6 +81,11 @@ class ConnectionListener (Thread): if not self.keep_running: break + if not self.all_ip_addresses: + self.all_ip_addresses = get_all_ips() + if self.all_ip_addresses: + self.driver._debug("All IP addresses", self.all_ip_addresses) + if not self.driver.connection_queue.empty(): queue_not_serviced_count += 1 if queue_not_serviced_count >= self.NOT_SERVICED_COUNT: @@ -1287,8 +1295,6 @@ class SMART_DEVICE_APP(DeviceConfig, DevicePlugin): self.client_can_stream_metadata = False self.client_wants_uuid_file_names = False - self._debug("All IP addresses", get_all_ips()) - message = None try: self.listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/src/calibre/gui2/actions/device.py b/src/calibre/gui2/actions/device.py index 9be0aaaf0c..d95da00369 100644 --- a/src/calibre/gui2/actions/device.py +++ b/src/calibre/gui2/actions/device.py @@ -182,6 +182,7 @@ class ConnectShareAction(InterfaceAction): def genesis(self): self.share_conn_menu = ShareConnMenu(self.gui) + self.share_conn_menu.aboutToShow.connect(self.set_smartdevice_action_state) self.share_conn_menu.toggle_server.connect(self.toggle_content_server) self.share_conn_menu.control_smartdevice.connect(self.control_smartdevice) self.share_conn_menu.config_email.connect(partial( diff --git a/src/calibre/utils/mdns.py b/src/calibre/utils/mdns.py index 63112036fd..225cc90748 100644 --- a/src/calibre/utils/mdns.py +++ b/src/calibre/utils/mdns.py @@ -5,29 +5,46 @@ __docformat__ = 'restructuredtext en' import socket, time, atexit from collections import defaultdict +from threading import Thread from calibre.utils.filenames import ascii_text from calibre import force_unicode _server = None +_all_ip_addresses = dict() + +class AllIpAddressesGetter (Thread): + + def get_all_ips(self): + ''' Return a mapping of interface names to the configuration of the + interface, which includes the ip address, netmask and broadcast addresses + ''' + import netifaces + all_ips = defaultdict(list) + if hasattr(netifaces, 'AF_INET'): + for x in netifaces.interfaces(): + try: + for c in netifaces.ifaddresses(x).get(netifaces.AF_INET, []): + all_ips[x].append(c) + except ValueError: + from calibre import prints + prints('Failed to get IP addresses for interface', x) + import traceback + traceback.print_exc() + return dict(all_ips) + + def run(self): + global _all_ip_addresses +# print 'sleeping' +# time.sleep(10) +# print 'slept' + _all_ip_addresses = self.get_all_ips() + +AllIpAddressesGetter().start() + def get_all_ips(): - ''' Return a mapping of interface names to the configuration of the - interface, which includes the ip address, netmask and broadcast addresses - ''' - import netifaces - all_ips = defaultdict(list) - if hasattr(netifaces, 'AF_INET'): - for x in netifaces.interfaces(): - try: - for c in netifaces.ifaddresses(x).get(netifaces.AF_INET, []): - all_ips[x].append(c) - except ValueError: - from calibre import prints - prints('Failed to get IP addresses for interface', x) - import traceback - traceback.print_exc() - return dict(all_ips) + return _all_ip_addresses def _get_external_ip(): 'Get IP address of interface used to connect to the outside world'