1
2 import time
3 import ACLMessage
4 import MessageReceiver
5 import threading
6 import types
7 import copy
8 import colors
9 import sys
10 import traceback
11
12 from xmpp import Node, Message, Presence, Iq
13 import xmpp
14 import re
15
16
18 """
19 Template operators
20 """
21
24
25 - def match(self, message):
27
29 """Implementation of & operator"""
30 return ANDTemplate(self, other)
32 """Implementation of &= operator"""
33 return (self & other)
34
36 """Implementation of | operator"""
37 return ORTemplate(self, other)
39 """Implementation of |= operator"""
40 return (self | other)
41
43 """Implementation of ^ operator"""
44 return XORTemplate(self, other)
46 """Implementation of ^= operator"""
47 return (self ^ other)
49 """Implementation of ~ operator"""
50 return NOTTemplate(self)
51
52
54 """
55 Template for message matching
56 """
58 self.performative = performative
59 self.sender = None
60 self.receivers = []
61 self.reply_to = []
62 self.content = None
63 self.reply_with = None
64 self.reply_by = None
65 self.in_reply_to = None
66 self.encoding = None
67 self.language = None
68 self.ontology = None
69 self.protocol = None
70 self.conversation_id = None
71
72
74 return str({"performative":self.performative,"sender":str(self.sender),"receivers":str(self.receivers),"reply_to":self.reply_to, "content":self.content,"reply_with":self.reply_with, "reply_by":self.reply_by, "in_reply_to":self.in_reply_to,"encoding":self.encoding, "language":self.language, "ontology":self.ontology,"protocol":self.protocol, "conversation_id":self.conversation_id})
75
78
81
84
86 self.receivers.append(recv)
87
89 if recv in self.receivers:
90 self.receivers.remove(recv)
91
94
95
99
101 if re in self.reply_to:
102 self.reply_to.remove(re)
103
106
109
112
113 - def setContent(self,c):
115
116 - def getContent(self):
118
121
123 return self.reply_with
124
126 self.in_reply_to = reply
127
129 return self.in_reply_to
130
133
136
139
144
149
152
155
159 self.conversation_id = e
160
162 return self.conversation_id
163
164
168 - def match(self, message):
170
173 self.expr1 = expr1
174 self.expr2 = expr2
175 - def match(self, message):
177
180 self.expr1 = expr1
181 self.expr2 = expr2
182 - def match(self, message):
184
187 self.expr1 = expr1
188 self.expr2 = expr2
189 - def match(self, message):
191
192
193 '''
194 class PresenceTemplate(BehaviourTemplate):
195 """
196 Template for presence notifications
197 """
198 def __init__(self, frm=None, type=None, status=None, show=None, role=None, affiliation=None):
199 self._frm, self._type, self._status, self._show, self._role, self._affiliation = frm,type,status,show,role,affiliation
200 '''
201
202
204 - def __init__(self, Template, regex=False):
215
216
253
254
256 """
257 Function that matches a xmpp Node with another one
258 """
259
260 try:
261
262 if type(self.template) != types.InstanceType:
263
264 return False
265
266 if "Message" not in str(self.template.__class__) and "Presence" not in str(self.template.__class__) and "Iq" not in str(self.template.__class__) and "Node" not in str(self.template.__class__):
267
268 return False
269
270 if type(other) != types.InstanceType:
271
272 return False
273
274 if "Message" not in str(other.__class__) and "Presence" not in str(other.__class__) and "Iq" not in str(other.__class__) and "Node" not in str(self.template.__class__):
275
276 return False
277
278 if self.template.name != None:
279 if self.template.name != other.name:
280
281 return False
282 if self.template.attrs != None and self.template.attrs != {}:
283
284
285 for i,j in self.template.attrs.items():
286
287 if (i,j) not in (other.attrs.items()):
288
289 if not self.regex:
290 return False
291 if not re.match(str(j),str(other.attrs[i])):
292 return False
293 if self.template.data != None and self.template.data != []:
294 if self.template.data != other.data:
295
296 if not self.regex:
297 return False
298 if not re.match(str(self.template.data[0]),str(other.data[0])):
299 return False
300
301
302 if self.template.namespace:
303 if self.template.namespace != other.namespace:
304
305 return False
306
307 for kid in self.template.kids:
308
309 suspects = other.getTags(kid.getName())
310 if not suspects: return False
311 value = False
312 for s in suspects:
313 value = MessageTemplate(kid,regex=self.regex).node_match(s)
314
315 if value == True:
316
317 break
318 if not value:
319
320 return False
321
322 except Exception, e:
323
324 return False
325
326 return True
327
329
330 frm,type,status,show,role,affiliation = message.frm,message.type,message.status,message.show,message.role,message.affiliation
331
332
333 if self._type !=None and type != self._type: return False
334 if self._status !=None and status != self._status: return False
335 if self._show !=None and show != self._show: return False
336 if self._role !=None and role != self._role: return False
337 if self._affiliation != None and affiliation != self._affiliation: return False
338
339 if self._frm:
340 if not JID(self._frm).getResource():
341 if self._frm != JID(frm).getBareJID():
342 return False
343 else:
344 if self._frm != frm: return False
345
346 return True
347
350
353
354
355
356
357
358 -class Behaviour(MessageReceiver.MessageReceiver):
367
368 """
369 def __getattr__(self, aname):
370 return self.myAgent.__dict__[aname]
371
372 def __setattr__(self, aname, value):
373 # Base case: aname is defined locally
374 if aname in self.__dict__:
375 self.__dict__[aname] = value
376 # Second case: aname is defined in "myAgent"
377 elif "myAgent" in self.__dict__ and self.__dict__["myAgent"] and aname in self.myAgent.__dict__:
378 setattr(self.myAgent, aname, value)
379 # Third case: new local declaration
380 else:
381 self.__dict__[aname] = value
382 """
383
385 self.myParent = parent
389 """
390 sets the agent which controls the behavior
391 """
392 self.myAgent = agent
393 self.DEBUG = self.myAgent.DEBUG
394 try:
395 self.setName(str(self.myAgent.getName()) + " Behaviour")
396 except:
397 pass
398
400 """
401 returns the agent which controls the behavior
402 """
403 return self.myAgent
405 if (self.myParent != None):
406 return self.myParent.root()
407 else:
408 return self
409
411 """
412 returns True if the behavior has finished
413 else returns False
414 """
415 return False
416
418 """
419 main loop
420 must be overridden
421 """
422 raise NotImplementedError
423
425 """
426 stops the behavior
427 """
428 try:
429 self._forceKill.set()
430 except:
431
432 self.myAgent.DEBUG("Behavior " +str(self)+ " is already dead","warn/")
433
435 """
436 this method runs when the behavior starts
437 """
438 pass
440 """
441 this method runs when the behavior stops
442 """
443 pass
445 """
446 returns the default exit code for the behavior
447 """
448 return self._exitcode
449
451 if not self.myAgent._running:
452
453 self.myAgent.behavioursGo.acquire()
454 self.myAgent.behavioursGo.wait()
455 self.myAgent.behavioursGo.release()
456
457 """
458 # Check wether this behaviour has already started
459 if not self._running:
460 self._running = True
461 else:
462 # The behaviour was already running, no need to run run (he he) twice
463 return
464 """
465 self.onStart()
466 try:
467 while (not self.done()) and (not self._forceKill.isSet()):
468 self._exitcode = self._process()
469 except Exception,e:
470 self.myAgent.DEBUG("Exception in Behaviour "+str(self)+": "+str(e), "err")
471 self.onEnd()
472
473
474
475 if not issubclass(self.__class__, EventBehaviour):
476 self.myAgent.removeBehaviour(self)
477
479 """
480 DEPRECATED
481 register a handler that will manage all incoming presence notifications matching the given presence template
482 """
483 self._presenceHandlers[handler] = template
484
485 - def managePresence(self, frm=None, type=None, status=None, show=None, role=None, affiliation=None):
486 """
487 DEPRECATED
488 manage a FIPA-formed presence message
489 """
490 class struct:
491 def __init__(self,frm,type,status,show,role,affiliation):
492 self.frm,self.type,self.status,self.show,self.role,self.affiliation=frm,type,status,show,role,affiliation
493
494 for handler in self._presenceHandlers:
495 t = self._presenceHandlers[handler]
496 if t:
497 if t.match(struct(frm,type,status,show,role,affiliation)):
498 handler(frm,type,status,show,role,affiliation)
499
501 """
502 Set the message template for this behaviour
503 """
504 if self.myAgent:
505 self.myAgent._behaviourList[self] = template
506
507
509 """
510 this behavior is only executed once
511 """
516 if (self._firsttime == True):
517 self._firsttime = False
518 return False
519 return True
520
521
522
523
525 """
526 this behavior runs periodically with a period
527 """
528 - def __init__(self, period, timestart = None):
529 Behaviour.__init__(self)
530 self._period = period
531 if (timestart == None):
532 self._nextActivation = time.time()
533 else:
534 self._nextActivation = timestart
535
539 self._period = period
540
542 if time.time() >= self._nextActivation:
543 self._exitcode = self._onTick()
544 while self._nextActivation <= time.time():
545 self._nextActivation += self._period
546 else:
547 t = self._nextActivation - time.time()
548 if t > 0:
549 time.sleep(t)
550 return self._exitcode
551
553 """
554 this method is executed every period
555 must be overridden
556 """
557 raise NotImplementedError
558
559
561 """
562 this behavior is executed only once after a timeout
563 """
567
571 """
572 cancels the programmed execution
573 """
574 self._stop = True
577
579 if (self._stop == False):
580 self.timeOut()
581 self.stop()
582
584 """
585 this method is executed after the timeout
586 must be overridden
587 """
588 raise NotImplementedError
589
590
591
592
593
595 """
596 this behavior is executed according to a Finite State Machine
597 """
599 Behaviour.__init__(self)
600 self._firstStateName = None
601 self._lastStatesNames = []
602 self._states = dict()
603 self._transitions = dict()
604 self._actualState = None
605 self._lastexitcode = None
606 self._destroy = False
607 self._firsttime = True
608
610 """
611 sets the parent agent
612 """
613
614 Behaviour.setAgent(self, agent)
615 for b in self._states:
616 self._states[b].setAgent(agent)
617
619 """
620 registers a state with a behavior
621 """
622 if not issubclass(behaviour.__class__, OneShotBehaviour):
623 print "WARNING! Registering not-OneShot as FSM state"
624 behaviour.setParent(self)
625 self._states[name]=behaviour
626 self._transitions[name]=dict()
627 behaviour._receive = self._receive
628 behaviour.setTemplate = self.setTemplate
629 behaviour._stateName = name
630
632 """
633 sets the first state of the fsm
634 """
635 self.registerState(behaviour, name)
636 self._firstStateName = name
637
644
646 """
647 registers a transition between two states
648 """
649 self._transitions[fromname][event] = toname
650
652 return self._states[name]
653
654
655
656
657
658
659
660
661
662
664 return self._lastexitcode
665
667 if self._actualState in self._lastStatesNames:
668 if self._firsttime == True:
669
670
671 self._firsttime = False
672 return False
673 else:
674 return True
675 else: return False
676
678 try:
679 b = self._states[self._actualState]
680 b.onEnd()
681 except KeyError:
682 pass
683 self._actualState = newState
684 try:
685 b = self._states[self._actualState]
686 b.onStart()
687 except KeyError:
688 pass
689
691 if (self._actualState == None):
692 self._transitionTo(self._firstStateName)
693
694 b = self._states[self._actualState]
695
696 self._lastexitcode = b._process()
697 if (b.done() or b._forceKill.isSet()):
698 if not self._lastexitcode: self._lastexitcode = b.exitCode()
699 self._transitionTo(self._transitions[b._stateName][self._lastexitcode])
700 self._lastexitcode = None
701
702
704 return self._states[self._actualState]
705
706
707
708
710 """
711 A behaviour that is executed in response to a certain event.
712 The 'onetime' parameter in the constructor represents the
713 re-usability of the behaviour. By default, an Event behaviour is
714 re-instanced (and re-launched) every time a new event that matches
715 the template arrives. This can be changed by setting 'onetime'
716 to True, which renders the behaviour for one use only
717 """
718
720 OneShotBehaviour.__init__(self)
721 self.onetime = onetime
722
723
724
725
726
727
728 if __name__ == "__main__":
733 print "Tick: " + str(time.time())
734
735 a = TestBehaviour(5)
736 a.start()
737