#!/usr/bin/env python
#*******************************************************************************
# ALMA - Atacama Large Millimiter Array
# (c) Associated Universities Inc., 2005
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# "@(#) $Id: EventRecorder.py,v 1.1 2010/10/01 17:20:48 javarias Exp $"
#
# who when what
# -------- ---------- ----------------------------------------------
# rhiriart 2008-01-14 created
#
from Acspy.Nc.Consumer import Consumer
from Acspy.Nc.Supplier import Supplier
from xml.dom.minidom import parseString
import sys, time, pickle
class EventRecorder(Consumer):
def __init__(self, channel_name):
'''
Constructor.
Parameters:
channel_name Channel name.
'''
Consumer.__init__(self, channel_name, None)
self.channel_name = channel_name
self.rec_file_name = self.channel_name + '.xml'
self.rec_file = None
self.start_time = -1
def begin(self):
'''
Begin the event recording session.
'''
self.start_time = time.time()
self.rec_file = open(self.rec_file_name, 'w')
self.rec_file.write('\n')
self.rec_file.write('\n')
self.rec_file.flush()
self.consumerReady()
def end(self):
'''
End the event recording session.
'''
self.disconnect()
if self.rec_file:
self.rec_file.write('\n')
self.rec_file.close()
def replaceXMLEntities(self, s):
'''
Replaces special characters of its corresponding XML entities.
& -> &
' -> '
< -> <
> -> >
" -> "
'''
return s.replace('&', '&').replace('\'', ''').replace('<', '<').replace('>', '>').replace('"', '"')
def processEvent(self, type_name=None, event_name=None, corba_any=None, se=None):
'''
This method gets called when an event is received.
It is overriding Consumer.processEvent().
'''
t = time.time() - self.start_time
s = ' '
print 'CORBA Any Value: ' + str(corba_any.value())
print 'CORBA Any Value dir: ' + str(dir(corba_any.value()))
s += self.replaceXMLEntities(pickle.dumps(self._transformUnknownStruct(corba_any.value())))
# s += self.replaceXMLEntities(pickle.dumps(corba_any.value()))
s += '\n'
if self.rec_file:
self.rec_file.write(s)
def _transformUnknownStruct(self, us):
'''
Transforms the omniORB UnknownStruct (a hidden, internal type that is used to implement
CORBA Anys in OmniORB and that can't be pickled).
This method is recursive, nested UnknownStructs will be converted as well.
Parameters:
us - UnknownStruct instance.
Retuns: The good, 'ol, known structure.
'''
id = us._NP_RepositoryId
if not self._isUnknownStruct(us): return us
members = us._members
values = us._values
kargs = {}
for i in range(len(members)):
arg = values[i]
# if '_NP_RepositoryId' in dir(arg):
if self._isUnknownStruct(arg):
arg = self._transformUnknownStruct(arg)
kargs[members[i]] = arg
modName = id.split(':')[1].split('/')[1]
clsName = id.split(':')[1].split('/')[2]
mod = __import__(modName)
cls = mod.__dict__[clsName]
ks = apply(cls, [], kargs) # "known" struct instance
return ks
def _isUnknownStruct(self, us):
d = dir(us)
print 'We have a', str(us)
print 'With dictionary:', str(d)
r = ('_members' in d) and ('_values' in d) and (str(us)[:13] == 'UnknownStruct')
print 'So it is', str(r)
return r
class Event:
def __init__(self, publisher, name, evst):
self.publisher = publisher
self.name = name
self.evStruct = evst
def getName(self):
return self.name
def getEventStruct(self):
return self.evStruct
def publish(self):
self.publisher.publishEvent(self.evStruct)
class Player:
def __init__(self, file_name):
'''
Constructor.
Parameters:
file_name - The name of a previously recorded event consumer session.
This file should have been created with the EventRecorder
class.
'''
f = open(file_name)
xml_doc = f.read()
root_dom = parseString(xml_doc)
self.events = []
session_dom = root_dom.firstChild
channel_name = session_dom.getAttribute('channel-name')
self.supplier = Supplier(channel_name)
for node in session_dom.childNodes:
if node.nodeName == 'Event':
event_name = node.getAttribute('event-name')
# stringified event structure
ses = self.restoreXMLEntities(str(node.firstChild.nodeValue))
se = pickle.loads(ses) # event structure
self.events.append(Event(self.supplier, str(event_name), se))
def __getitem__(self, i):
'''
Overriden indexing operation.
'''
return self.events[i]
def __len__(self):
'''
Overriden length operation.
'''
return len(self.events)
def restoreXMLEntities(self, s):
'''
Utilitiy function. Replaces XML entities for its respective characters.
& -> &
&apos -> '
< -> <
> -> >
" -> "
'''
return s.replace('"', '"').replace('>', '>').replace('<', '<').replace(''', '\'').replace('&', '&')
if __name__ == "__main__":
recorder = EventRecorder(sys.argv[1])
recorder.begin()
print "Press a key to finish..."
sys.stdin.read(1)
recorder.end()
# __oOo__