#!/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)