summaryrefslogtreecommitdiffstats
path: root/clients/ivamPipeConnector.py
diff options
context:
space:
mode:
Diffstat (limited to 'clients/ivamPipeConnector.py')
-rw-r--r--clients/ivamPipeConnector.py247
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")