update test and examples for OMF6 in OMF section
[nepi.git] / src / nepi / resources / omf / omf_client.py
index f20132d..113bd1e 100644 (file)
@@ -1,38 +1,53 @@
-"""
-    NEPI, a framework to manage network experiments
-    Copyright (C) 2013 INRIA
-
-    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 <http://www.gnu.org/licenses/>.
-
-"""
+#
+#    NEPI, a framework to manage network experiments
+#    Copyright (C) 2013 INRIA
+#
+#    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 <http://www.gnu.org/licenses/>.
+#
+# Author: Alina Quereilhac <alina.quereilhac@inria.fr>
+#         Julien Tribino <julien.tribino@inria.fr>
 
 from nepi.util.logger import Logger
+from nepi.resources.omf.omf6_parser import OMF6Parser
+
+try:
+    import sleekxmpp
+    from sleekxmpp.exceptions import IqError, IqTimeout
+    class BaseOMFClient(sleekxmpp.ClientXMPP):
+        pass
+except ImportError:
+    print "SleekXMPP is not installed. Without this library, \n" + \
+          " You will be not able to use OMF Resources \n"+ \
+          " If you want to install SleekXmpp : \n"+ \
+          " git clone -b develop git://github.com/fritzy/SleekXMPP.git \n"+ \
+          " cd SleekXMPP \n"+ \
+           "sudo python setup.py install\n"
+    class BaseOMFClient(object):
+        pass
 
-import sleekxmpp
-from sleekxmpp.exceptions import IqError, IqTimeout
 import traceback
 import xml.etree.ElementTree as ET
 
-# inherit from BaseXmpp and XMLStream classes
+# inherit from BaseXmpp and XMLstream classes
 class OMFClient(sleekxmpp.ClientXMPP, Logger): 
     """
     .. class:: Class Args :
       
         :param jid: Jabber Id (= Xmpp Slice + Date)
-        :type jid: Str
+        :type jid: str
         :param password: Jabber Password (= Xmpp Password)
-        :type password: Str
+        :type password: str
 
     .. note::
 
@@ -44,9 +59,9 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         """
 
         :param jid: Jabber Id (= Xmpp Slice + Date)
-        :type jid: Str
+        :type jid: str
         :param password: Jabber Password (= Xmpp Password)
-        :type password: Str
+        :type password: str
 
 
         """
@@ -56,6 +71,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         self._ready = False
         self._registered = False
         self._server = None
+        self._parser = None
 
         self.register_plugin('xep_0077') # In-band registration
         self.register_plugin('xep_0030')
@@ -65,7 +81,16 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         self.add_event_handler("session_start", self.start)
         self.add_event_handler("register", self.register)
         self.add_event_handler("pubsub_publish", self.handle_omf_message)
+
+        #Init the parser
+        self._init_parser()
         
+    def _init_parser(self):
+        """ Init the parser depending on the OMF Version
+
+        """
+        self._parser = OMF6Parser()
+
     @property
     def ready(self):
         """ Check if the client is ready
@@ -102,7 +127,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
             self._registered = True
         except IqError as e:
             msg = " Could not register account: %s" % e.iq['error']['text']
-            selferror(msg)
+            self.error(msg)
         except IqTimeout:
             msg = " No response from server."
             self.error(msg)
@@ -131,7 +156,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
             result = self['xep_0060'].get_nodes(self._server)
             for item in result['disco_items']['items']:
                 msg = ' - %s' % str(item)
-                self.info(msg)
+                self.debug(msg)
             return result
         except:
             error = traceback.format_exc()
@@ -147,7 +172,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
                 #self.boundjid.full)
             for node in result['node']:
                 msg = ' - %s' % str(node)
-                self.info(msg)
+                self.debug(msg)
             return result
         except:
             error = traceback.format_exc()
@@ -161,7 +186,8 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         :type node: str
 
         """
-        self.debug(" Create Topic : " + node)
+        msg = " Create Topic : " + node
+        self.info(msg)
    
         config = self['xep_0004'].makeForm('submit')
         config.add_field(var='pubsub#node_type', value='leaf')
@@ -174,8 +200,9 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         try:
             self['xep_0060'].create_node(self._server, node, config = config)
         except:
-            error = traceback.format_exc()
-            msg = ' Could not create topic: %s\ntraceback:\n%s' % (node, error)
+            #error = traceback.format_exc()
+            #msg = ' Could not create topic: %s\ntraceback:\n%s' % (node, error)
+            msg = 'Could not create the topic : '+node+' . Maybe the topic already exists'
             self.error(msg)
 
     def delete(self, node):
@@ -193,8 +220,9 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
             msg = ' Deleted node: %s' % node
             self.info(msg)
         except:
-            error = traceback.format_exc()
-            msg = ' Could not delete topic: %s\ntraceback:\n%s' % (node, error)
+            #error = traceback.format_exc()
+            #msg = ' Could not delete topic: %s\ntraceback:\n%s' % (node, error)
+            msg = 'Could not delete the topic : '+node+' . Maybe It is not the owner of the topic'
             self.error(msg)
     
     def publish(self, data, node):
@@ -208,7 +236,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         """ 
 
         msg = " Publish to Topic : " + node
