Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
La Quadrature du Net
piphone
piphone-sip
Commits
869e514b
Commit
869e514b
authored
Aug 22, 2016
by
okhin
Browse files
Fixing some small bugs
parent
a5151972
Pipeline
#110
passed with stage
in 2 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
ari.py
View file @
869e514b
...
...
@@ -89,7 +89,7 @@ class Channel(object):
'''
def
__init__
(
self
,
config
,
name
):
self
.
config
=
config
self
.
channel
=
name
self
.
name
=
name
def
status
(
self
):
'''
...
...
piphone.py
View file @
869e514b
...
...
@@ -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
()
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment