aboutsummaryrefslogtreecommitdiff
path: root/src/IvyCpy.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/IvyCpy.py')
-rw-r--r--src/IvyCpy.py646
1 files changed, 646 insertions, 0 deletions
diff --git a/src/IvyCpy.py b/src/IvyCpy.py
new file mode 100644
index 0000000..f83d432
--- /dev/null
+++ b/src/IvyCpy.py
@@ -0,0 +1,646 @@
+# -*- coding: iso-8859-1 -*-
+REVISION = "$Id: "
+
+# import
+import threading
+import ivycpy
+import sys
+import traceback
+import re
+import os
+
+##
+# class Ivy
+# this class is an Object oriented interface for the Ivy-c Library
+#
+class Ivy:
+
+ ##
+ # __init__()
+ # initialisation method
+ # this method creates an Ivy Object and initializes an ivybus
+ # @param name: name of the application to connect
+ # @param message: the message displayed on connection
+ # @param aIvyApplicationListener: the reference to the object used to treat connection / disconnection event for applications
+ #
+ def __init__(self, name, message, aIvyApplicationListener):
+ self.lIvyApplicationlisteners=[]
+ self.dIvyClient={}
+ self.addApplicationListener(aIvyApplicationListener)
+ self.sReadyMessage=message
+ self.sAppName=name
+ self.dRegexp={}
+ self.lBindListeners=[]
+ self.sendToSelf = False
+ self.selfIvyClient = Ivy.SelfIvyClient(self)
+ self.dIvyClient[str(self.selfIvyClient)] = self.selfIvyClient
+ ivycpy.IvyInit(name,
+ message,
+ 0,
+ self._appliCallback,
+ self._die)
+
+ ##
+ # method called on instruction Ivy()
+ # this method creates and starts a thread listening for ivy events
+ #
+ def __call__(self):
+ self.theThread=threading.Thread(target=self.mainloop)
+ self.theThread.setDaemon(1)
+ self.theThread.start()
+
+ ##
+ # this method returns the IvyClient associated to an ivy-c client
+ # @param ivyclient: the reference of the ivy-c client in the local database
+ # @return the Ivy.IvyClient object corresponding to the ivyclient identifier
+ #
+ def getIvyClient(self, ivyclient):
+ ivyClient = None
+ if not self.dIvyClient.has_key(str(ivyclient)):
+ ivyClient = Ivy.IvyClient(ivyclient)
+ self.dIvyClient[str(ivyclient)] = ivyClient
+ else:
+ ivyClient = self.dIvyClient[str(ivyclient)]
+ return ivyClient
+
+ ##
+ # getter of self Ivy client attribute
+ # @return this IvyClient object
+ #
+ def getSelfIvyClient(self):
+ return self.selfIvyClient
+
+ ##
+ # getter of an Ivy client using his name
+ # @param name: name of the client
+ # @return the reference of the Ivy.IvyClient with the given name
+ #
+ def getIvyClientsByName(self, name):
+ ivyclient = ivycpy.IvyGetApplication(name)
+ return self.getIvyClient(ivyclient)
+
+ ##
+ # method returning the ivy-c clients connected to the ivybus
+ # @return the list of Ivy.IvyClient connected to the ivybus
+ #
+ def getIvyClients(self):
+ lIvyClient = [ self.getIvyClientsByName(client)
+ for client in ivycpy.IvyGetApplicationList(",").split(",")]
+ # suppression du dernier element car element vide
+ lIvyClient.pop()
+ return lIvyClient
+
+ ##
+ # methods starting the connection to ivybus
+ # @param sdomainbus: address used for braodcast
+ #
+ def start(self, sdomainbus):
+ #a partir de la chaine de caracteres
+ addr, port = sdomainbus.split(":")
+ self.sDomainBus= Ivy.Domain(addr, port)
+ ivycpy.IvySetBindCallback(self._bindCallback)
+ ivycpy.IvyBindDirectMsg(self._directMessage)
+ ivycpy.IvyStart(sdomainbus)
+
+ ##
+ # methods stopping the connection to ivybus
+ #
+ def stop(self):
+ ivycpy.IvyStop()
+
+ ##
+ # method launching the ivy mainloop in charge of listening events on the ivybus
+ #
+ def mainloop(self):
+ ivycpy.IvyMainLoop()
+
+ ##
+ # method adding a ivy binding event listener to database
+ # @param aBindListener: listener for ivy event
+ #
+ def addBindListener(self, aBindListener):
+ self.lBindListeners.append(aBindListener)
+
+ ##
+ # method removing an ivy binding event listener from database
+ # @param aBindListener: the listener to remove
+ #
+ def removeBindListener(self, aBindListener):
+ self.lBindListeners.remove(aBindListener)
+
+ ##
+ # method adding application listener to database
+ # @param aApplicationListener: the listener to application connection
+ #
+ def addApplicationListener(self, aApplicationListener):
+ self.lIvyApplicationlisteners.append(aApplicationListener)
+
+ ##
+ # method removing application listener from database
+ # @param aApplicationListener: the listener to remove
+ #
+ def removeApplicationListener(self, aApplicationListener):
+ try:
+ self.lIvyApplicationlisteners.remove(aApplicationListener)
+ except ValueError, x:
+ IvyException(str(x))()
+
+ ##
+ # protected method called on bindings events
+ # @param client: reference to the ivy-c subscribing client
+ # @param id : unique id of the binding
+ # @param regexp: regular expression to match
+ # @param event: binding or removal of an existing binding
+ #
+ def _bindCallback(self, client, id, regexp, event):
+ if (event == ivycpy.IvyAddBind ):
+ for bl in self.lBindListeners:
+ bl.bindPerformed(client, id, regexp)
+ elif (event == ivycpy.IvyRemoveBind ):
+ for bl in self.lBindListeners:
+ bl.unbindPerformed(client, id, regexp)
+
+ ##
+ # method called on applications connection
+ # @param ivyclient: reference to the client connected or disconnected
+ # @param connected: connection or disconnection
+ #
+ def _appliCallback(self, ivyclient, connected):
+ ivyClient = self.getIvyClient(ivyclient)
+ if connected == ivycpy.IvyApplicationConnected:
+ self._connect(ivyClient)
+ else:
+ self._disconnect(ivyClient)
+
+ ##
+ # method calling the connect method of the applications listeners
+ # @param arg: anything
+ #
+ def _connect(self, *arg):
+ for listener in self.lIvyApplicationlisteners:
+ listener.connect(*arg)
+
+ ##
+ # method calling the disconnect method of the applications listeners
+ # @param arg: anything
+ #
+ def _disconnect(self, *arg):
+ for listener in self.lIvyApplicationlisteners:
+ listener.disconnect(*arg)
+
+ ##
+ # method called on die message
+ # @param ivyclient: reference to the client to kill
+ # @param id: id of the message
+ #
+ def _die(self, ivyclient, id):
+ ivyClient = self.getIvyClient(ivyclient)
+ for listener in self.lIvyApplicationlisteners:
+ listener.die(ivyClient, id)
+
+ ##
+ # method called on direct message
+ # @param ivyclient: reference of the client
+ # @param id: id of the message
+ # @param msg: the message
+ #
+ def _directMessage(self, ivyclient, id, msg):
+ ivyClient = self.getIvyClient(ivyclient)
+ for listener in self.lIvyApplicationlisteners:
+ listener.directMessage(ivyClient, id, msg)
+
+ ##
+ # method which binds message for application
+ # @param regexp: the regular expression to match
+ # @param aIvyMessageListener: the listener to call on reception
+ # @return the id of the subscription
+ #
+ def bindMsg(self, regexp, aIvyMessageListener):
+ id = ivycpy.IvyBindMsg(aIvyMessageListener.receive,regexp)
+ self.dRegexp[regexp] = id
+ self.selfIvyClient.bindMsg(regexp,aIvyMessageListener,id)
+ return id
+
+ ##
+ # method which unbinds message for client
+ # @param param: regexp or id of the message to unbind
+ #
+ def unBindMsg(self, param):
+ if type(param) == type(1):
+ ivycpy.IvyUnBindMsg(param)
+ self.selfIvyClient.unbindMsg(param)
+ else:
+ if self.dRegexp.has_key(param):
+ self.selfIvyClient.unbindMsg(param)
+ id=self.dRegexp[param]
+ ivycpy.IvyUnBindMsg(id)
+ else:
+ IvyException("This expression did not exist")()
+
+ ##
+ # method sending message on the ivybus
+ # @param message: the message to send
+ # @return the result of the operation 0 if error, 1 if ok
+ #
+ def sendMsg(self, message):
+ if self.getSendToSelf() is True:
+ self.selfIvyClient.sendMsg(message)
+ return ivycpy.IvySendMsg(message)
+
+ ##
+ # method sending a die message to the ivy-c client
+ # @param ivyclient : ivy-c client to kill
+ #
+ def sendDie(self, ivyclient):
+ if type(ivyclient) == type(self.selfIvyClient):
+ self.selfIvyClient.sendDie()
+ else:
+ ivycpy.IvySendDieMsg(ivyclient)
+
+ ##
+ # methods sending a message directly to a client
+ # @param ivyclient : the ivy-c client to contact
+ # @param id : id with no real meanings
+ # @param message : the message to send
+ #
+ def sendDirectMsg(self, ivyclient, id, message):
+ if type(ivyclient) == type(self.selfIvyClient):
+ self.selfIvyClient.sendDirectMsg(id, message)
+ else :
+ ivycpy.IvySendDirectMsg(ivyclient,id,message)
+
+ ##
+ # methods sending an error message directly to a client
+ # @param ivyclient : the ivy-c client to contact
+ # @param id : id with no real meanings
+ # @param error : the message to send
+ #
+ def sendError(self, ivyclient, id, error):
+ if type(ivyclient) == type(self.selfIvyClient):
+ self.selfIvyClient.sendError(id, error)
+ else:
+ ivycpy.IvySendError(ivyclient,id,error)
+
+ ##
+ # method launching a timer
+ # @param nbticks : number of ticks
+ # @param delay: delay before launching
+ # @param callback: method to call at the end
+ # @return the id of the timer
+ #
+ def timer_repeat(self, nbticks, delay, callback):
+ try:
+ timerid = ivycpy.IvyTimerRepeatAfter(nbticks, long(delay), callback)
+ except:
+ IvyException("An error occurred in IvyTimerRepeatAfter")()
+ timerid = None
+
+ return (timerid)
+
+ ##
+ # method modifying the timer
+ # @param timerid: id of the timer to modify
+ # @param newdelay: waiting delay
+ #
+ def timer_modify(self, timerid, newdelay):
+ ivycpy.IvyTimerModify(timerid, long(newdelay))
+
+ ##
+ # method removing timer
+ # @param timerid: id of the timer to remove
+ #
+ def timer_remove(self, timerid):
+ ivycpy.IvyTimerRemove(timerid)
+
+ ##
+ # method setting the value of boolean sendToSelf
+ # @param value : boolean representing the falg sendToSelf
+ #
+ def setSendToSelf(self, value):
+ self.sendToSelf = value
+
+ ##
+ # method returning the value of the flag sendToSelf
+ # @return boolean representing the value of the flag sendToSelf
+ #
+ def getSendToSelf(self):
+ return self.sendToSelf
+
+ ##
+ # class IvyClient
+ # this class encapsulates an ivy-c client and gives methodes to access this client
+ #
+ class IvyClient:
+
+ ##
+ # initialisation of the IvyClient
+ # @param ptr: (ivy-c client) pointer on the ivy-c client
+ #
+ def __init__(self, ptr):
+ self.ptr = ptr
+
+ ##
+ # getter of the ivy-c client attribute
+ # @return a pointer on an ivy-c client
+ #
+ def getPtr(self):
+ return self.ptr
+
+ ##
+ # getter of the ivy-c client name
+ # @return a string representing the name of the ivy-c client
+ #
+ def getName(self):
+ return ivycpy.IvyGetApplicationName(self.ptr)
+
+ ##
+ # getter of the ivy-c client host
+ # @return a string representing the host of the ivy-c client
+ #
+ def getHost(self):
+ return ivycpy.IvyGetApplicationHost(self.ptr)
+
+ ##
+ # getter of the ivy-c client messages bindings
+ # @return a table of strings representing the message for this ivy-c client
+ #
+ def getMessages(self):
+ return ivycpy.IvyGetApplicationMessages(self.ptr)
+
+ ##
+ # method sending a die message to the ivy-c client
+ # @param ivyclient : ivy-c client to kill
+ #
+ def sendDie(self):
+ ivycpy.IvySendDieMsg(self.ptr)
+
+ ##
+ # methods sending a message directly to a client
+ # @param ivyclient : the ivy-c client to contact
+ # @param id : id with no real meanings
+ # @param message : the message to send
+ #
+ def sendDirectMsg(self, id, message):
+ ivycpy.IvySendDirectMsg(self.ptr,id,message)
+
+ ##
+ # methods sending an error message directly to a client
+ # @param ivyclient : the ivy-c client to contact
+ # @param id : id with no real meanings
+ # @param error : the message to send
+ #
+ def sendError(self, id, error):
+ ivycpy.IvySendError(self.ptr,id,error)
+
+ ##
+ # class SelfIvyClient
+ # this class works like an IvyClient class but represents the application client
+ #
+ class SelfIvyClient(IvyClient):
+
+ ##
+ # initialization of the SelfIvyClient
+ # @param ptr: pointer on the Ivy object
+ #
+ def __init__(self, ptr):
+ self.ptr = ptr
+ self.dBindings = {}
+ self.dId2Regexp = {}
+ self.dRegexp2Id = {}
+
+ ##
+ # getter of the ptr attribute
+ # @return a pointer on an Ivy object
+ #
+ def getPtr(self):
+ return self.ptr
+
+ ##
+ # getter of the self Client name
+ # @return a string representing the name of the selfclient
+ #
+ def getName(self):
+ return self.ptr.sAppName
+
+ ##
+ # getter of the self Client host
+ # @return a string representing the host of the selfclient
+ #
+ def getHost(self):
+ return os.uname()[1]
+
+ ##
+ # getter of the self Client messages bindings
+ # @return a tuple of strings representing the message for this selfIvyClient
+ #
+ def getMessages(self):
+ return tuple(self.ptr.dRegexp.keys())
+
+ ##
+ # method sending a die message to the self Client
+ #
+ def sendDie(self):
+ self.ptr._die(self,0)
+
+ ##
+ # methods sending a message directly to self Client
+ # @param id : id with no real meanings
+ # @param message : the message to send
+ #
+ def sendDirectMsg(self, id, message):
+ self.ptr._directMessage(self,id,message)
+
+ ##
+ # methods sending an error message directly to self Client
+ # @param id : id with no real meanings
+ # @param error : the message to send
+ #
+ def sendError(self, id, error):
+ self.ptr._directMessage(self,id,error)
+
+ ##
+ # method sending a message to self
+ # @param message : string representing the message to send
+ #
+ def sendMsg(self,message):
+ for regexp in self.dBindings.keys():
+ r = re.compile(regexp)
+ captures = r.match(message)
+ if captures:
+ captures=captures.groups()
+ if len(captures)==0:
+ captures=''
+ self.dBindings[regexp](message)
+
+ ##
+ # method in charge of treating bindings
+ # @param regexp : String representing the regular expression to match
+ # @param aIvyMessageListener : the reference to object to call on reception
+ # @param id : id with no real meanings
+ #
+ def bindMsg(self, regexp, aIvyMessageListener, id):
+ self.dId2Regexp[id] = regexp
+ self.dRegexp2Id[regexp] = id
+ self.dBindings[regexp] = aIvyMessageListener.receive
+
+ ##
+ # method sending a message to self
+ # @param message : id or regexp to delete
+ #
+ def unbindMsg(self, param):
+ if type(param) == type(1):
+ regexp = self.dId2Regexp.pop(param)
+ self.dRegexp2Id.pop(regexp)
+ self.dBindings.pop(regexp)
+ else:
+ if self.dRegexp.has_key(param):
+ id = self.dRegexp2Id.pop(param)
+ self.dRegexp2Id.pop(id)
+ self.dBindings.pop(param)
+ else:
+ IvyException("This expression did not exist")()
+
+ ##
+ # class domain
+ # this class contains and allows access to ivybus properties
+ #
+ class Domain:
+ ##
+ # initialisation method
+ # @param domainaddr: Ip adress for broadcast
+ # @param port: port for braodcast
+ #
+ def __init__(self, domainaddr, port):
+ self.domainaddr=domainaddr
+ self.port=port
+
+ ##
+ # method call on print
+ # display address and port used by ivybus
+ # @return the string to print
+ #
+ def __str__(self):
+ return self.domainaddr+":"+self.port
+
+ ##
+ # getter of broadcast Ip adress
+ # @return the IP address
+ #
+ def getDomainaddr(self):
+ return self.domainaddr
+
+ ##
+ # getter of broadcast port
+ # @return the IP port
+ #
+ def getPort(self):
+ return self.port
+
+
+##
+# IvyApplicationAdapter
+# Classe d'objets abstraite definissant l'interface des objets a fournir a l'objet de classe Ivy
+# lors de son initialisation et par les methodes addApplicationListener et removeApplicationListener
+#
+class IvyApplicationAdapter :
+
+ ##
+ # abstract method called on application connection
+ # @param client: name of the client
+ #
+ def connect(self,client):
+ pass
+
+ ##
+ # abstract method called on application disconnection
+ # @param client: name of the client
+ #
+ def disconnect(self,client):
+ pass
+
+ ##
+ # abstract method called on die message
+ # @param client: name of the client
+ # @param id: id of the message
+ #
+ def die(self,client, id):
+ pass
+
+ ##
+ # abstract method called on direct message
+ # @param client: name of the client
+ # @param id: id of the client
+ # @param msg: message sent
+ #
+ def directMessage(self, client, id, msg):
+ pass
+
+##
+# IvyBindAdapter
+# Classe d'objets abstraite definissant l'interface des objets
+# a fournir a l'objet de classe Ivy
+# via addBindListener et removeBindListener
+#
+class IvyBindAdapter :
+
+ ##
+ # invoked when a Ivy Client performs a bind
+ # @param client: name of the client
+ # @param id: id of the client
+ # @param regexp: regular expression to match
+ #
+ def bindPerformed(self,client, id, regexp):
+ pass
+
+ ##
+ # invoked when a Ivy Client performs a unbind
+ # @param client: name of the client
+ # @param id: id of the client
+ # @param regexp: regular expression to match
+ #
+ def unbindPerformed(self,client, id, regexp):
+ pass
+
+
+##
+# class IvyMessageAdapter
+# classe abstraite definissant l'interface a fournir à la classe Ivy
+# pour la reception de message
+#
+class IvyMessageAdapter:
+
+ ##
+ # invoked when a message matching regexp is send on the bus
+ # @param client: name of the sender
+ # @param arg: message received
+ #
+ def receive(self, client, *arg):
+ pass
+
+
+##
+# classe gerant les exceptions Ivy
+#
+class IvyException :
+
+ ##
+ # on error send an IvyException
+ #
+ def __call__(self):
+ raise self
+
+ ##
+ # print the message of the exception
+ # @return the message to print
+ #
+ def __str__(self):
+ return self.message
+
+ ##
+ # initialisation method
+ # @param message : the message to print
+ #
+ def __init__(self, message):
+ self.message=message
+
+