]> git.ipfire.org Git - ipfire.org.git/blobdiff - webapp/backend/talk.py
talk: Update for Kamailio
[ipfire.org.git] / webapp / backend / talk.py
index 70a4172437f3d5bbbaec69a4442c06be55e67de0..cad51d984e96942791ffd321f7d13d999fad598b 100644 (file)
@@ -1,5 +1,7 @@
 #!/usr/bin/python
 
+import re
+
 import database
 
 from misc import Object
@@ -8,7 +10,7 @@ class Talk(Object):
        def init(self):
                db_args = self.backend.db._db_args
                db_args.update({
-                       "database" : "yate",
+                       "database" : "kamailio",
                })
 
                self._db = database.Connection(**db_args)
@@ -31,7 +33,7 @@ class Talk(Object):
                return accounts
 
        def user_is_online(self, sip_id):
-               res = self.db.get("SELECT 1 FROM lines WHERE username = %s \
+               res = self.db.get("SELECT 1 FROM location WHERE username = %s \
                        AND expires >= NOW() LIMIT 1", sip_id)
 
                if res:
@@ -39,28 +41,35 @@ class Talk(Object):
 
                return False
 
-       def get_trunks(self):
-               res = self.db.query("SELECT * FROM accounts WHERE enabled = TRUE \
-                       ORDER BY description, account")
-
-               return res
+       def get_lines(self, account=None):
+               accounts_cache = {}
 
-       def get_lines(self, account):
-               if not account.is_talk_enabled():
+               if account and not account.is_talk_enabled():
                        return []
 
-               res = self.db.query("SELECT location, expires, user_agent FROM lines \
-                       WHERE username = %s ORDER BY expires DESC", account.sip_id)
+               if account:
+                       res = self.db.query("SELECT contact AS location, expires, user_agent, socket \
+                               FROM location WHERE domain = %s AND username = %s ORDER BY expires DESC",
+                               "ipfire.org", account.sip_id)
+               else:
+                       res = self.db.query("SELECT username, domain, contact AS location, \
+                               expires, user_agent, socket FROM location ORDER BY username, expires DESC")
 
                result = []
                for row in res:
-                       # Check if TLS is used
-                       row.tls_enabled = row.location.startswith("sip/sips:") or \
-                               "transport=TLS" in row.location
+                       if account:
+                               row.account = account
+                       elif row.username:
+                               try:
+                                       row.account = accounts_cache[row.username]
+                               except KeyError:
+                                       row.account = accounts_cache[row.username] = \
+                                               self.accounts.get_by_sip_id(row.username)
+                       else:
+                               row.account = None
 
-                       # Strip a leading sip/
-                       if row.location.startswith("sip/"):
-                               row.location = row.location[4:]
+                       # Check if TLS is used
+                       row.tls_enabled = row.socket.startswith("tls:")
 
                        # Cut off everything after ;
                        row.location, sep, rest = row.location.partition(";")
@@ -69,39 +78,62 @@ class Talk(Object):
 
                return result
 
-       def _process_cdr(self, entries):
+       def _process_sip_uri(self, sip_uri):
+               sip_uri, delimiter, rest = sip_uri.partition(";")
+
+               m = re.match(r"^sip:([0-9]{4})@ipfire\.org", sip_uri)
+               if m:
+                       return m.group(1)
+
+               # Remove trailing default port
+               if sip_uri.endswith(":5060"):
+                       sip_uri = sip_uri.replace(":5060", "")
+
+               return sip_uri
+
+       def _process_cdr(self, entries, replace_sip_uris=False):
                accounts_cache = {}
 
                result = []
                for row in entries:
+                       if replace_sip_uris:
+                               row["caller"] = self._process_sip_uri(row.caller)
+
                        try:
-                               row.caller_account = accounts_cache[row.caller]
+                               row["caller_account"] = accounts_cache[row.caller]
                        except KeyError:
-                               row.caller_account = accounts_cache[row.caller] = \
+                               row["caller_account"] = accounts_cache[row.caller] = \
                                        self.accounts.get_by_sip_id(row.caller)
 
+                       if replace_sip_uris:
+                               row["called"] = self._process_sip_uri(row.called)
+
                        try:
-                               row.called_account = accounts_cache[row.called]
+                               row["called_account"] = accounts_cache[row.called]
                        except KeyError:
-                               row.called_account = accounts_cache[row.called] = \
+                               row["called_account"] = accounts_cache[row.called] = \
                                        self.accounts.get_by_sip_id(row.called)
 
                        if not row.called_account:
-                               row.called_conference = self.get_conference(row.called)
+                               row["called_conference"] = self.get_conference(row.called)
                        else:
-                               row.called_conference = None
+                               row["called_conference"] = None
+
+                       try:
+                               row["time"] = datetime.datetime.fromutctimestamp(row.time)
+                       except:
+                               pass
 
                        result.append(row)
 
                return result
 
        def get_call_log(self, account, limit=25):
-               res = self.db.query("SELECT * FROM cdr \
-                       WHERE ((direction = 'incoming' AND called = %s) OR (direction = 'outgoing' AND caller = %s)) \
-                       AND (status = 'answered' OR \
-                               (status = 'ringing' AND (reason = 'hangup' OR reason = 'Request Terminated'))) \
-                       AND NOT (status = 'outgoing' AND reason = 'pickup') \
-                       AND ended = TRUE ORDER BY time DESC LIMIT %s", account.sip_id, account.sip_id, limit)
+               if account:
+                       res = self.db.query("SELECT * FROM cdr WHERE (caller = %s OR called = %s) \
+                               ORDER BY time DESC LIMIT %s", account.sip_id, account.sip_id, limit)
+               else:
+                       res = self.db.query("SELECT * FROM cdr ORDER BY time DESC LIMIT %s", limit)
 
                return self._process_cdr(res)
 
@@ -109,18 +141,23 @@ class Talk(Object):
                if account and sip_id is None:
                        sip_id = account.sip_id
 
+                       # If the given account does not have a SIP ID,
+                       # we not need to search for any active sessions
+                       if sip_id is None:
+                               return []
+
                if sip_id:
-                       res = self.db.query("SELECT * FROM cdr \
-                               WHERE direction = 'incoming' AND (caller = %s OR called = %s) \
-                                       AND status = 'answered' AND NOT ended \
-                               ORDER BY time", sip_id, sip_id)
+                       sip_id = "sip:%s@%%" % sip_id
+
+                       res = self.db.query("SELECT from_uri AS caller, \
+                               to_uri AS called, start_time AS time FROM dialog \
+                               WHERE from_uri LIKE %s OR to_uri LIKE %s ORDER BY time",
+                               sip_id, sip_id)
                else:
-                       res = self.db.query("SELECT * FROM cdr \
-                               WHERE direction = 'incoming' AND \
-                                       status = 'answered' AND NOT ended \
-                               ORDER BY time")
+                       res = self.db.query("SELECT from_uri AS caller, to_uri AS called, \
+                               start_time AS time FROM dialog ORDER BY time")
 
-               return self._process_cdr(res)
+               return self._process_cdr(res, replace_sip_uris=True)
 
        def initiate_call(self, caller, called, when=None):
                self.db.execute("INSERT INTO dialout(caller, called, not_before) \
@@ -129,12 +166,11 @@ class Talk(Object):
        # Favourites
 
        def get_favourite_contacts(self, account, limit=6):
-               ignored_numbers = ["9999", account.sip_id, ""]
-
-               res = self.db.query("SELECT called, %s AS caller, COUNT(*) AS count FROM cdr \
-                       WHERE direction = 'outgoing' AND caller = %s AND status = 'answered' \
-                       AND NOT called = ANY(%s) GROUP BY called ORDER BY count DESC LIMIT %s",
-                       account.sip_id, account.sip_id, ignored_numbers, limit)
+               res = self.db.query("SELECT src_user AS caller, dst_ouser AS called, \
+                       COUNT(*) AS count FROM acc WHERE method = %s AND src_user = %s AND \
+                       dst_ouser BETWEEN %s AND %s AND time >= NOW() - INTERVAL '1 year' \
+                       GROUP BY caller, called ORDER BY count DESC LIMIT %s",
+                       "INVITE", account.sip_id, "1000", "1999", limit)
 
                return self._process_cdr(res)
 
@@ -191,6 +227,9 @@ class Conference(Object):
                participants = [p.caller for p in self.participants]
 
                for invitee in self.backend.talk.get_phonebook():
+                       if not invitee.sip_id:
+                               continue
+
                        if invitee.sip_id in participants:
                                continue