]>
git.ipfire.org Git - ipfire.org.git/blob - src/backend/talk.py
10 from .misc
import Object
11 from .decorators
import *
13 class Freeswitch(Object
):
17 "host" : self
.settings
.get("freeswitch_database_host"),
18 "database" : self
.settings
.get("freeswitch_database_name", "freeswitch"),
19 "user" : self
.settings
.get("freeswitch_database_user"),
20 "password" : self
.settings
.get("freeswitch_database_password"),
23 return database
.Connection(**credentials
)
25 def get_sip_registrations(self
, sip_uri
):
26 logging
.debug("Fetching SIP registrations for %s" % sip_uri
)
28 user
, delim
, domain
= sip_uri
.partition("@")
30 res
= self
.db
.query("SELECT * FROM sip_registrations \
31 WHERE sip_user = %s AND sip_host = %s AND expires >= EXTRACT(epoch FROM CURRENT_TIMESTAMP) \
32 ORDER BY contact", user
, domain
)
35 yield SIPRegistration(self
, data
=row
)
37 def get_sip_channels(self
, account
):
38 res
= self
.db
.query("SELECT * FROM channels \
39 WHERE (direction = %s AND cid_num = %s) OR \
40 (direction = %s AND callee_num = %s) ORDER BY created_epoch",
41 "inbound", account
.sip_id
, "outbound", account
.sip_id
)
46 c
= Channel(self
, data
=row
)
51 def get_cdr_by_account(self
, account
, date
=None, limit
=None):
52 res
= self
.db
.query("SELECT * FROM cdr \
53 WHERE ((caller_id_number = %s AND bleg_uuid IS NOT NULL) \
54 OR (destination_number = %s AND bleg_uuid IS NULL)) \
55 AND (%s IS NULL OR start_stamp::date = %s) \
56 ORDER BY end_stamp DESC LIMIT %s", account
.sip_id
,
57 account
.sip_id
, date
, date
, limit
)
60 yield CDR(self
, data
=row
)
63 class SIPRegistration(object):
64 def __init__(self
, freeswitch
, data
):
65 self
.freeswitch
= freeswitch
70 m
= re
.match(r
"Registered\(([A-Z]+)(\-NAT)?\)", self
.data
.status
)
77 return ipaddress
.ip_address(self
.data
.network_ip
)
80 def network_port(self
):
81 return self
.data
.network_port
85 return self
.data
.user_agent
87 def is_reachable(self
):
88 return self
.data
.ping_status
== "Reachable"
92 if self
.is_reachable() and self
.data
.ping_time
:
93 return self
.data
.ping_time
/ 1000.0
96 class Channel(object):
97 def __init__(self
, freeswitch
, data
):
98 self
.freeswitch
= freeswitch
103 return self
.freeswitch
.backend
107 return self
.data
.uuid
111 return self
.data
.direction
115 return self
.backend
.accounts
.get_by_sip_id(self
.caller_number
)
118 def caller_name(self
):
119 return self
.data
.cid_name
122 def caller_number(self
):
123 return self
.data
.cid_num
127 return self
.backend
.accounts
.get_by_sip_id(self
.callee_number
)
130 def callee_name(self
):
131 return self
.data
.callee_name
134 def callee_number(self
):
135 return self
.data
.callee_num
138 def called_number(self
):
139 return self
.data
.dest
142 def application(self
):
143 return self
.data
.application
146 def application_data(self
):
147 return self
.data
.application_data
151 return time
.time() - self
.data
.created_epoch
155 # We always assume a symmetric codec
157 self
.data
.write_codec
,
160 if self
.data
.write_rate
:
161 s
.append("%.0f kHz" % (int(self
.data
.write_rate
) / 1000.0))
163 if self
.data
.write_bit_rate
== "0":
166 s
.append("%.0f kBit/s" % (int(self
.data
.write_bit_rate
) / 1000.0))
179 transport_protocol
, key_negotiation
, cipher_suite
= self
.data
.secure
.split(":")
183 return "%s: %s" % (key_negotiation
.upper(), cipher_suite
.replace("_", "-"))
187 def __init__(self
, freeswitch
, data
):
188 self
.freeswitch
= freeswitch
193 return self
.freeswitch
.backend
197 if self
.data
.bleg_uuid
:
204 return self
.backend
.accounts
.get_by_phone_number(self
.data
.caller_id_number
)
207 def caller_number(self
):
208 return self
.data
.caller_id_number
212 return self
.backend
.accounts
.get_by_phone_number(self
.data
.destination_number
)
215 def callee_number(self
):
216 return self
.data
.destination_number
219 def time_start(self
):
220 return self
.data
.start_stamp
223 def time_answered(self
):
224 return self
.data
.answer_stamp
228 return self
.data
.duration
232 return self
.data
.write_codec
235 def user_agent(self
):
236 return self
.data
.user_agent
.replace("_", " ")
240 return sum((self
.data
.rtp_audio_in_raw_bytes
or 0, self
.data
.rtp_audio_out_raw_bytes
or 0))
244 return self
.data
.rtp_audio_in_mos
249 # Connect to FreeSWITCH
250 self
.freeswitch
= Freeswitch(self
.backend
)
255 def conferences(self
):
258 for no
in range(1, 10):
259 conference
= Conference(self
.backend
, no
)
260 conferences
.append(conference
)
264 def get_conference(self
, id):
265 for c
in self
.conferences
:
266 if not c
.sip_id
== id:
272 class Conference(Object
):
273 def __init__(self
, backend
, no
):
274 Object
.__init
__(self
, backend
)
277 def __cmp__(self
, other
):
278 return cmp(self
.no
, other
.no
)
282 return "IPFire Conference Room %s" % self
.no
286 return "%s" % (9000 + self
.no
)
290 return "%s@ipfire.org" % self
.sip_id
293 def participants(self
):
294 if not hasattr(self
, "_participants"):
295 self
._participants
= self
.backend
.talk
.get_ongoing_calls(sip_id
=self
.sip_id
)
297 return self
._participants