diff src/browser/sat_browser/jid.py @ 519:138336986bd0

browser_side: refactorize class JID to allow modifying its attributes
author souliane <souliane@mailoo.org>
date Tue, 02 Sep 2014 21:18:10 +0200
parents da690ef8019e
children b38629924602
line wrap: on
line diff
--- a/src/browser/sat_browser/jid.py	Tue Sep 02 21:13:59 2014 +0200
+++ b/src/browser/sat_browser/jid.py	Tue Sep 02 21:18:10 2014 +0200
@@ -25,7 +25,12 @@
     """This class help manage JID (Node@Domaine/Resource)"""
 
     def __init__(self, jid):
-        self.__raw = str(self.__normalize(jid))
+        try:
+            assert(isinstance(jid, str))
+        except AssertionError:
+            raise AssertionError('Expected a string but got a %(class)s: %(inst)s' %
+                                 {'class': jid.__class__, 'inst': jid})
+        self.__raw = str(JID.__normalize(jid))
         self.__parse()
 
     @classmethod
@@ -37,32 +42,67 @@
         tokens[0] = tokens[0].lower()  # force node and domain to lower-case
         return '/'.join(tokens)
 
+    # XXX: I defined node, domain and resource as properties here, and renamed
+    # the class attributes with the '__' prefix, but it appeared that the setter
+    # methods were not called! Maybe pyjamas doesn't handle them well.
+    def setNode(self, node):
+        self.node = node
+        self.__build()
+
+    def setDomain(self, domain):
+        self.domain = domain
+        self.__build()
+
+    def setResource(self, resource):
+        self.resource = resource
+        self.__build()
+
+    @property
+    def bare(self):
+        return self.domain if not self.node else (self.node + "@" + self.domain)
+
+    @bare.setter
+    def bare(self, bare):
+        self.__parseBare(bare)
+        self.build()
+
+    def __build(self):
+        """Build the JID string from the node, domain and resource"""
+        self.__raw = self.bare if not self.resource else (self.bare + '/' + self.resource)
+
     def __parse(self):
-        """Find node domain and resource"""
-        node_end = self.__raw.find('@')
-        if node_end < 0:
-            node_end = 0
-        domain_end = self.__raw.find('/')
-        if domain_end < 1:
-            domain_end = len(self.__raw)
-        self.node = self.__raw[:node_end]
-        self.domain = self.__raw[(node_end + 1) if node_end else 0:domain_end]
-        self.resource = self.__raw[domain_end + 1:]
-        if not node_end:
-            self.bare = self.__raw
-        else:
-            self.bare = self.node + '@' + self.domain
+        """Parse the JID string to extract the node, domain and resource"""
+        tokens = self.__raw.split('/')
+        bare, self.resource = (tokens[0], tokens[1]) if len(tokens) > 1 else (self.__raw, '')
+        self.__parseBare(bare)
+
+    def __parseBare(self, bare):
+        """Parse the given JID bare to extract the node and domain
+
+        @param bare (str): JID bare to parse
+        """
+        tokens = bare.split('@')
+        self.node, self.domain = (tokens[0], tokens[1]) if len(tokens) > 1 else ('', bare)
 
     def __str__(self):
-        return self.__raw.__str__()
+        try:
+            return self.__raw
+        except AttributeError:
+            raise AttributeError("Trying to output a JID which has not been parsed yet")
 
     def is_valid(self):
         """
         @return: True if the JID is XMPP compliant
         """
-        #FIXME: always return True for the moment
         return self.domain != ''
 
     def __eq__(self, other):
-        """Redefine equality operator to implement the naturally expected test"""
-        return self.node == other.node and self.domain == other.domain and self.resource == other.resource
+        """Redefine equality operator to implement the naturally expected behavior"""
+        return self.__raw == other.__raw
+
+    def __hash__(self):
+        """Redefine hash to implement the naturally expected behavior"""
+        return hash(self.__raw)
+
+    def full(self):
+        return str(self)