]> git.ipfire.org Git - ipfire.org.git/commitdiff
talk: Show active channels
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Oct 2018 14:49:53 +0000 (15:49 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 10 Oct 2018 14:49:53 +0000 (15:49 +0100)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/accounts.py
src/backend/talk.py
src/templates/talk/index.html
src/templates/talk/modules/channels.html [new file with mode: 0644]
src/web/__init__.py
src/web/talk.py

index 0e0ae04c048b07ebb0a77e491319429e65830092..aafa632477853c12f3159a45b7031966c706f998 100644 (file)
@@ -168,6 +168,7 @@ templates_talk_DATA = \
 templates_talkdir = $(templatesdir)/talk
 
 templates_talk_modules_DATA = \
+       src/templates/talk/modules/channels.html \
        src/templates/talk/modules/registrations.html
 
 templates_talk_modulesdir = $(templates_talkdir)/modules
index 7e6e4431d5672fde36a1aa744eb53aa95cf3cbb4..faede4e31f10625746bb1e88ef8a4c9a34a1d91c 100644 (file)
@@ -12,6 +12,12 @@ from .decorators import *
 from .misc import Object
 
 class Accounts(Object):
+       def __iter__(self):
+               # Only return developers (group with ID 1000)
+               accounts = self.search("(&(objectClass=posixAccount)(gidNumber=1000))")
+
+               return iter(accounts)
+
        @property
        def ldap(self):
                if not hasattr(self, "_ldap"):
@@ -60,12 +66,6 @@ class Accounts(Object):
                if result:
                        return result[0]
 
-       def get_all(self):
-               # Only return developers (group with ID 1000)
-               return self.search("(&(objectClass=posixAccount)(gidNumber=1000))")
-
-       list = get_all
-
        def get_by_uid(self, uid):
                return self.search_one("(&(objectClass=posixAccount)(uid=%s))" % uid)
 
index 9b7d2f626b0fa99fe214d5ca94dd8b862e2c0b1e..53ec41068a0eae956dd6dea611f5829798e541e8 100644 (file)
@@ -3,6 +3,7 @@
 import ipaddress
 import logging
 import re
+import time
 
 from . import database
 
@@ -33,6 +34,15 @@ class Freeswitch(Object):
                for row in res:
                        yield SIPRegistration(self, data=row)
 
+       def get_sip_channels(self, account):
+               res = self.db.query("SELECT * FROM channels \
+                       WHERE (direction = %s AND cid_num = %s) OR \
+                               (direction = %s AND callee_num = %s) ORDER BY created_epoch",
+                       "inbound", account.sip_id, "outbound", account.sip_id)
+
+               for row in res:
+                       yield Channel(self, data=row)
+
 
 class SIPRegistration(object):
        def __init__(self, freeswitch, data):
@@ -67,33 +77,86 @@ class SIPRegistration(object):
                        return self.data.ping_time / 1000.0
 
 
+class Channel(object):
+       def __init__(self, freeswitch, data):
+               self.freeswitch = freeswitch
+               self.data = data
 
-class Talk(Object):
-       def init(self):
-               # Connect to FreeSWITCH
-               self.freeswitch = Freeswitch(self.backend)
+       @property
+       def backend(self):
+               return self.freeswitch.backend
 
-       def get_phonebook(self, account=None):
-               accounts = []
-               for a in self.accounts.list():
-                       if account and a == account:
-                               continue
+       @property
+       def uuid(self):
+               return self.data.uuid
 
-                       if not a.is_talk_enabled():
-                               continue
+       @property
+       def direction(self):
+               return self.data.direction
+
+       @lazy_property
+       def caller(self):
+               return self.backend.accounts.get_by_sip_id(self.caller_number)
+
+       @property
+       def caller_name(self):
+               return self.data.cid_name
+
+       @property
+       def caller_number(self):
+               return self.data.cid_num
+
+       @lazy_property
+       def callee(self):
+               return self.backend.accounts.get_by_sip_id(self.callee_number)
 
-                       accounts.append(a)
+       @property
+       def callee_name(self):
+               return self.data.callee_name
+
+       @property
+       def callee_number(self):
+               return self.data.callee_num
+
+       @property
+       def called_number(self):
+               return self.data.dest
+
+       @property
+       def application(self):
+               return self.data.application
 
-               return accounts
+       @property
+       def application_data(self):
+               return self.data.application_data
 
-       def user_is_online(self, sip_id):
-               res = self.db.get("SELECT 1 FROM location WHERE username = %s \
-                       AND expires >= NOW() LIMIT 1", sip_id)
+       @property
+       def duration(self):
+               return time.time() - self.data.created_epoch
 
-               if res:
-                       return True
+       @property
+       def codec(self):
+               # We always assume a symmetric codec
+               s = [
+                       "%s @ %s kHz" % (self.data.write_codec, int(self.data.write_rate) / 1000.0),
+               ]
+
+               if self.data.write_bit_rate == "0":
+                       s.append("VBR")
+               else:
+                       s.append("%.0f kBit/s" % (int(self.data.write_bit_rate) / 1000.0))
 
-               return False
+               return " ".join(s)
+
+       @property
+       def secure(self):
+               return self.data.secure
+
+
+class Talk(Object):
+       def init(self):
+               # Connect to FreeSWITCH
+               self.freeswitch = Freeswitch(self.backend)
 
        def get_lines(self, account=None):
                accounts_cache = {}
@@ -230,17 +293,6 @@ class Talk(Object):
 
                return self._process_cdr(res, replace_sip_uris=True)
 
-       # Favourites
-
-       def get_favourite_contacts(self, account, limit=6):
-               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)
-
        # Conferences
 
        @property
