]> git.ipfire.org Git - ipfire.org.git/commitdiff
voip: Show conferences
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 28 Jun 2023 16:41:20 +0000 (16:41 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 28 Jun 2023 16:41:20 +0000 (16:41 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/backend/asterisk.py
src/templates/voip/index.html
src/templates/voip/modules/conferences.html [new file with mode: 0644]
src/web/__init__.py
src/web/voip.py

index 3b93fb4ce97e6e472cbf998faf86b5db6f88f36b..60546077b60761c78c6860d9876c67bf5a719de6 100644 (file)
@@ -325,6 +325,7 @@ templates_voip_DATA = \
 templates_voipdir = $(templatesdir)/voip
 
 templates_voip_modules_DATA = \
+       src/templates/voip/modules/conferences.html \
        src/templates/voip/modules/outbound-registrations.html \
        src/templates/voip/modules/queues.html \
        src/templates/voip/modules/registrations.html
index d8c74bcab17b250c195fff9688218d5a7e5d60ad..2ea954f46d68e4355363427ce5a25790d7994c27 100644 (file)
@@ -58,11 +58,14 @@ class Asterisk(misc.Object):
                result = manager.ping()
                print(result)
 
-       async def _fetch(self, cls, action, filter=None):
+       async def _fetch(self, cls, action, filter=None, data={}):
                objects = []
 
+               # Collect arguments
+               args = { "Action" : action } | data
+
                # Run the action and parse all messages
-               for data in await self.manager.send_action({ "Action" : action }):
+               for data in await self.manager.send_action(args):
                        if not data.Event == cls.event:
                                continue
 
@@ -100,6 +103,16 @@ class Asterisk(misc.Object):
 
                return queues.values()
 
+       async def get_conferences(self):
+               conferences = await self._fetch(Conference, "ConfbridgeListRooms")
+
+               # Fetch everything else
+               async with asyncio.TaskGroup() as tasks:
+                       for c in conferences:
+                               tasks.create_task(c._fetch())
+
+               return conferences
+
 
 class Channel(misc.Object):
        event = "CoreShowChannel"
@@ -299,3 +312,52 @@ class QueueMember(misc.Object):
                return datetime.datetime.fromtimestamp(int(self.data.LoginTime))
 
        # XXX status?
+
+
+class Conference(misc.Object):
+       event = "ConfbridgeListRooms"
+
+       def init(self, data):
+               self.data = data
+
+       def __str__(self):
+               return self.name
+
+       @property
+       def name(self):
+               return self.data.Conference
+
+       async def _fetch(self):
+               # Fetch all members
+               self.members = await self.backend.asterisk._fetch(
+                       ConferenceMember, "ConfbridgeList", data={ "Conference" : self.name, })
+
+
+class ConferenceMember(misc.Object):
+       event = "ConfbridgeList"
+
+       def init(self, data):
+               self.data = data
+
+       def __str__(self):
+               return self.name
+
+       def __lt__(self, other):
+               if isinstance(other, self.__class__):
+                       return not self.duration < other.duration
+
+               return NotImplemented
+
+       @property
+       def name(self):
+               return "%s <%s>" % (self.data.CallerIDName, self.data.CallerIDNum)
+
+       def is_admin(self):
+               return self.data.Admin == "Yes"
+
+       def is_muted(self):
+               return self.data.Muted == "Yes"
+
+       @property
+       def duration(self):
+               return datetime.timedelta(seconds=int(self.data.AnsweredTime))
index df15086f34bdde858de21ccacc1ddcbc528beacb..7177cb213e191bbe488afacafc4a10e3cfe2cc72 100644 (file)
                </section>
        {% end %}
 
+       {% if conferences %}
+               <section class="section">
+                       <div class="container">
+                               <h4 class="title is-4">
+                                       {{ _("Conferences") }}
+                                       <span class="tag">{{ len(conferences) }}</span>
+                               </h4>
+
+                               {% module VoIPConferences(conferences) %}
+                       </div>
+               </section>
+       {% end %}
+
        {% if queues %}
                <section class="section">
                        <div class="container">
diff --git a/src/templates/voip/modules/conferences.html b/src/templates/voip/modules/conferences.html
new file mode 100644 (file)
index 0000000..cc26b74
--- /dev/null
@@ -0,0 +1,19 @@
+{% for c in conferences %}
+       <div class="notification">
+               <h5 class="title is-5">{{ _("Conference Room %s") % c }}</h5>
+
+               {% if c.members %}
+                       <ul>
+                               {% for m in sorted(c.members) %}
+                                       <li>
+                                               {{ m }}
+
+                                               <span class="is-pulled-right">
+                                                       {{ format_time(m.duration) }}
+                                               </span>
+                                       </li>
+                               {% end %}
+                       </ul>
+               {% end %}
+       </div>
+{% end %}
index 2f14ca673058fbf29ff6465f851e9fe02e22eab6..dbf510c28c8ca0f89618cf5aa948a3d3340d9072 100644 (file)
@@ -89,6 +89,7 @@ class Application(tornado.web.Application):
                                "UsersList"            : users.ListModule,
 
                                # VoIP
+                               "VoIPConferences"      : voip.ConferencesModule,
                                "VoIPOutboundRegistrations" :
                                        voip.OutboundRegistrationsModule,
                                "VoIPQueues"           : voip.QueuesModule,
index b5794b147a4e8e271d6b7b299237bf71379b47e8..ed8d33972603ae4966da4b8495da6eeb611c44f4 100644 (file)
@@ -13,14 +13,17 @@ class IndexHandler(base.BaseHandler):
                if not self.current_user.is_staff():
                        raise tornado.web.HTTPError(403)
 
-               registrations, outbound_registrations, queues, = await asyncio.gather(
-                       self.backend.asterisk.get_registrations(),
-                       self.backend.asterisk.get_outbound_registrations(),
-                       self.backend.asterisk.get_queues(),
-               )
+               # Fetch everything
+               registrations, outbound_registrations, queues, conferences, = \
+                       await asyncio.gather(
+                               self.backend.asterisk.get_registrations(),
+                               self.backend.asterisk.get_outbound_registrations(),
+                               self.backend.asterisk.get_queues(),
+                               self.backend.asterisk.get_conferences(),
+                       )
 
-               self.render("voip/index.html", registrations=registrations,
-                       outbound_registrations=outbound_registrations, queues=queues)
+               self.render("voip/index.html", registrations=registrations, queues=queues,
+                       outbound_registrations=outbound_registrations, conferences=conferences)
 
 
 class OutboundRegistrationsModule(ui_modules.UIModule):
@@ -38,3 +41,8 @@ class RegistrationsModule(ui_modules.UIModule):
 class QueuesModule(ui_modules.UIModule):
        def render(self, queues):
                return self.render_string("voip/modules/queues.html", queues=queues)
+
+
+class ConferencesModule(ui_modules.UIModule):
+       def render(self, conferences):
+               return self.render_string("voip/modules/conferences.html", conferences=conferences)