From: Michael Tremer Date: Wed, 28 Jun 2023 16:41:20 +0000 (+0000) Subject: voip: Show conferences X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=214a68a05594c61106b64ea81688cbd63bd0d6fa;p=ipfire.org.git voip: Show conferences Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 3b93fb4c..60546077 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/src/backend/asterisk.py b/src/backend/asterisk.py index d8c74bca..2ea954f4 100644 --- a/src/backend/asterisk.py +++ b/src/backend/asterisk.py @@ -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)) diff --git a/src/templates/voip/index.html b/src/templates/voip/index.html index df15086f..7177cb21 100644 --- a/src/templates/voip/index.html +++ b/src/templates/voip/index.html @@ -37,6 +37,19 @@ {% end %} + {% if conferences %} +
+
+

+ {{ _("Conferences") }} + {{ len(conferences) }} +

+ + {% module VoIPConferences(conferences) %} +
+
+ {% end %} + {% if queues %}
diff --git a/src/templates/voip/modules/conferences.html b/src/templates/voip/modules/conferences.html new file mode 100644 index 00000000..cc26b743 --- /dev/null +++ b/src/templates/voip/modules/conferences.html @@ -0,0 +1,19 @@ +{% for c in conferences %} +
+
{{ _("Conference Room %s") % c }}
+ + {% if c.members %} +
    + {% for m in sorted(c.members) %} +
  • + {{ m }} + + + {{ format_time(m.duration) }} + +
  • + {% end %} +
+ {% end %} +
+{% end %} diff --git a/src/web/__init__.py b/src/web/__init__.py index 2f14ca67..dbf510c2 100644 --- a/src/web/__init__.py +++ b/src/web/__init__.py @@ -89,6 +89,7 @@ class Application(tornado.web.Application): "UsersList" : users.ListModule, # VoIP + "VoIPConferences" : voip.ConferencesModule, "VoIPOutboundRegistrations" : voip.OutboundRegistrationsModule, "VoIPQueues" : voip.QueuesModule, diff --git a/src/web/voip.py b/src/web/voip.py index b5794b14..ed8d3397 100644 --- a/src/web/voip.py +++ b/src/web/voip.py @@ -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)