index 669cb85794c0ad56ca3901ed7ffa9b9dbaf67cf2..268f9c7a4933b0822b522fce8f06690b9c377a47 100644 (file)
@@ -3,5 +3,5 @@
 {% block title %}{{ _("Home") }}{% end block %}
 
 {% block main %}
-       XXX
+       {% module TalkChannels(current_user) %}
 {% end block %}
diff --git a/src/templates/talk/modules/channels.html b/src/templates/talk/modules/channels.html
new file mode 100644 (file)
index 0000000..336c429
--- /dev/null
@@ -0,0 +1,52 @@
+{% if channels %}
+       <div class="card">
+               <div class="card-body">
+                       <table class="table mb-0">
+                               <tbody>
+                                       {% for chan in channels %}
+                                               <tr>
+                                                       <td>
+                                                               {{ chan.direction }}
+
+                                                               {% if chan.direction == "inbound" %}
+                                                                       {% if chan.application == "conference" %}
+                                                                               CONFERENCE
+
+                                                                       {% else %}
+                                                                               {% if chan.callee %}
+                                                                                       <a href="/users/{{ chan.callee.uid }}">{{ chan.callee }}</a>
+                                                                               {% else %}
+                                                                                       {{ chan.callee_name }}
+                                                                               {% end %}
+               
+                                                                               <span class="text-muted">({{ chan.callee_number }})</span>
+                                                                       {% end %}
+                                                               {% elif chan.direction == "outbound" %}
+                                                                       {% if chan.caller %}
+                                                                               <a href="/users/{{ chan.caller.uid }}">{{ chan.caller }}</a>
+                                                                       {% else %}
+                                                                               {{ chan.caller_name }}
+                                                                       {% end %}
+       
+                                                                       <span class="text-muted">({{ chan.caller_number }})</span>
+                                                               {% end %}
+               
+                                                               <br>
+               
+                                                               <span class="text-muted">{{ chan.codec }}</span>
+
+                                                               {% if chan.secure %}
+                                                                       <span class="text-muted">{{ chan.secure }}</span>
+                                                               {% end %}
+                                                       </td>
+
+                                                       <td class="text-right">
+                                                               {{ format_time(chan.duration) }}
+                                                       </td>
+                                               </tr>
+                                       {% end %}
+                               </tbody>
+                       </table>
+               </div>
+       </div>
+{% end %}
index 786517135ad24382a070b20ed1cbf7f82834e07d..8c62f83008e8a30ff1eed691743694d1842de9b9 100644 (file)
@@ -53,6 +53,7 @@ class Application(tornado.web.Application):
                                "Map"                  : ui_modules.MapModule,
 
                                # Talk
+                               "TalkChannels"         : talk.ChannelsModule,
                                "TalkRegistrations"    : talk.RegistrationsModule,
 
                                # Old modules
index c3158eec4a7b598538c69ac24c2c7f62ba604894..f0f52c14b026b99402800797c9d6c034d16e4d8f 100644 (file)
@@ -31,6 +31,13 @@ class RegistrationsHandler(base.BaseHandler):
                self.render("talk/registrations.html", account=account)
 
 
+class ChannelsModule(ui_modules.UIModule):
+       def render(self, account):
+               channels = self.backend.talk.freeswitch.get_sip_channels(account)
+
+               return self.render_string("talk/modules/channels.html", account=account, channels=channels)
+
+
 class RegistrationsModule(ui_modules.UIModule):
        def render(self, account):
                return self.render_string("talk/modules/registrations.html", account=account)