From 8dd3e12ec52cf993856bc0ea3601cc1c07acce1b Mon Sep 17 00:00:00 2001
From: Marek Siarkowicz <mareksiarkowicz@gmail.com>
Date: Mon, 15 Jun 2015 01:52:50 +0200
Subject: Handle connection errors through Exceptions.

---
 ParrotZikTray               | 38 +++++++++++++++++++----------------
 bluetooth_paired_devices.py | 48 ++++++++++++++++++++++++++++++---------------
 2 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/ParrotZikTray b/ParrotZikTray
index e43ac90..55713b3 100755
--- a/ParrotZikTray
+++ b/ParrotZikTray
@@ -67,22 +67,27 @@ class ParrotZikIndicator(SysIndicator):
             else:
                 self.reconnect.stop()
         else:
-            mac = bluetooth_paired_devices.get_parrot_zik_mac()
-            if mac:
-                self.info_item.set_label("Connecting")
-                resource_manager = connect(mac)
-                if resource_manager.sock:
-                    if resource_manager.api_version.startswith('1'):
-                        self.version_1_interface.activate(resource_manager)
-                    else:
-                        self.version_2_interface.activate(resource_manager)
-                    self.autorefresh(self)
-                    self.autorefresh.start(self, REFRESH_FREQUENCY)
-                    self.reconnect.stop()
-                else:
-                    self.info_item.set_label("Failed to connect")
+            self.info("Trying to connect")
+            try:
+                resource_manager = connect()
+            except bluetooth_paired_devices.BluetoothIsNotOn:
+                self.info("Bluetooth is turned off")
+            except bluetooth_paired_devices.DeviceNotConnected:
+                self.info("Parrot Zik Not connected")
+            except bluetooth_paired_devices.ConnectionFailure:
+                self.info("Failed to connect")
             else:
-                self.info_item.set_label("Parrot Zik Not connected")
+                if resource_manager.api_version.startswith('1'):
+                    self.version_1_interface.activate(resource_manager)
+                else:
+                    self.version_2_interface.activate(resource_manager)
+                self.autorefresh(self)
+                self.autorefresh.start(self, REFRESH_FREQUENCY)
+                self.reconnect.stop()
+
+    def info(self, message):
+        self.info_item.set_label(message)
+        print(message)
 
     @repeat
     def autorefresh(self):
@@ -123,8 +128,7 @@ class ParrotZikBaseInterface(object):
     def activate(self, resource_manager):
         self.parrot = self.parrot_class(resource_manager)
         self.read_battery()
-        self.indicator.info_item.set_label("Connected to: "
-                                           + self.parrot.friendly_name)
+        self.indicator.info("Connected to: " + self.parrot.friendly_name)
         self.firmware_version.set_label(
             "Firmware version: " + self.parrot.version)
         self.auto_connection.set_active(self.parrot.auto_connect)
diff --git a/bluetooth_paired_devices.py b/bluetooth_paired_devices.py
index 139ca3d..5ab060f 100644
--- a/bluetooth_paired_devices.py
+++ b/bluetooth_paired_devices.py
@@ -17,11 +17,16 @@ def get_parrot_zik_mac():
         p = re.compile('90:03:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}|'
                        'A0:14:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}')
         if sys.platform == "linux2":
-            out = os.popen("bluez-test-device list").read()
-            res = p.findall(out)
-            if len(res) > 0:
-                return res[0]
-
+            bluetooth_on = int(os.popen('bluez-test-adapter powered').read())
+            if bluetooth_on == 1:
+                out = os.popen("bluez-test-device list").read()
+                res = p.findall(out)
+                if len(res) > 0:
+                    return res[0]
+                else:
+                    raise DeviceNotConnected
+            else:
+                raise BluetoothIsNotOn
         elif sys.platform == "darwin":
             fd = open("/Library/Preferences/com.apple.Bluetooth.plist", "rb")
             plist = binplist.BinaryPlist(file_obj=fd)
@@ -30,6 +35,8 @@ def get_parrot_zik_mac():
                 for mac in parsed_plist['PairedDevices']:
                     if p.match(mac.replace("-", ":")):
                         return mac.replace("-", ":")
+                else:
+                    raise DeviceNotConnected
             except Exception:
                 pass
 
@@ -45,41 +52,38 @@ def get_parrot_zik_mac():
                     res = p.findall(mac)
                     if len(res) > 0:
                         return res[0]
-
+                    else:
+                        raise DeviceNotConnected
                 except EnvironmentError:
                     pass
 
 
-def connect(addr=None):
+def connect():
+    mac = get_parrot_zik_mac()
     if sys.platform == "darwin":
         service_matches = lightblue.findservices(
-            name="Parrot RFcomm service", addr=addr)
+            name="Parrot RFcomm service", addr=mac)
     else:
         uuids = ["0ef0f502-f0ee-46c9-986c-54ed027807fb",
                  "8B6814D3-6CE7-4498-9700-9312C1711F63"]
         service_matches = []
         for uuid in uuids:
-            service_matches = bluetooth.find_service(uuid=uuid, address=addr)
+            service_matches = bluetooth.find_service(uuid=uuid, address=mac)
             if service_matches:
                 break
 
     if len(service_matches) == 0:
-        print "Failed to find Parrot Zik RFCOMM service"
-        return GenericResourceManager(None)
+        raise ConnectionFailure
 
     if sys.platform == "darwin":
         first_match = service_matches[0]
-        port = first_match[1]
-        name = first_match[2]
         host = first_match[0]
+        port = first_match[1]
     else:
         first_match = service_matches[0]
         port = first_match["port"]
-        name = first_match["name"]
         host = first_match["host"]
 
-    print "Connecting to \"%s\" on %s" % (name, host)
-
     if sys.platform == "darwin":
         sock = lightblue.socket()
     else:
@@ -90,3 +94,15 @@ def connect(addr=None):
     sock.send('\x00\x03\x00')
     sock.recv(1024)
     return GenericResourceManager(sock)
+
+
+class DeviceNotConnected(Exception):
+    pass
+
+
+class ConnectionFailure(Exception):
+    pass
+
+
+class BluetoothIsNotOn(Exception):
+    pass
-- 
cgit v1.2.1