-        self.debug(msg)
+        self.info(msg)
         try:
             result = self['xep_0060'].publish(self._server,node,payload=data)
             # id = result['pubsub']['publish']['item']['id']
@@ -231,7 +259,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
                 data)
             for item in result['pubsub']['items']['substanzas']:
                 msg = 'Retrieved item %s: %s' % (item['id'], tostring(item['payload']))
-                self.info(msg)
+                self.debug(msg)
         except:
             error = traceback.format_exc()
             msg = ' Could not retrieve item %s from topic %s\ntraceback:\n%s' \
@@ -248,7 +276,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         try:
             result = self['xep_0060'].retract(self._server, self.boundjid, data)
             msg = ' Retracted item %s from topic %s' % (data, self.boundjid)
-            self.info(msg)
+            self.debug(msg)
         except:
             error = traceback.format_exc()
             msg = 'Could not retract item %s from topic %s\ntraceback:\n%s' \
@@ -262,7 +290,7 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         try:
             result = self['xep_0060'].purge(self._server, self.boundjid)
             msg = ' Purged all items from topic %s' % self.boundjid
-            self.info(msg)
+            self.debug(msg)
         except:
             error = traceback.format_exc()
             msg = ' Could not purge items from topic %s\ntraceback:\n%s' \
@@ -280,8 +308,8 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
             result = self['xep_0060'].subscribe(self._server, node)
             msg = ' Subscribed %s to topic %s' \
                     % (self.boundjid.user, node)
-            self.info(msg)
-            #self.debug(msg)
+            #self.info(msg)
+            self.debug(msg)
         except:
             error = traceback.format_exc()
             msg = ' Could not subscribe %s to topic %s\ntraceback:\n%s' \
@@ -298,51 +326,24 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         try:
             result = self['xep_0060'].unsubscribe(self._server, node)
             msg = ' Unsubscribed %s from topic %s' % (self.boundjid.bare, node)
-            self.info(msg)
+            self.debug(msg)
         except:
             error = traceback.format_exc()
             msg = ' Could not unsubscribe %s from topic %s\ntraceback:\n%s' \
                     % (self.boundjid.bare, node, error)
             self.error(msg)
 
-    def _check_for_tag(self, root, namespaces, tag):
-        """  Check if an element markup is in the ElementTree
+    def check_mailbox(self, itype, attr):
+        """ Check the mail box
 
-        :param root: Root of the tree
-        :type root: ElementTree Element
-        :param namespaces: Namespaces of the element
-        :type namespaces: str
-        :param tag: Tag that will search in the tree
-        :type tag: str
+        :param itype: type of mail
+        :type itype: str
+        :param attr: value wanted
+        :type attr: str
 
         """
-        for element in root.iter(namespaces+tag):
-            if element.text:
-                return element
-            else : 
-                return None    
-
-    def _check_output(self, root, namespaces):
-        """ Check the significative element in the answer and display it
-
-        :param root: Root of the tree
-        :type root: ElementTree Element
-        :param namespaces: Namespaces of the tree
-        :type namespaces: str
+        return self._parser.check_mailbox(itype, attr)
 
-        """
-        fields = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
-        response = ""
-        for elt in fields:
-            msg = self._check_for_tag(root, namespaces, elt)
-            if msg is not None:
-                response = response + " " + msg.text + " :"
-        deb = self._check_for_tag(root, namespaces, "MESSAGE")
-        if deb is not None:
-            msg = response + " " + deb.text
-            self.debug(msg)
-        else :
-            self.info(response)
 
     def handle_omf_message(self, iq):
         """ Handle published/received message 
@@ -351,9 +352,5 @@ class OMFClient(sleekxmpp.ClientXMPP, Logger):
         :type iq: Iq Stanza
 
         """
-        namespaces = "{http://jabber.org/protocol/pubsub}"
-        for i in iq['pubsub_event']['items']:
-            root = ET.fromstring(str(i))
-            self._check_output(root, namespaces)
-
+        self._parser.handle(iq)