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
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
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"
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))
</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">
--- /dev/null
+{% 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 %}
"UsersList" : users.ListModule,
# VoIP
+ "VoIPConferences" : voip.ConferencesModule,
"VoIPOutboundRegistrations" :
voip.OutboundRegistrationsModule,
"VoIPQueues" : voip.QueuesModule,
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):
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)