From 84c303a0c798216c32aac942fb76d74b6bfdaa79 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 6 Jan 2016 14:49:17 +0100 Subject: [PATCH] first commit --- vxml/README | 35 +++++++++++++ vxml/entrouvert.vxml | 116 +++++++++++++++++++++++++++++++++++++++++++ vxml/record.vxml | 9 ++++ vxml/record.wsgi | 37 ++++++++++++++ vxml/scriptvocal.xml | 21 ++++++++ vxml/vxml.wsgi | 66 ++++++++++++++++++++++++ 6 files changed, 284 insertions(+) create mode 100644 vxml/README create mode 100644 vxml/entrouvert.vxml create mode 100644 vxml/record.vxml create mode 100755 vxml/record.wsgi create mode 100644 vxml/scriptvocal.xml create mode 100755 vxml/vxml.wsgi diff --git a/vxml/README b/vxml/README new file mode 100644 index 0000000..467ccb6 --- /dev/null +++ b/vxml/README @@ -0,0 +1,35 @@ +Accueil téléphonique eo +----------------------- + +Il nécessite un serveur vocal acceptant des scripts VXML, comme celui d'OVH. + +Script WSGI +----------- + +Le script vxml.wsgi est basé sur flask et requests, il propose deux vues: + +/play?text= + + synthèse vocale du texte envoyé, les fichiers wav généré sont mis en cache en utilisant le hash SHA1 + du texte comme clé. Ils sont conservé dans le répertoire `sounds` du répertoire courant. + +/vxml/ + + transforme le fichier VXML donné qui doit se trouver dans le chemin courant de lors de l'exécution + du script WSGI, il modifie toutes les balices `voice` pour les faire pointer vers la vue de + synthèse vocale. + +Le script record.wsgi est conçu pour recevoir les fichiers wav généré par les balises `record` du +VXML sur le serveur vocal d'OVH. + +Script VXML +----------- + +entrouvert.vxml + + script VXML principal pour l'accueil téléphonique entrouvert + +record.vxml + + sous script pour la fonctionnalité répondeur, il permet principalement de conserver le + numéro de l'appelant dans le nom du fichier wav généré. diff --git a/vxml/entrouvert.vxml b/vxml/entrouvert.vxml new file mode 100644 index 0000000..52d52e1 --- /dev/null +++ b/vxml/entrouvert.vxml @@ -0,0 +1,116 @@ + + + + + +
+ + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ Au revoir. Durée de l'appel : secondes + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + +
+
+ + + + +
+
diff --git a/vxml/record.vxml b/vxml/record.vxml new file mode 100644 index 0000000..21215fc --- /dev/null +++ b/vxml/record.vxml @@ -0,0 +1,9 @@ + + + + +
+ + +
+
diff --git a/vxml/record.wsgi b/vxml/record.wsgi new file mode 100755 index 0000000..6ca885b --- /dev/null +++ b/vxml/record.wsgi @@ -0,0 +1,37 @@ +import site +import sys +import os + +prev_sys_path = list(sys.path) + +site.addsitedir('/home/bdauvergne/venv/lib/python2.7/site-packages/') +# Reorder sys.path so new directories at the front. +new_sys_path = [] +for item in list(sys.path): + if item not in prev_sys_path: + new_sys_path.append(item) + sys.path.remove(item) +sys.path[:0] = new_sys_path + +from flask import Flask, request, Response, __version__ +from werkzeug.debug import DebuggedApplication +from werkzeug.urls import url_encode + +import os +import hashlib +import requests +import subprocess + +secret = 'secret' + +app = Flask(__name__) +app.debug = True +application = DebuggedApplication(app, evalex=True) # The trick is HERE! Add this extra line! + +@app.route("/", methods=['GET', 'POST']) +def record(): + if request.method == 'POST': + f = request.files['file'] + path = '/tmp/' + f.save(os.path.join(path, f.filename)) + return Response('OK') diff --git a/vxml/scriptvocal.xml b/vxml/scriptvocal.xml new file mode 100644 index 0000000..860bbae --- /dev/null +++ b/vxml/scriptvocal.xml @@ -0,0 +1,21 @@ + + + + +
+ + + Guess what the computer is thinking! Pick a number between 0 and 9. + + + + + + Guess what the computer is thinking now! Pick a number between 0 and 9. + + + You guessed and . + + +
+
diff --git a/vxml/vxml.wsgi b/vxml/vxml.wsgi new file mode 100755 index 0000000..d794b97 --- /dev/null +++ b/vxml/vxml.wsgi @@ -0,0 +1,66 @@ +import site +import sys + +prev_sys_path = list(sys.path) + +site.addsitedir('/home/bdauvergne/venv/lib/python2.7/site-packages/') +# Reorder sys.path so new directories at the front. +new_sys_path = [] +for item in list(sys.path): + if item not in prev_sys_path: + new_sys_path.append(item) + sys.path.remove(item) +sys.path[:0] = new_sys_path + +from flask import Flask, request, Response, __version__ +from werkzeug.debug import DebuggedApplication +from werkzeug.urls import url_encode + +import os +import hashlib +import requests +import subprocess + +secret = 'secret' + +app = Flask(__name__) +app.debug = True +application = DebuggedApplication(app, evalex=True) # The trick is HERE! Add this extra line! + +default_voice = 'Emma' # 'Agnes' # 'Becool' # 'Moussa' # 'Agnes' + +@app.route("/play") +def play(): + text = request.args.get('text') + voice = request.args.get('voice', default_voice) + key_prehash = secret + voice + text + key = hashlib.md5(key_prehash.encode('utf8')).hexdigest() + path = os.path.join('sounds', key+'.wav') + if not os.path.exists(path): + r = requests.get('http://voxygen.fr/sites/all/modules/voxygen_voices/assets/proxy/index.php', + params=dict(method='redirect', text=text, voice=voice)) + p = subprocess.Popen('/usr/bin/sox -t mp3 - -r 8k -c 1 -t wav -'.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate(input=r.content) + with file(path, 'w') as f: + f.write(out) + return Response(file(path), mimetype="audio/x-wav") + +import xml.etree.ElementTree as ET + +@app.route("/vxml/", methods=['GET', 'POST']) +def vxml(path, voice=default_voice): + tree = ET.parse(path) + root = tree.getroot() + if request.form: + for node in root.iter(): + for key in node.attrib: + node.attrib[key] = node.attrib[key].format(**request.form) + for audio in root.findall('.//{http://www.w3.org/2001/vxml}audio'): + play_voice = voice + if 'voice' in audio.attrib: + play_voice = audio.attrib['voice'] + del audio.attrib['voice'] + q = dict(voice=play_voice, text=audio.text) + url = '/~bdauvergne/vxml.wsgi/play?%s' % url_encode(q) + audio.attrib['src'] = url + return Response(ET.tostring(root), mimetype='application/xml')