Commit 869e514b authored by okhin's avatar okhin 🚴

Fixing some small bugs

parent a5151972
Pipeline #110 passed with stage
in 2 seconds
......@@ -89,7 +89,7 @@ class Channel(object):
'''
def __init__(self, config, name):
self.config = config
self.channel = name
self.name = name
def status(self):
'''
......
......@@ -75,7 +75,7 @@ class PiphoneJSONEncoder(json.JSONEncoder):
return { 'caller': obj.caller
, 'callee': obj.callee
, 'callid': obj.id
, 'url': obj.url()
, 'url': obj.url
, 'history': obj.history
, 'owner': obj.owner }
else:
......@@ -114,6 +114,7 @@ def authenticated(f):
bottle_logger.exception(e)
abort(403, e)
except Exception as e:
bottle_logger.exception(e)
abort(500, e)
return f(db, *args, **kwargs)
return wrapped
......@@ -166,7 +167,7 @@ def hold_bridge():
raise e
@asyncio.coroutine
def listen():
def listen(db):
'''
Start listening on the websocket
'''
......@@ -181,7 +182,7 @@ def listen():
try:
event = yield from ws.recv()
# Let's call the applications function
yield from dispatch(json.loads(event))
yield from dispatch(json.loads(event), db)
except websockets.exceptions.ConnectionClosed as e:
ws_logger.warning("Connexion closed")
ws_logger.exception(e)
......@@ -194,7 +195,7 @@ def listen():
ws.close()
@asyncio.coroutine
def dispatch(self, event):
def dispatch(event, db):
"""
Let's work on our events. Parse them and do request on the ARI API. Event is
a dict loaded from JSON.
......@@ -204,7 +205,7 @@ def dispatch(self, event):
if 'channel' not in event:
return
call_id = re.sub('-\d+$', '', event['channel']['id'])
call = Call.load(call_id, self.db)
call = Call.load(call_id, db)
call.event_handler(event)
class Call(object):
......@@ -224,31 +225,32 @@ class Call(object):
self.owner = owner
if callid == None:
self.id = str(uuid.uuid4())
self.db = db
self.event_handler({'type': 'Created', 'timestamp': datetime.datetime.now().isoformat(), 'channel': {'id': 'Init'}})
else:
self.id = callid
self.db = db
self.event_handler({'type': 'Created', 'timestamp': datetime.datetime.now().isoformat(), 'channel': {'id': 'Init'}})
except Exception as e:
phone_logger.exception(e)
raise e
@property
def url(self):
return ''.join(['/calls/', self.id])
@property
def state(self):
sort = sorted(self.history, reverse=True, key=itemgetter(1))
return sort[0][0]
@classmethod
def load(cls, callid, db):
phone_logger.debug("Loading call {}".format(callid,))
phone_logger.debug("Loading call {} from db {}".format(callid, db,))
try:
results = db.execute('SELECT caller, callee, owner, callid, history FROM calls WHERE callid = ?;', (callid,))
result = results.fetchone()
assert len(result) == 5
object = cls(result[0], result[1], result[2], result[3])
object = cls(result[0], result[1], result[2], result[3], db=db)
object.history = json.loads(result[4])
object.db = db
return object
except Exception as e:
phone_logger.exception(e)
......@@ -267,6 +269,13 @@ class Call(object):
There's a new event related to our call
'''
state = event['type']
try:
if self.state.startswith(state):
# We're alreaydy in this state, we just need to noop
return
except IndexError:
if state in self.actions:
getattr(self, self.actions[state])(event=event)
if state in self.actions:
getattr(self, self.actions[state])(event=event)
......@@ -298,7 +307,7 @@ class Call(object):
We received a DTMF sequence
'''
try:
assert self.state().startswith('Up')
assert self.state.startswith('Up')
# The only thing we want to do is to call the callee if we press 1
if event['digit'] != '1':
return
......@@ -318,12 +327,13 @@ class Call(object):
channel = ari.Channel(config['asterisk'], self.id + '-' + sanitize_phonenumber(self.callee))
channel.originate(endpoint)
except AssertionError as e:
phone_logger.error("Received a DTMF sequence out le being in a '{}' state, ignoring: {}".format(self.state(), event['digit']))
phone_logger.error("Received a DTMF sequence out le being in a '{}' state, ignoring: {}".format(self.state, event['digit']))
def change(self, event):
'''
Let's change the state of the call
'''
# First we need to check if it's really a change ie, if the new state is not the previous one
self.update((':'.join([event['channel']['state'], event['channel']['id'].split('-')[-1]]), event['timestamp'],))
phone_logger.info("New state for call {}: {}".format(event['channel']['id'], event['channel']['state']))
# We now need to take action according to our new state
......@@ -371,7 +381,7 @@ class Call(object):
try:
endpoint = 'SIP/' + sanitize_phonenumber(self.caller) + '@' + config['asterisk']['sip-context']
channel = ari.Channel(config['asterisk'], self.id + '-' + sanitize_phonenumber(self.caller))
channel.originate()
channel.originate(endpoint)
except Exception as e:
phone_logger.exception(e)
raise e
......@@ -387,14 +397,15 @@ class Call(object):
, (self.caller, self.callee, self.owner, self.id, json.dumps(self.history)))
self.db.commit()
except Exception as e:
bottle_logger.exception(e)
phone_logger.exception(e)
raise e
def start():
def start(db):
global running
running = True
threads.submit(app.run, server='paste')
loop.run_until_complete(listen())
loop.run_until_complete(listen(db))
def stop():
global running
......@@ -435,7 +446,7 @@ def calls(db, callid=None):
bottle_logger.debug("Found {} results: {}".format(len(rows), rows))
assert len(rows) == 1
call = Call.load(callid, db)
head = {'call': call.url(), 'user': request.params['api'], 'hits': 1}
head = {'call': call.url, 'user': request.params['api'], 'hits': 1}
return {'head': head, 'data': call}
except AssertionError as e:
bottle_logger.debug("Not exactly one results found, this is an issue")
......@@ -454,11 +465,12 @@ def originate(db, callid=None):
bottle_logger.debug("POST {}".format(request.fullpath))
try:
if callid is not None:
call = Call(request.params['caller'], request.params['callee'], request.params['api'], callid=request.params['callid'], db=db)
call = Call(request.params['caller'], request.params['callee'], request.params['api'], callid=callid, db=db)
else:
call = Call(request.params['caller'], request.params['callee'], request.params['api'], db=db)
bottle_logger.debug("Originate a call: {}".format(json.dumps(call, cls=PiphoneJSONEncoder)))
head = {'call': call.url()
call.save()
head = {'call': call.url
, 'user': request.params['api']
, 'hits': 1}
return {'header': head, 'data': call}
......@@ -471,6 +483,6 @@ if __name__ == '__main__':
db = sqlite3.connect(config['piphone']['db'])
phone_logger.info("Starting the piphone SIP backend")
try:
start()
start(db)
except (KeyboardInterrupt, SystemExit):
stop()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment