summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-01-09 14:02:55 +0000
committerLennart Poettering <lennart@poettering.net>2004-01-09 14:02:55 +0000
commitd5168da28d6574d106f50fdb69bdbb9fe73596b5 (patch)
tree900d38646f2629042a7a6138dba5a2300fa34839
parent8ceda18de1ba57c10af74043d0e3c33fecd4767a (diff)
some more python work
git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@22 dbf6933d-3bce-0310-9bcc-ed052ba35b35
-rwxr-xr-xclients/ivam-autobox24
-rwxr-xr-xclients/ivam-voicebox11
-rw-r--r--clients/ivamDefs.py4
-rw-r--r--clients/ivamPipeConnector.py14
-rw-r--r--clients/ivamVoiceBox.py60
-rwxr-xr-xclients/newmessage2
-rwxr-xr-xclients/newvoicebox58
-rw-r--r--conf/msntab2
-rw-r--r--doc/README.VoiceBox84
-rw-r--r--doc/TODO2
10 files changed, 229 insertions, 32 deletions
diff --git a/clients/ivam-autobox b/clients/ivam-autobox
index 8b11f8e..4b043d2 100755
--- a/clients/ivam-autobox
+++ b/clients/ivam-autobox
@@ -7,18 +7,20 @@ import ivamCore, ivamVoiceBox
from optparse import OptionParser
def usage():
- log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--default-record-time=SECS] [--default-pin=PIN] [--default-pin-file=PINFILE] [--debug] [DIRECTORY]" % sys.argv[0])
+ log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--default-record-time=SECS] [--default-pin=PIN] [--default-pin-file=PINFILE] [--record-only] [--no-record] [--debug] [--notify-script=PATH] [--email=EMAIL] [DIRECTORY]" % sys.argv[0])
def parseArgs(vb, argv):
try:
- opts, args = getopt.getopt(argv[1:], "dh", ["help", "record-time=", "pin=", "pin-file=", "default-record-time=", "default-pin=", "default-pin-file=", "debug"])
+ opts, args = getopt.getopt(argv[1:], "dh", ["help", "record-time=", "pin=", "pin-file=", "default-record-time=", "default-pin=", "default-pin-file=", "debug", "record-only", "no-record", "email=", "notify-script="])
except getopt.GetoptError:
usage()
sys.exit(1)
recordTime = 60
pin = "-"
+ email = "root"
+ notifyScript = "newvoicebox"
for o, a in opts:
if o in ("-d", "--debug"):
@@ -37,13 +39,24 @@ def parseArgs(vb, argv):
elif o in ("--default-pin-file"):
pin = getContents(a)
+ elif o in ("--notify-script"):
+ notifyScript = a
+
+ elif o in ("--email"):
+ email = a
+
dname = "msn-" + os.getenv("RINGMSN")
if len(args):
dname = args[0] + "/" + dname
try:
- ivamVoiceBox.setupVoiceBox(dname, pin, recordTime)
+ dname = ivamVoiceBox.setupVoiceBox(dname, pin, recordTime)
+
+ ivamCore.log("Created new voice box, calling notification script. ('%s %s %s')" % (notifyScript, dname, email))
+ r=os.spawnvp(os.P_WAIT, notifyScript, (notifyScript, dname, email))
+ ivamCore.log("Program finished (return value is %i)." % r)
+
except OSError:
pass
@@ -59,6 +72,11 @@ def parseArgs(vb, argv):
elif o in ("--pin-file"):
vb.setPin(getContents(a))
+ elif o in ("--record-only"):
+ vb.recordOnly = True
+
+ elif o in ("--no-record"):
+ vb.noRecord = True
def main():
vb = ivamVoiceBox.VoiceBox()
diff --git a/clients/ivam-voicebox b/clients/ivam-voicebox
index 1ec19d5..be2c2eb 100755
--- a/clients/ivam-voicebox
+++ b/clients/ivam-voicebox
@@ -6,12 +6,12 @@ from ivamCore import log
import ivamCore, ivamVoiceBox
def usage():
- log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--message-program=BINARY] [--debug] DIRECTORY" % sys.argv[0])
+ log("%s [--record-time=SECS] [--pin=PIN] [--pin-file=PINFILE] [--message-program=BINARY] [--debug] [--record-only] [--no-record] DIRECTORY" % sys.argv[0])
def parseArgs(vb, argv):
try:
- opts, args = getopt.getopt(argv[1:], "hd", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program="])
+ opts, args = getopt.getopt(argv[1:], "hd", ["help", "record-time=", "pin=", "pin-file=", "debug", "message-program=", "record-only", "no-record"])
except getopt.GetoptError:
usage()
sys.exit(1)
@@ -44,6 +44,13 @@ def parseArgs(vb, argv):
elif o in ("--message-program"):
vb.messageProgram = a
+ elif o in ("--record-only"):
+ vb.recordOnly = True
+
+ elif o in ("--no-record"):
+ vb.noRecord = True
+
+
def main():
vb = ivamVoiceBox.VoiceBox()
parseArgs(vb, sys.argv)
diff --git a/clients/ivamDefs.py b/clients/ivamDefs.py
index 0804e45..c161467 100644
--- a/clients/ivamDefs.py
+++ b/clients/ivamDefs.py
@@ -1,3 +1,5 @@
spoolDirectory = "/home/lennart/tmp/ivam-spool"
-shareDirectory = "/home/lennart/projects/ivam-reloaded/ulaw"
+ulawDirectory = "/home/lennart/projects/ivam-reloaded/ulaw"
+shareDirectory = "/home/lennart/projects/ivam-reloaded/doc"
+binDirectory = "/home/lennart/projects/ivam-reloaded/clients"
diff --git a/clients/ivamPipeConnector.py b/clients/ivamPipeConnector.py
index bbaf9ed..91445ba 100644
--- a/clients/ivamPipeConnector.py
+++ b/clients/ivamPipeConnector.py
@@ -20,6 +20,7 @@ class PipeConnector(ivamApi.Connector):
timeout = 0
quit = False
+ umask = 0007
def __init__(self, processor):
@@ -85,10 +86,15 @@ class PipeConnector(ivamApi.Connector):
if ivamCore.DEBUG:
ivamCore.log("recordClip('%s')" % fname)
- if z:
- self.recordFile = gzip.open(fname, "w+b")
- else:
- self.recordFile = open(fname, "w+b")
+ u = os.umask(self.umask)
+
+ try:
+ if z:
+ self.recordFile = gzip.open(fname, "w+b")
+ else:
+ self.recordFile = open(fname, "w+b")
+ finally:
+ os.umask(u)
self.recordName = fname
self.recording = True
diff --git a/clients/ivamVoiceBox.py b/clients/ivamVoiceBox.py
index 9dc84f9..b05de03 100644
--- a/clients/ivamVoiceBox.py
+++ b/clients/ivamVoiceBox.py
@@ -13,6 +13,8 @@ class VoiceBox(ivamApi.Processor):
# State
currentState = STATE_INVALID
fileSuffix = ".ulaw.gz"
+ recordOnly = False
+ noRecord = False
def getClip(self, s):
return "%s/%s%s" % (self.directory, s, self.fileSuffix)
@@ -25,8 +27,11 @@ class VoiceBox(ivamApi.Processor):
self.callerNumber = callerNumber
self.ringNumber = ringNumber
- self.currentState = self.STATE_WELCOME
- c.playClip(self.getClip("welcome"))
+ if self.noRecord:
+ self.authNow(c)
+ else:
+ self.currentState = self.STATE_WELCOME
+ c.playClip(self.getClip("welcome"))
def loginComplete(self, c):
self.messages = self.getMessageNames()
@@ -41,6 +46,14 @@ class VoiceBox(ivamApi.Processor):
self.currentState = self.STATE_MESSAGE_BEEP
c.playClip(self.getClip("beep"))
+
+ def authNow(self, c):
+ self.currentState = self.STATE_AUTH
+ self.inputPin = ""
+ c.stopPlayback()
+ c.playClip(self.getClip("auth"))
+ c.setTimeout(self.AUTH_TIMEOUT)
+
def onClipFinish(self, c, fname):
if ivamCore.DEBUG:
@@ -121,7 +134,7 @@ class VoiceBox(ivamApi.Processor):
if ivamCore.DEBUG:
ivamCore.log("onDtmfEvent(%c)" % event)
- if ((self.currentState == self.STATE_WELCOME) or (self.currentState == self.STATE_WELCOME_BEEP)) and (event == '0'):
+ if ((self.currentState == self.STATE_WELCOME) or (self.currentState == self.STATE_WELCOME_BEEP)) and (event == '0') and not self.recordOnly:
if self.pin == "":
self.loginComplete(c)
@@ -131,11 +144,7 @@ class VoiceBox(ivamApi.Processor):
c.hangup()
else:
- self.currentState = self.STATE_AUTH
- self.inputPin = ""
- c.stopPlayback()
- c.playClip(self.getClip("auth"))
- c.setTimeout(self.AUTH_TIMEOUT)
+ self.authNow(c)
elif self.currentState == self.STATE_AUTH:
c.stopPlayback()
@@ -227,7 +236,7 @@ class VoiceBox(ivamApi.Processor):
os.environ["LENGTH"] = `c.recordLength`
os.environ["SEC_LENGTH"] = "%0.1f" % (c.recordLength/8000.0)
- ivamCore.log("Starting new message notification program.")
+ ivamCore.log("Starting new message notification program ('%s %s')." % (self.messageProgram, fname))
r=os.spawnvp(os.P_WAIT, self.messageProgram, (self.messageProgram, fname))
ivamCore.log("Program finished (return value is %i)." % r)
@@ -276,19 +285,30 @@ class VoiceBox(ivamApi.Processor):
-def setupVoiceBox(dname, pin = "-", recordTime = 60, email = "root"):
- if dname.find("/") == -1:
- dname = "%s/%s" % (ivamDefs.spoolDirectory, dname)
+def setupVoiceBox(dname, pin = "-", recordTime = 60, email = "root", umask = 0007):
+
+ u = os.umask(umask)
+ try:
+
+ if dname.find("/") == -1:
+ dname = "%s/%s" % (ivamDefs.spoolDirectory, dname)
- os.mkdir(dname, 0770)
- os.mkdir("%s/messages" % dname, 0770)
+ os.mkdir(dname, 0777)
+ os.mkdir("%s/messages" % dname, 0777)
- setContents("%s/PIN" % dname, pin)
- setContents("%s/RECORD_TIME" % dname, `recordTime`)
- setContents("%s/EMAIL" % dname, email)
+ setContents("%s/PIN" % dname, pin)
+ setContents("%s/RECORD_TIME" % dname, `recordTime`)
+ setContents("%s/EMAIL" % dname, email)
+
+ ulaw = map(lambda e: e+".ulaw.gz", ('welcome', 'beep', 'empty', 'nomoremessages', 'auth', 'authok', 'removed'))
- ulaw = map(lambda e: e+".ulaw.gz", ('welcome', 'beep', 'empty', 'nomoremessages', 'auth', 'authok', 'removed'))
+ for f in ulaw:
+ os.symlink("%s/%s" % (ivamDefs.ulawDirectory, f), "%s/%s" % (dname, f))
- for f in ulaw + ['newmessage', 'README']:
- os.symlink("%s/%s" % (ivamDefs.shareDirectory, f), "%s/%s" % (dname, f))
+ os.symlink("%s/%s" % (ivamDefs.binDirectory, "ivam-newmessage"), "%s/%s" % (dname, "newmessage"))
+ os.symlink("%s/%s" % (ivamDefs.shareDirectory, "README.VoiceBox"), "%s/%s" % (dname, "README"))
+
+ return dname
+ finally:
+ os.umask(u)
diff --git a/clients/newmessage b/clients/newmessage
index afc56c5..b5101a5 100755
--- a/clients/newmessage
+++ b/clients/newmessage
@@ -55,7 +55,7 @@ For listening to the recorded message please dial $RINGMSN. During
the welcome message press 0 followed by your PIN. Then you will listen
to the last recorded message.
- Best regards, your voicebox.
+ Best regards, your voice box system
--$BOUND
Content-Type: application/ogg; charset=unknown-8bit
diff --git a/clients/newvoicebox b/clients/newvoicebox
new file mode 100755
index 0000000..0f6ccde
--- /dev/null
+++ b/clients/newvoicebox
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# $Id$
+#
+# This file is part of ivam.
+#
+# asd is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# asd 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 General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with ivam; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+
+if [ ! -d "$1" ] ; then
+ echo "New spool directory not found or not readable." > /dev/stderr
+ exit 1
+fi
+
+EMAIL=root
+[ "x$2" != "x" ] && EMAIL="$2"
+
+DATE=$(date)
+
+(
+ BOUND="$$-`date +%s`-ivam"
+
+ cat <<EOF
+To: $EMAIL
+Subject: New voice box created for $RINGMSN
+Mime-Version: 1.0
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+
+A new voice box has been created:
+
+ Caller number: $CALLERMSN
+ Local number: $RINGMSN
+Spool directory: $1
+ Date: $DATE
+
+Don't forget to configure this new voice box by adjusting the files
+in the spool directory. For more information see the README file
+you find in there.
+
+ Best regards, your voice box system
+
+EOF
+
+) | /usr/sbin/sendmail -oi -t
+
diff --git a/conf/msntab b/conf/msntab
index 02391ae..251e906 100644
--- a/conf/msntab
+++ b/conf/msntab
@@ -1,6 +1,6 @@
# local MSN remote MSN options action
-41264179 * rings=0,pipehack ivam-autobox
+41264179 * rings=0,pipehack ivam-autobox
#41264179 41264177 rings=0 ivam-dialup --pin=4711 ppp0
#* 41264179 rings=0 @hangup
diff --git a/doc/README.VoiceBox b/doc/README.VoiceBox
new file mode 100644
index 0000000..885742a
--- /dev/null
+++ b/doc/README.VoiceBox
@@ -0,0 +1,84 @@
+In the voice box spool directory the following files may be used to
+adjust configuration options:
+
+./RECORD_TIME
+
+ Specify the time in seconds when message recording is stopped.
+
+ Defaults to "60".
+
+./PIN
+
+ Specify the PIN for the voice box when queried over the phone
+ line. This should be a string capable of being entered via DTMF
+ tones, thus consisting of 0-9, *, # only. The length is up to you.
+
+ Two special PINs may be set: an empty string disables all
+ authentication, "-" will deny all authentication attempts.
+
+ Defaults to "-".
+
+./newmessage
+
+ This should be a link pointing to a script which is called
+ whenever a new message is recorded. It is run with a single
+ argument: the filename of the recorded message. Special
+ environment variables are passed:
+
+ RINGMSN
+
+ The local number of the voice box
+
+ CALLERMSN
+
+ The remote number the message originates from
+
+ LENGTH
+
+ The length in bytes of the uncompressed voice
+ message. Since the sampling rate of the ISDN
+ is fixed to 8000Hz divide this value by 8000
+ to get the length in seconds.
+
+ SEC_LENGTH
+
+ The length in seconds of the voice message
+ written as fixed point number. This is the
+ same as LENGTH/8000.
+
+ SPOOLDIR
+
+ The spool directory where the configuration of
+ the voice box resides.
+
+./EMAIL
+
+ Specify the email address of the owner of this voice box. This
+ address ist notified whenever a new message is recorded. It is
+ interpreted by the default newmessage script. If you change
+ that script this file may become useless.
+
+ Defaults to "root".
+
+./*.ulaw.gz
+
+ These are audio files which are used by the voice box
+ automaton. You may replace them with your on recordings.
+
+ ./welcome.ulaw.gz -- The welcome message
+ ./authok.ulaw.gz -- "Authentication successful"
+ ./beep.ulaw.gz -- A beep
+ ./nomoremessages.ulaw.gz -- "No more messages available"
+ ./auth.ulaw.gz -- "Please authenticate"
+ ./empty.ulaw.gz -- "The voice box is empty"
+ ./removed.ulaw.gz -- "Message deleted successfully"
+
+./messages/
+
+ This is not a configuration item but where the recorded
+ messages are stored. You are free to delete any message from
+ the voice box by issuing standard Unix commands like 'rm'
+ inside this directory. The file names inside the directory
+ include the Unix time, the local number and the originating
+ number seperated by colons.
+
diff --git a/doc/TODO b/doc/TODO
index 78fc329..97e6c8f 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -6,7 +6,9 @@
* @same support
* uid switching for each client
* init script
+* mail on successful mailbox creation in ivam-autobox
+* --no-record --record-only (for voicebox) (DONE)
* make it a daemon (DONE)
* newmessage script (DONE)
* python part (DONE)