Package spade :: Package xmppd :: Package modules :: Module wq
[hide private]
[frames] | no frames]

Source Code for Module spade.xmppd.modules.wq

  1  from xmpp import * 
  2  import types 
  3  import copy 
  4   
5 -class ItemNotFound(Exception):
6 - def __init__(self): pass
7 -class Conflict(Exception):
8 - def __init__(self): pass
9
10 -class Group:
11 """ 12 A XEP-142 Workgroup 13 """
14 - def __init__(self, gname, wq, users=[]):
15 self.name = gname 16 self.wq = wq 17 18 self.users = dict() 19 self.agents = dict() # An "agent" here is a client that "works" in the group and assists users 20 21 for u in users: 22 self.users[u] = None 23 self.DEBUG = self.wq.DEBUG 24 self.DEBUG("Group %s created"%(self.name),"ok")
25
26 - def fullJID(self):
27 return str(self.name) + '@' + str(self.wq.jid)
28
29 - def dispatch(self, session, stanza):
30 """ 31 Mini-dispatcher for the jabber stanzas that arrive to the group 32 """ 33 self.DEBUG("Group '"+self.getName()+"' dispatcher called") 34 if stanza.getName() == 'iq': 35 self.IQ_cb(session, stanza) 36 elif stanza.getName() == 'presence': 37 self.Presence_cb(session, stanza) 38 elif stanza.getName() == 'message': 39 self.Message_cb(session, stanza)
40 # TODO: Implement the rest of protocols 41
42 - def IQ_cb(self, session, stanza):
43 """ 44 IQ Callback for a group 45 """ 46 self.DEBUG("IQ callback of group %s called"%(self.getName()),"info") 47 join_queue = stanza.getTag('join-queue') 48 depart_queue = stanza.getTag('depart-queue') 49 queue_status = stanza.getTag('queue_status') 50 frm = str(session.peer) 51 if join_queue: 52 self.DEBUG("Join-queue","info") 53 ns = join_queue.getNamespace() 54 typ = stanza.getType() 55 queue_notifications = join_queue.getTag('queue-notifications') 56 if ns == "http://jabber.org/protocol/workgroup" and typ == 'set' and queue_notifications: 57 # User requests to join the group 58 try: 59 if self.addUser(JID(frm).getStripped()): 60 # The joining is succesful 61 reply = stanza.buildReply(typ="result") 62 session.enqueue(reply) 63 return 64 except Conflict: 65 # User already in group 66 self.DEBUG("User tried to join the same group again","warn") 67 reply = stanza.buildReply(typ="error") 68 err = Node('error', {'code': '409', 'type': 'cancel'} ) 69 conflict = Node('conflict', {'xmlns': 'urn:ietf:params:xml:ns:xmpp-stanzas'} ) 70 err.addChild(node=conflict) 71 reply.addChild(node=err) 72 session.enqueue(reply) 73 return 74 except Exception, e: 75 self.DEBUG("Unknown exception when user was joining a group","error") 76 return 77 elif depart_queue: 78 self.DEBUG("Depart-queue","info") 79 ns = depart_queue.getNamespace() 80 typ = stanza.getType() 81 jid = depart_queue.getTag('jid') 82 if ns == "http://jabber.org/protocol/workgroup" and typ == 'set': 83 # User requests departing a group 84 if jid: 85 # TODO: Authenticate user for being able to remove other jid than own 86 user = jid.getData() 87 else: 88 user = JID(frm).getStripped() 89 try: 90 if self.delUser(user): 91 # The departing is succesful 92 reply = stanza.buildReply(typ="result") 93 session.enqueue(reply) 94 m = Message(frm=self.fullJID(),to=frm) 95 dq = m.setTag("depart-queue", {"xmlns":"http://jabber.org/protocol/workgroup"}) 96 session.enqueue(m) 97 return 98 except ItemNotFound: 99 # The user was not in the group 100 self.DEBUG("User not in the group","warn") 101 reply = stanza.buildReply(typ="error") 102 err = Node('error', {'code': '404', 'type': 'cancel'} ) 103 conflict = Node('item-not-found', {'xmlns': 'urn:ietf:params:xml:ns:xmpp-stanzas'} ) 104 err.addChild(node=conflict) 105 reply.addChild(node=err) 106 session.enqueue(reply) 107 return 108 109 except Exception, e: 110 self.DEBUG("Unknown exception when user was departing a group","error") 111 return 112 elif queue_status: 113 self.DEBUG("Queue-status","info") 114 ns = queue_status.getNamespace() 115 typ = stanza.getType() 116 if ns == "http://jabber.org/protocol/workgroup" and typ == 'get': 117 # User Status Poll 118 reply = stanza.buildReply(typ="result") 119 p = Node("position") 120 p.setData("0") 121 queue_status.addChild(node=p) 122 t = Node("time") 123 t.setData("0") 124 queue_status.addChild(node=t) 125 reply.addChild(node=queue_status) 126 session.enqueue(reply) 127 return
128 129 130
131 - def addUser(self, barejid):
132 if barejid not in self.users.keys(): 133 self.users[barejid] = None 134 self.DEBUG("User %s joined group %s"%(barejid,self.getName()),"ok") 135 return True 136 else: 137 raise Conflict
138
139 - def delUser(self, barejid):
140 if barejid in self.users.keys(): 141 del self.users[barejid] 142 self.DEBUG("User %s departed group %s"%(barejid,self.getName()),"ok") 143 return True 144 else: 145 raise ItemNotFound
146
147 - def updateAgent(self, barejid, pres):
148 self.agents[barejid] = pres 149 self.DEBUG("Agent %s joined group %s"%(barejid,self.getName()),"ok") 150 return True
151
152 - def getName(self):
153 return self.name
154 - def setName(self, name):
155 self.name = name 156 return
157 158
159 -class WQ(PlugIn):
160 """ 161 The Workgroup Queues component 162 """ 163 NS = ''
164 - def plugin(self, server):
165 self.server = server 166 try: 167 self.jid = server.plugins['WQ']['jid'] 168 self.name = server.plugins['WQ']['name'] 169 except: 170 self.DEBUG("Could not find MUC jid or name","error") 171 return 172 173 self.groups = dict() 174 175 # Test stuff 176 g = Group("test", self) 177 self.addGroup(g) 178 179 self.DEBUG("Created WQ: '%s' '%s'"%(self.name,str(self.jid)), "warn")
180
181 - def addGroup(self, group, name = ""):
182 if not group and not name: 183 # WTF 184 self.DEBUG("addGroup called without parameters","warn") 185 return False 186 elif not group and name: 187 group = Group(name, self) 188 elif group: 189 if group.getName() in self.groups.keys(): 190 return False 191 else: 192 self.groups[group.getName()] = group 193 self.DEBUG("Added group %s to Workgroup Queues"%(group.getName()),"ok") 194 return True
195
196 - def addUser(self, barejid, gname):
197 if gname not in self.groups.keys(): 198 # Group does not exist 199 raise ItemNotFound 200 else: 201 # User tries to join group 202 self.groups[gname].addUser(barejid)
203
204 - def dispatch(self, session, stanza):
205 """ 206 Mini-dispatcher for the jabber stanzas that arrive to the WQ 207 """ 208 self.DEBUG("WQ dispatcher called", "warn") 209 try: 210 to = stanza['to'] 211 gname = to.getNode() 212 domain = to.getDomain() 213 except: 214 self.DEBUG("There was no 'to'",'warn') 215 216 # No group name. Stanza directed to the WQ 217 if gname == '' and domain == str(self.jid): 218 if stanza.getName() == 'iq': 219 self.IQ_cb(session, stanza) 220 elif stanza.getName() == 'presence': 221 self.Presence_cb(session, stanza) 222 # TODO: Implement the rest of protocols 223 # Stanza directed to a specific group 224 if gname in self.groups.keys() and domain == str(self.jid): 225 self.groups[gname].dispatch(session, stanza) 226 else: 227 # The room does not exist 228 self.notExist_cb(session,stanza)
229