|
@@ -1,24 +1,25 @@
|
|
|
#!/usr/bin/env python2
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
+import ConfigParser
|
|
|
import audioop
|
|
|
import contextlib
|
|
|
import glob
|
|
|
import io
|
|
|
import os
|
|
|
+import signal
|
|
|
import string
|
|
|
import subprocess
|
|
|
+import sys
|
|
|
import syslog
|
|
|
+import tempfile
|
|
|
import threading
|
|
|
import urllib2
|
|
|
import wave
|
|
|
from datetime import datetime
|
|
|
-import tempfile
|
|
|
|
|
|
import linphone
|
|
|
from enum import Enum
|
|
|
-import signal
|
|
|
-import sys
|
|
|
|
|
|
VOLUME_THRESHOLD = 100
|
|
|
|
|
@@ -29,7 +30,7 @@ def slugify(s):
|
|
|
and converts spaces to hyphens, wich is url/filename friendly.
|
|
|
"""
|
|
|
valid_chars = "-_.() %s%s" % (string.ascii_letters, string.digits)
|
|
|
- filename = ''.join(c for c in s if c in valid_chars)
|
|
|
+ filename = ''.join(cc for cc in s if cc in valid_chars)
|
|
|
filename = filename.replace(' ', '_') # I don't like spaces in filenames.
|
|
|
return filename
|
|
|
|
|
@@ -70,7 +71,6 @@ SHOULDIANSWER_LOOKUP_URL = "https://ch.shouldianswer.net/telefonnummer/{$number$
|
|
|
|
|
|
|
|
|
def is_in_blacklists(a_number):
|
|
|
-
|
|
|
the_number = a_number.lstrip("0")
|
|
|
the_number = the_number.replace("+", "")
|
|
|
|
|
@@ -181,7 +181,6 @@ class SipConnection(object):
|
|
|
|
|
|
if len(buf) >= 20000:
|
|
|
volume = audioop.rms(buf, 2)
|
|
|
- print("Detected volume : " + str(volume))
|
|
|
# print("State : " + str(conversation.status))
|
|
|
buf = ''
|
|
|
if volume < self._volume_threshold:
|
|
@@ -202,7 +201,7 @@ class SipConnection(object):
|
|
|
if state == linphone.CallState.Released:
|
|
|
# Let's convert wav to mp3
|
|
|
if call.current_params.record_file is not None and os.path.isfile(call.current_params.record_file):
|
|
|
- log("Converting output from wav to mp3")
|
|
|
+ log("Saving to mp3 : " + call.current_params.record_file)
|
|
|
subprocess.call('lame --quiet --preset insane %s' % call.current_params.record_file, shell=True)
|
|
|
os.remove(call.current_params.record_file)
|
|
|
|
|
@@ -216,7 +215,7 @@ class SipConnection(object):
|
|
|
|
|
|
call_params = core.create_call_params(call)
|
|
|
a_file = current_dir + "/out/call_from_" + slugify(call.remote_address.username) + \
|
|
|
- "_" + datetime.now().strftime(
|
|
|
+ "_" + datetime.now().strftime(
|
|
|
'%Y-%m-%d_%Hh%Mmn%Ss') + ".wav"
|
|
|
|
|
|
log(a_file)
|
|
@@ -240,11 +239,11 @@ class SipConnection(object):
|
|
|
return self
|
|
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
|
- log("Cleaning on exit ...")
|
|
|
+ log(str(self) + ": cleaning on exit ...")
|
|
|
os.unlink(self._incoming_stream_file)
|
|
|
|
|
|
def start(self):
|
|
|
- print("starting")
|
|
|
+ log("starting " + str(self))
|
|
|
self._core.use_files = True
|
|
|
self._core.record_file = self._incoming_stream_file
|
|
|
|
|
@@ -264,9 +263,11 @@ class SipConnection(object):
|
|
|
self._is_quitting = True
|
|
|
self.__exit__(None, None, None)
|
|
|
|
|
|
+ def __str__(self):
|
|
|
+ return self._username + "@" + self._domain
|
|
|
+
|
|
|
def __init__(self, domain, username, password):
|
|
|
|
|
|
- print("init")
|
|
|
callbacks = {
|
|
|
'call_state_changed': self.call_state_changed
|
|
|
}
|
|
@@ -285,29 +286,32 @@ class SipConnection(object):
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
- connections = []
|
|
|
-
|
|
|
- def signal_handler(signal, frame):
|
|
|
- print('External stop request!')
|
|
|
- for conn in connections:
|
|
|
- conn.request_quit()
|
|
|
-
|
|
|
+ cfg = ConfigParser.SafeConfigParser()
|
|
|
|
|
|
- conn1 = SipConnection("192.168.1.1", "621", "toto")
|
|
|
- connections.append(conn1)
|
|
|
- threading.Thread(target=conn1.start).start()
|
|
|
+ cfg_path = current_dir + "/config.ini"
|
|
|
|
|
|
- signal.signal(signal.SIGINT, signal_handler)
|
|
|
- signal.signal(signal.SIGTERM, signal_handler)
|
|
|
- signal.pause()
|
|
|
+ if len(sys.argv) == 2:
|
|
|
+ cfg_path = sys.argv[1]
|
|
|
|
|
|
+ connections = []
|
|
|
|
|
|
+ cfg.read(cfg_path)
|
|
|
|
|
|
+ for c in cfg.sections():
|
|
|
+ connections.append(SipConnection(cfg.get(c, "domain"), cfg.get(c, "username"), cfg.get(c, "password")))
|
|
|
|
|
|
+ for sip_c in connections:
|
|
|
+ threading.Thread(target=sip_c.start).start()
|
|
|
|
|
|
+ # Ensuring clean quit and ressource releasing
|
|
|
+ # when receiving ctrl-c from console or SIGTERM
|
|
|
+ # from daemon manager.
|
|
|
|
|
|
+ def signal_handler(sig, frame):
|
|
|
+ print('External stop request!')
|
|
|
+ for conn in connections:
|
|
|
+ conn.request_quit()
|
|
|
|
|
|
-# TODO : créer un fichier de config
|
|
|
-# TODO : pouvoir s'enregistrer sur plusieurs comptes SIP
|
|
|
-# TODO : De pouvoir utiliser des mp3 pour gagner de la place, qu'on convertit au vol en wav, puis qu'on efface.
|
|
|
-# TODO : Ecrire le readme
|
|
|
+ signal.signal(signal.SIGINT, signal_handler)
|
|
|
+ signal.signal(signal.SIGTERM, signal_handler)
|
|
|
+ signal.pause()
|