#!/usr/bin/python
############################################################################
# FILE: ttsDaemon
# DESCRIPTION: Daemon which handles text to speech messages. Runs on port
# 2222.
# AUTHOR: Marc Spoorendonk
# DATE: 2002-07-04 00:44:13 CET
# CHANGES:
# yyyy-mm-dd
############################################################################
import sys
# also search for imported files in parent dir
sys.path.append('..')
sys.path.append('../lib')
from stat import * # constants for array indices
import os # for system
import time # for sleep
import socket # For gethostbyaddr()
import mimetools
import SocketServer
from xml.dom import minidom # for parsing xml tags
import thread
import Queue
false=0
true=1
class TtsDaemon(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
allow_reuse_address = 1 # Seems to make sense in testing environment
handlerArray = {}
speechQueue=Queue.Queue()
def __init__(self, eventd=None):
self.name="TtsDaemon"
server_address = ('', 2222)
SocketServer.TCPServer.__init__(self, server_address, TTSRequestHandler)
sa = self.socket.getsockname()
print "Serving TTS on " + sa[0] + " port %d." % sa[1]
self.files={}
print "TextToSpeech daemon started"
thread.start_new_thread(self.processQueue, ());
# serve_forever() contains a while(true) and thus should run in its own thread
self.serve_forever()
#thread.start_new_thread(self.serve_forever, ());
def server_bind(self):
"""Overload server_bind to store the server name."""
SocketServer.TCPServer.server_bind(self)
host, port = self.socket.getsockname()
self.server_name = socket.getfqdn(host)
self.server_port = port
def getHandler(self, login):
#loop through all handlers and return the correct one
for handler in self.handlerArray.keys():
if handler.login == login:
return handler
def registerClient(self, handlerObject):
self.handlerArray[handlerObject]=1
print "registering client; handlerCount: %d" % len(self.handlerArray)
def unRegisterClient(self, handlerObject):
del self.handlerArray[handlerObject]
print "unregistering client; handlerCount: %d" % len(self.handlerArray)
def processQueue(self):
while 1:
if not self.speechQueue.empty():
entry=self.speechQueue.get()
print 'say in ' + entry['language'] + ': ' + entry['text']
os.system('~marc/project/tts/sayText "'+ entry['text'] + '" ' + entry['language'])
else:
time.sleep(.1)
def addSpeechEntry(self, entry):
if not entry.has_key('priority'):
entry['priority']=10
if not entry.has_key('language'):
entry['language']='en'
print entry
self.speechQueue.put(entry)
class TTSRequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
self.server.registerClient(self)
self.sendHello()
while 1:
self.raw_requestline = self.rfile.readline()
if not self.raw_requestline:
break;
if not self.parse_request(): # An error code has been sent, just exit
break
self.server.unRegisterClient(self)
def parse_request(self):
"""Parse a request (internal).
Return value is 1 for success, 0 for failure; on failure, an
error is sent back.
"""
requestline = self.raw_requestline
if requestline[-1:] == '\n':
requestline = requestline[:-1]
if requestline[-1:] == '\r':
requestline = requestline[:-1]
self.requestline = requestline
print "request line: "+self.requestline
#print "closed: %d" % self.rfile.closed
if self.requestline == "":
return 1;
try:
dom = minidom.parseString(self.requestline)
self.command = dom.childNodes[0]
except:
print "ERROR: Malformed XML input: "+self.requestline
self.send('')
else:
return self.executeCommand()
return 1
def executeCommand(self):
tagName=self.command.tagName
cmdFunc=getattr(self, "cmd"+tagName.capitalize()) # call command method
retVal=cmdFunc()
return retVal
def send(self, str):
self.wfile.write(str+"\r\n")
#====================== issued by daemon; sent to client on socket =============================
def sendHello(self):
self.send('')
#================ commands issued by client connected to socket =====================
def cmdComment(self):
print "comment"
return 1
def cmdLogin(self):
self.login=self.command.attributes["login"].value
print "Client is now known as " + self.login
return 1
def cmdQuit(self):
print "Quitting"
return 0
def cmdSaytext(self):
if(self.command.getAttribute('text')):
text=self.command.attributes["text"].value
entry={ 'text': text }
if(self.command.getAttribute('language')): # language is optional so we check first
entry['language']=self.command.attributes['language'].value
if(self.command.getAttribute('priority')): # priority is optional so we check first
entry['priority']=self.command.attributes['priority'].value
self.server.addSpeechEntry(entry);
self.send('');
else:
self.cmdHelp()
return 1
def cmdHelp(self):
self.send("""
broadcast a text: <saytext text="This is a test" language="en"/>
quit: <quit/>
""");
return 1
def cmdTest(self):
return 1
if __name__ == '__main__': # for testing
ttsDaemon=TtsDaemon()
print "tts daemon started"
while 1: # loop forever
time.sleep(.1)