diff options
Diffstat (limited to 'clients/ivamPipeConnector.py')
-rw-r--r-- | clients/ivamPipeConnector.py | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/clients/ivamPipeConnector.py b/clients/ivamPipeConnector.py new file mode 100644 index 0000000..af302b8 --- /dev/null +++ b/clients/ivamPipeConnector.py @@ -0,0 +1,247 @@ + +import os, sys, time, select, signal, gzip + +import ivamCore, ivamApi, ivamUtil + +pc = None + +def sigterm(*args): + pc.quit = 1 + +class PipeConnector(ivamApi.Connector): + + BUFSIZE = 128 + + stdin = sys.stdin + stdout = sys.stdout + + playing = False + recording = False + + timeout = 0 + quit = False + + def __init__(self, processor): + + if ivamCore.DEBUG: + ivamCore.log("PipeConnector()") + + global pc + pc = self + signal.signal(signal.SIGTERM, sigterm) + + self.callerNumber = os.getenv("CALLERMSN") + self.ringNumber = os.getenv("RINGMSN") + self.processor = processor + + try: + s = os.fstat(128) + self.pipeHack = True + ivamCore.log("Found and enabled pipe hack.") + except OSError: + self.pipeHack = False + ivamCore.log("Pipe hack not detected.") + + def openDtmf(self): + + try: + fn = os.environ["DTMFFIFO"] + except KeyError: + self.dtmfFifo = None + return + + self.dtmfFifo = file(fn, "rb") + + def playClip(self, fname): + + self.stopPlayback() + + if ivamCore.DEBUG: + ivamCore.log("playClip('%s')" % fname) + + self.playFile = ivamUtil.magicFile(fname, "rb") + self.playName = fname + self.playing = True + self.playBuffer = None + + def stopPlayback(self): + + if ivamCore.DEBUG: + ivamCore.log("stopPlayback()") + + if self.playing: + self.playFile.close() + self.playing = False + + def stopPlayback2(self): + + self.stopPlayback() + self.processor.onClipFinish(self, self.playName) + + def recordClip(self, fname, z = False): + + self.stopRecording() + + if ivamCore.DEBUG: + ivamCore.log("recordClip('%s')" % fname) + + if z: + self.recordFile = gzip.open(fname, "w+b") + else: + self.recordFile = open(fname, "w+b") + + self.recordName = fname + self.recording = True + + def stopRecording(self): + + if ivamCore.DEBUG: + ivamCore.log("stopRecording()") + + if self.recording: + self.recordFile.close() + self.recording = False + + self.processor.onRecordFinish(self, self.recordName) + + def setTimeout(self, t): + + if ivamCore.DEBUG: + ivamCore.log("timeout(%u)" % t) + + if t: + self.timeout = time.time()+t + else: + self.timeout = 0 + + + def run(self): + + if ivamCore.DEBUG: + ivamCore.log("run()") + + self.openDtmf() + self.processor.onConnect(self, self.callerNumber, self.ringNumber) + self.loop() + self.stopPlayback() + self.stopRecording() + self.processor.onHangup(self) + + if not self.dtmfFifo is None: + self.dtmfFifo.close() + + if ivamCore.DEBUG: + ivamCore.log("run() finished") + + def hangup(self): + + if ivamCore.DEBUG: + ivamCore.log("hangup()") + + self.quit = True + + def loop(self): + + while not self.quit: + + t = None + now = time.time() + + if self.timeout: + t = self.timeout - now + + if t < 0: + t = 0 + + o = [] + i = [self.stdin] + + if not self.dtmfFifo is None: + i += [self.dtmfFifo] + + if self.playing: + o += [self.stdout] + + if t is None: + i, o, x = select.select(i, o, []) + else: + i, o, x = select.select(i, o, [], t) + + now = time.time() + + if self.timeout and self.timeout < now: + self.processor.onTimeout(self) + self.timeout = 0 + if self.quit: break + + # Check DTMF fifo + if not self.dtmfFifo is None and self.dtmfFifo in i: + self.handleDtmf() + if self.quit: break + + # Check STDOUT + if self.stdout in o: + self.writeStdout() + if self.quit: break + + # Check STDIN + if self.stdin in i: + self.readStdin() + if self.quit: break + + + def readStdin(self): + + buf = os.read(self.stdin.fileno(), self.BUFSIZE) + + if buf == "": + self.quit = 1 + elif self.recording: + self.recordFile.write(buf) + + + def writeStdout(self): + + if not self.playing: + return + + if self.playBuffer is None: + + self.playBuffer = self.playFile.read(self.BUFSIZE) + + # EOF? + if len(self.playBuffer) == 0: + self.stopPlayback2() + return + + c = os.write(self.stdout.fileno(), self.playBuffer) + self.playBuffer = self.playBuffer[c:] + + if len(self.playBuffer) == 0: + self.playBuffer = None + + def handleDtmf(self): + + if not self.dtmfFifo is None: + + d = self.dtmfFifo.read(1) + + if d == "": + self.dtmfFifo.close() + self.dtmfFifo = None + else: + self.processor.onDtmfEvent(self, d) + + def flushOutput(self): + + if not self.pipeHack: + return + + try: + b = os.read(128, 4096) + if ivamCore.DEBUG: + ivamCore.log("Pipe hack succeeded") + except OSError: + + if ivamCore.DEBUG: + ivamCore.log("Pipe hack failed") |