kuuko pushed a commit to branch master.

http://git.enlightenment.org/apps/econnman.git/commit/?id=18e7be6bf80df6b86965ba93391b205339fc7267

commit 18e7be6bf80df6b86965ba93391b205339fc7267
Author: Kai Huuhko <kai.huu...@gmail.com>
Date:   Sat Mar 5 08:20:56 2016 +0200

    Add support for IPv6
---
 econnman-bin.in | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 197 insertions(+), 15 deletions(-)

diff --git a/econnman-bin.in b/econnman-bin.in
index 2715f1d..4f23acb 100755
--- a/econnman-bin.in
+++ b/econnman-bin.in
@@ -56,10 +56,10 @@ except:
 
 dbus_ml = DBusEcoreMainLoop()
 bus = dbus.SystemBus(mainloop=dbus_ml)
-log = logging.getLogger("econnman")
+log = logging.getLogger("econnman-bin")
 log_handler = logging.StreamHandler()
 log_formatter = logging.Formatter(
-    "%(relativeCreated)d %(levelname)s %(name)s: %(message)s"
+    "%(created)d %(name)s [%(levelname)s]:: %(message)s (@lineno %(lineno)d)"
     )
 log_handler.setFormatter(log_formatter)
 log.addHandler(log_handler)
@@ -347,6 +347,20 @@ class ObjectView(object):
         sc.callback_changed_add(callback)
         return sc, items
 
+    def add_label_and_segment_control(self, box, options, callback, label):
+        lb = self.add_label(box, label)
+
+        sc = SegmentControl(box)
+        sc.size_hint_weight = EXPAND_HORIZ
+        sc.size_hint_align = FILL_BOTH
+        items = {}
+        for o in options:
+            items[o] = sc.item_add(None, o)
+        sc.show()
+        box.pack_end(sc)
+        sc.callback_changed_add(callback)
+        return lb, sc, items
+
     def add_frame_and_box(self, box, label):
         fr = Frame(box)
         fr.size_hint_weight = EXPAND_HORIZ
