3 from sleekxmpp.exceptions import IqError, IqTimeout
5 import xml.etree.ElementTree as ET
9 class OMFClient(sleekxmpp.ClientXMPP):
11 .. class:: Class Args :
13 :param jid: Jabber Id (= Xmpp Slice + Date)
15 :param password: Jabber Password (= Xmpp Password)
20 This class is an XMPP Client with customized method
24 def __init__(self, jid, password):
25 sleekxmpp.ClientXMPP.__init__(self, jid, password)
27 self._registered = False
30 self.register_plugin('xep_0077') # In-band registration
31 self.register_plugin('xep_0030')
32 self.register_plugin('xep_0059')
33 self.register_plugin('xep_0060') # PubSub
35 self.add_event_handler("session_start", self.start)
36 self.add_event_handler("register", self.register)
37 self.add_event_handler("pubsub_publish", self.handle_omf_message)
39 self._logger = logging.getLogger("neco.omf.xmppClient")
40 self._logger.setLevel(neco.LOGLEVEL)
46 def start(self, event):
49 self._server = "pubsub.%s" % self.boundjid.domain
51 def register(self, iq):
53 self._logger.info("%s already registered!" % self.boundjid)
58 resp['register']['username'] = self.boundjid.user
59 resp['register']['password'] = self.password
63 self._logger.info("Account created for %s!" % self.boundjid)
64 self._registered = True
66 self._logger.error("Could not register account: %s" %
67 e.iq['error']['text'])
69 self._logger.error("No response from server.")
73 self.plugin['xep_0077'].cancel_registration(
74 ifrom=self.boundjid.full)
75 self._logger.info("Account unregistered for %s!" % self.boundjid)
77 self._logger.error("Could not unregister account: %s" %
78 e.iq['error']['text'])
80 self._logger.error("No response from server.")
84 result = self['xep_0060'].get_nodes(self._server)
85 for item in result['disco_items']['items']:
86 self._logger.info(' - %s' % str(item))
89 error = traceback.format_exc()
90 self._logger.error('Could not retrieve node list.\ntraceback:\n%s', error)
92 def subscriptions(self):
94 result = self['xep_0060'].get_subscriptions(self._server)
96 for node in result['node']:
97 self._logger.info(' - %s' % str(node))
100 error = traceback.format_exc()
101 self._logger.error('Could not retrieve subscriptions.\ntraceback:\n%s', error)
103 def create(self, node):
104 self._logger.debug(" Create Topic : " + node)
106 config = self['xep_0004'].makeForm('submit')
107 config.add_field(var='pubsub#node_type', value='leaf')
108 config.add_field(var='pubsub#notify_retract', value='0')
109 config.add_field(var='pubsub#publish_model', value='open')
110 config.add_field(var='pubsub#persist_items', value='1')
111 config.add_field(var='pubsub#max_items', value='1')
112 config.add_field(var='pubsub#title', value=node)
115 self['xep_0060'].create_node(self._server, node, config = config)
117 error = traceback.format_exc()
118 self._logger.error('Could not create topic: %s\ntraceback:\n%s' % (node, error))
120 def delete(self, node):
122 self['xep_0060'].delete_node(self._server, node)
123 self._logger.info('Deleted node: %s' % node)
125 error = traceback.format_exc()
126 self._logger.error('Could not delete topic: %s\ntraceback:\n%s' % (node, error))
128 def publish(self, data, node):
129 self._logger.debug(" Publish to Topic :" + node)
131 result = self['xep_0060'].publish(self._server,node,payload=data)
132 # id = result['pubsub']['publish']['item']['id']
133 # print('Published at item id: %s' % id)
135 error = traceback.format_exc()
136 self._logger.error('Could not publish to: %s\ntraceback:\n%s' \
141 result = self['xep_0060'].get_item(self._server, self.boundjid,
143 for item in result['pubsub']['items']['substanzas']:
144 self._logger.info('Retrieved item %s: %s' % (item['id'],
145 tostring(item['payload'])))
147 error = traceback.format_exc()
148 self._logger.error('Could not retrieve item %s from topic %s\ntraceback:\n%s' \
149 % (data, self.boundjid, error))
151 def retract(self, data):
153 result = self['xep_0060'].retract(self._server, self.boundjid, data)
154 self._logger.info('Retracted item %s from topic %s' % (data, self.boundjid))
156 error = traceback.format_exc()
157 self._logger.error('Could not retract item %s from topic %s\ntraceback:\n%s' \
158 % (data, self.boundjid, error))
162 result = self['xep_0060'].purge(self._server, self.boundjid)
163 self._logger.info('Purged all items from topic %s' % self.boundjid)
165 error = traceback.format_exc()
166 self._logger.error('Could not purge items from topic %s\ntraceback:\n%s' \
167 % (self.boundjid, error))
169 def subscribe(self, node):
171 result = self['xep_0060'].subscribe(self._server, node)
172 #self._logger.debug('Subscribed %s to node %s' \
173 #% (self.boundjid.bare, node))
174 self._logger.info(' Subscribed %s to topic %s' \
175 % (self.boundjid.user, node))
177 error = traceback.format_exc()
178 self._logger.error(' Could not subscribe %s to topic %s\ntraceback:\n%s' \
179 % (self.boundjid.bare, node, error))
181 def unsubscribe(self, node):
183 result = self['xep_0060'].unsubscribe(self._server, node)
184 self._logger.info(' Unsubscribed %s from topic %s' % (self.boundjid.bare, node))
186 error = traceback.format_exc()
187 self._logger.error(' Could not unsubscribe %s from topic %s\ntraceback:\n%s' \
188 % (self.boundjid.bare, node, error))
190 def _check_for_tag(self, treeroot, namespaces, tag):
191 for element in treeroot.iter(namespaces+tag):
197 def _check_output(self, treeroot, namespaces):
198 output_param = ["TARGET", "REASON", "PATH", "APPID", "VALUE"]
200 for elt in output_param:
201 msg = self._check_for_tag(treeroot, namespaces, elt)
203 response = response + " " + msg.text + " :"
204 deb = self._check_for_tag(treeroot, namespaces, "MESSAGE")
206 self._logger.debug(response + " " + deb.text)
208 self._logger.info(response)
210 def handle_omf_message(self, iq):
211 namespaces = "{http://jabber.org/protocol/pubsub}"
212 for i in iq['pubsub_event']['items']:
213 root = ET.fromstring(str(i))
214 self._check_output(root, namespaces)