@@ -925,6 +939,28 @@ class ServiceView(ObjectView):
     """
     bus_interface = "net.connman.Service"
 
+    ipv4_fields = (#("Method", "ipv4_method"),
+                   ("Address", "ipv4_address"),
+                   ("Netmask", "ipv4_netmask"),
+                   ("Gateway", "ipv4_gateway"),
+                   )
+    ipv6_fields = (#("Method", "ipv6_method"),
+                   ("Address", "ipv6_address"),
+                   ("Prefix Length", "ipv6_prefix_length"),
+                   ("Gateway", "ipv6_gateway"),
+                   #("Privacy", "ipv6_privacy"),
+                   )
+    proxy_fields = (("Method", "proxy_method"),
+                    ("URL", "proxy_url"),
+                    ("Servers", "proxy_servers"),
+                    ("Excludes", "proxy_excludes"),
+                    )
+    vpn_fields = (  # named Provider in spec
+                  ("Host", "vpn_host"),
+                  ("Domain", "vpn_domain"),
+                  ("Name", "vpn_name"),
+                  ("Type", "vpn_type"),
+                  )
     eth_fields = (("Method", "eth_method"),
                   ("Interface", "eth_iface"),
                   ("Address", "eth_addr"),
@@ -932,15 +968,6 @@ class ServiceView(ObjectView):
                   ("Speed", "eth_speed"),
                   ("Duplex", "eth_duplex"),
                   )
-    vpn_fields = (("Host", "vpn_host"),
-                  ("Domain", "vpn_domain"),
-                  ("Name", "vpn_name"),
-                  ("Type", "vpn_type"),
-                  )
-    ipv4_fields = (("Address", "ipv4_address"),
-                   ("Netmask", "ipv4_netmask"),
-                   ("Gateway", "ipv4_gateway"),
-                   )
 
     top_widgets = (
         "connect",
@@ -959,6 +986,7 @@ class ServiceView(ObjectView):
         "domains_label",
         "domains_entry",
         "ipv4_frame",
+        "ipv6_frame",
         "proxy_frame",
         "ethernet_frame",
         "vpn_frame",
@@ -1033,10 +1061,22 @@ class ServiceView(ObjectView):
             en.callback_unfocused_add(self._on_ipv4_property_unfocused)
             setattr(self, attr, en)
 
-        # section: IPv6: similar to ipv4? refactor ipv4?
-        if properties.get("IPv6"):
-            fr, bx = self.add_frame_and_box(self.box, "IPv6")
-            lb = self.add_label(bx, "TODO")
+        # section: IPv6
+        self.ipv6_properties = {"IPv6": {}, "IPv6.Configuration": {}}
+        fr, bx = self.add_frame_and_box(self.box, "IPv6")
+        self.ipv6_frame = fr
+        self.ipv6_box = bx
+        options = ("Automatic", "Manual", "Off")
+        self.ipv6_method, self.ipv6_method_items = self.add_segment_control(
+            bx, options, self._on_ipv6_method)
+        for name, attr in self.ipv6_fields:
+            lb, en = self.add_label_and_entry(bx, name)
+            en.callback_activated_add(self._on_ipv6_property_changed)
+            en.callback_unfocused_add(self._on_ipv6_property_unfocused)
+            setattr(self, attr, en)
+        options = ("Disabled", "Enabled", "Prefered")
+        self.ipv6_privacy_lb, self.ipv6_privacy, self.ipv6_privacy_items = 
self.add_label_and_segment_control(
+            bx, options, self._on_ipv6_privacy, "Privacy")
 
         # section: Proxy: custom contents for direct, auto and manual
         #  - direct: nothing
@@ -1186,6 +1226,11 @@ class ServiceView(ObjectView):
             self.ipv4_address.disabled = value
             self.ipv4_netmask.disabled = value
             self.ipv4_gateway.disabled = value
+            self.ipv6_method.disabled = value
+            self.ipv6_address.disabled = value
+            self.ipv6_prefix_length.disabled = value
+            self.ipv6_gateway.disabled = value
+            self.ipv6_privacy.disabled = value
             self.proxy_method.disabled = value
         elif name == "Favorite":
             value = bool(value)
@@ -1250,6 +1295,47 @@ class ServiceView(ObjectView):
                 self.ipv4_method_items["Off"].selected = True
             elif method:
                 log.error("Unknown method: %s", method)
+        elif name in ("IPv6", "IPv6.Configuration"):
+            self.ipv6_properties[name] = value
+            used = self.ipv6_properties["IPv6"]
+            conf = self.ipv6_properties["IPv6.Configuration"]
+
+            def get_val(name):
+                v = used.get(name) or conf.get(name)
+                if not v:
+                    return ""
+                return str(v)
+            self.ipv6_address.text = get_val("Address")
+            self.ipv6_prefix_length.text = get_val("PrefixLength")
+            self.ipv6_gateway.text = get_val("Gateway")
+
+            method = str(conf.get("Method", ""))
+            editable = (method == "manual") and (not self.immutable)
+            self.ipv6_address.editable = editable
+            self.ipv6_prefix_length.editable = editable
+            self.ipv6_gateway.editable = editable
+            # privacy has only meaning if Method is set to "auto"
+            editable = (method == "auto") and (not self.immutable)
+            self.ipv6_privacy.disabled = not editable
+
+            if method in ("auto", "fixed", "6to4"):
+                self.ipv6_method_items["Automatic"].selected = True
+            elif method == "manual":
+                self.ipv6_method_items["Manual"].selected = True
+            elif method == "off":
+                self.ipv6_method_items["Off"].selected = True
+            elif method:
+                log.error("Unknown method: %s", method)
+
+            privacy = str(conf.get("Privacy", ""))
+            if privacy == "disabled":
+                self.ipv6_privacy_items["Disabled"].selected = True
+            elif privacy == "enabled":
+                self.ipv6_privacy_items["Enabled"].selected = True
+            elif privacy == "prefered":
+                self.ipv6_privacy_items["Prefered"].selected = True
+            elif privacy:
+                log.error("Unknown privacy: %s", privacy)
 
         elif name in ("Proxy", "Proxy.Configuration"):
             self.proxy_properties[name] = value
@@ -1437,6 +1523,102 @@ class ServiceView(ObjectView):
         self.ipv4_netmask.text = get_val("Netmask")
         self.ipv4_gateway.text = get_val("Gateway")
 
+    def _ipv6_apply(self):
+        value = self.ipv6_method.item_selected.text
+        if value == "Automatic":
+            method = "auto"
+        elif value == "Manual":
+            method = "manual"
+        elif value == "Off":
+            method = "off"
+
+        def make_variant(s):
+            return dbus.String(s, variant_level=1)
+        new = {"Method": make_variant(method)}
+        if method == "manual":
+            if self.ipv6_address.text:
+                new["Address"] = make_variant(self.ipv6_address.text)
+            if self.ipv6_prefix_length.text:
+                new["PrefixLength"] = 
make_variant(self.ipv6_prefix_length.text)
+            if self.ipv6_gateway.text:
+                new["Gateway"] = make_variant(self.ipv6_gateway.text)
+            value = self.ipv6_privacy.item_selected.text
+            if value:
+                new["Privacy"] = make_variant(value)
+            if len(new) == 1:  # no properties yet
+                return
+
+        conf = self.ipv6_properties["IPv6.Configuration"]
+        changed = []
+        for k, v in new.items():
+            if conf.get(k) != v:
+                changed.append(k)
+        log.debug("Changed IPv6: %s", ", ".join(changed))
+        if not changed:
+            return
+
+        def on_reply():
+            log.info("Set IPv6=%s", new)
+
+        def on_error(exc):
+            log.error("Failed to set IPv6.Configuration=%s: %s", new, exc)
+            popup_error(self.obj, "Failed to Apply IPv6",
+                        exc.get_dbus_message())
+        self.bus_obj.SetProperty(
+            "IPv6.Configuration", new,
+            reply_handler=on_reply, error_handler=on_error
+            )
+
+    def _on_ipv6_method(self, obj, item):
+        if item.text == "Automatic":
+            method = "auto"
+        elif item.text == "Manual":
+            method = "manual"
+        elif item.text == "Off":
+            method = "off"
+        conf = self.ipv6_properties["IPv6.Configuration"]
+
+        editable = (method == "manual") and (not self.immutable)
+        self.ipv6_address.editable = editable
+        self.ipv6_prefix_length.editable = editable
+        self.ipv6_gateway.editable = editable
+        # privacy has only meaning if Method is set to "auto"
+        editable = (method == "auto") and (not self.immutable)
+        self.ipv6_privacy.disabled = not editable
+
+        if method == conf["Method"]:
+            return
+        self._ipv6_apply()
+
+    def _on_ipv6_privacy(self, obj, item):
+        if item.text == "Disabled":
+            privacy = "disabled"
+        elif item.text == "Enabled":
+            privacy = "enabled"
+        elif item.text == "Prefered":
+            privacy = "prefered"
+        conf = self.ipv6_properties["IPv6.Configuration"]
+        if privacy == conf["Privacy"]:
+            return
+        self._ipv6_apply()
+
+    def _on_ipv6_property_changed(self, obj):
+        self._ipv6_apply()
+
+    def _on_ipv6_property_unfocused(self, obj):
+        used = self.ipv6_properties["IPv6"]
+        conf = self.ipv6_properties["IPv6.Configuration"]
+
+        def get_val(name):
+            v = used.get(name) or conf.get(name)
+            if not v:
+                return ""
+            return str(v)
+        self.ipv6_address.text = get_val("Address")
+        self.ipv6_prefix_length.text = get_val("PrefixLength")
+        self.ipv6_gateway.text = get_val("Gateway")
+        #self.ipv6_privacy.text = get_val("Privacy")
+
     def _on_proxy_method(self, obj, item):
         if item.text == "Direct":
             method = "direct"

-- 


Reply via email to