Support for room and track URLs

Allow to associate a URL to a room, for example a link to a video
conference room. Tracks assigned to this room will automatically inherit
the link. The link for a given track can be overridden using the "url"
command.

This allows organizers to provide video links for each room, while still
enabling teams to link to whatever they end up really using.

Change-Id: I633eb83c579e4093ae769bcd053e4d2ec2fe4bc3
This commit is contained in:
Thierry Carrez 2020-05-04 14:09:31 +02:00
parent d2d7d21e98
commit 5538127768
6 changed files with 51 additions and 10 deletions

View File

@ -154,6 +154,20 @@ pass ``auto`` as the etherpad URL::
#keystone etherpad auto #keystone etherpad auto
url
---
A URL can be associated to a track, for example pointing to where the video
meeting happens. By default the bot points to the URL associated to the room,
if any. You can override it using the ``url`` command::
#keystone url https://meet.jit.si/awesome-keystone-meeting
If you set a track-specific URL and would like to remove it, you can pass
``none`` as the URL::
#keystone url none
color color
----- -----
@ -244,7 +258,7 @@ Join that channel and load base JSON data from a public URL (see base.json
for an example). You can use the pastebin service as a quick way to publish for an example). You can use the pastebin service as a quick way to publish
that data:: that data::
~fetchdb http://paste.openstack.org/raw/793036/ ~fetchdb http://paste.openstack.org/raw/793040/
Then you can give other commands to the bot, like:: Then you can give other commands to the bot, like::

View File

@ -170,6 +170,7 @@
"WedP2": "" "WedP2": ""
}, },
"Ballroom A": { "Ballroom A": {
"url": "http://meet.jit.si/DEN-ptg-BallroomA",
"FriA1": "nova", "FriA1": "nova",
"FriA2": "nova", "FriA2": "nova",
"FriP1": "nova", "FriP1": "nova",

View File

@ -53,7 +53,7 @@
{{#each tracks as |track| }} {{#each tracks as |track| }}
{{#if (lookup @root.now track) }} {{#if (lookup @root.now track) }}
<tr> <tr>
<td class="col-sm-1">{{trackbadge track}}</span></td> <td class="col-sm-1">{{trackbadge @root.urls @root.location @root.schedule track}}</span></td>
<td>{{#trackContentLine}}{{lookup @root.now track}}{{/trackContentLine}}</td> <td>{{#trackContentLine}}{{lookup @root.now track}}{{/trackContentLine}}</td>
<td>{{lookup @root.location track}} <td>{{lookup @root.location track}}
{{#if (checkins track)}} {{#if (checkins track)}}
@ -80,7 +80,7 @@
{{#each tracks as |track| }} {{#each tracks as |track| }}
{{#if (lookup @root.next track) }} {{#if (lookup @root.next track) }}
<tr> <tr>
<td class="col-sm-1">{{trackbadge track}}</span></td> <td class="col-sm-1">{{trackbadge @root.urls @root.location @root.schedule track}}</span></td>
<td> <td>
{{#each (lookup @root.next track) as |item|}} {{#each (lookup @root.next track) as |item|}}
{{#trackContentLine}}{{item}}{{/trackContentLine}} <br/> {{#trackContentLine}}{{item}}{{/trackContentLine}} <br/>
@ -121,7 +121,7 @@
<span class="glyphicon glyphicon-{{sched.cap_icon}}" <span class="glyphicon glyphicon-{{sched.cap_icon}}"
title="{{sched.cap_desc}}"></span>{{/if}}</td> title="{{sched.cap_desc}}"></span>{{/if}}</td>
{{#each (lookup @root.slots day) as |time|}} {{#each (lookup @root.slots day) as |time|}}
<td>{{ roomcode @root.schedule room time.name 0 }}</td> <td>{{ roomcode @root.urls @root.schedule room time.name 0 }}</td>
{{/each}} {{/each}}
</tr> </tr>
{{/if}} {{/if}}

View File

@ -57,20 +57,31 @@ function checkins_tooltip(track) {
} }
} }
function track_badge(track) { function track_badge(track, roomurl) {
var title = checkins_tooltip(track); var title = checkins_tooltip(track);
if (roomurl != undefined) {
return '<a target="_blank" href="' + roomurl +
'" class="label label-primary ' +
track +
'" title="' + title + '">' + track;
}
return '<span class="label label-primary ' + return '<span class="label label-primary ' +
track + track +
'" title="' + title + '">' + track; '" title="' + title + '">' + track;
} }
Handlebars.registerHelper('trackbadge', Handlebars.registerHelper('trackbadge',
function(track) { function(urls, locations, schedule, track) {
return new Handlebars.SafeString(track_badge(track)); if (urls[track] != undefined) {
roomurl = urls[track];
} else {
roomurl = schedule[locations[track]]['url'];
}
return new Handlebars.SafeString(track_badge(track, roomurl));
}); });
Handlebars.registerHelper('roomcode', Handlebars.registerHelper('roomcode',
function(schedule, room, timecode, s) { function(urls, schedule, room, timecode, s) {
var cell = ''; var cell = '';
if (schedule[room][timecode] != undefined) { if (schedule[room][timecode] != undefined) {
if (schedule[room][timecode] == "") { if (schedule[room][timecode] == "") {
@ -80,7 +91,12 @@ Handlebars.registerHelper('roomcode',
cell = '<small><i>' + room + "-" + timecode + '</i></small>'; cell = '<small><i>' + room + "-" + timecode + '</i></small>';
} }
} else { } else {
cell = track_badge(schedule[room][timecode]); if (urls[schedule[room][timecode]] != undefined) {
url = urls[schedule[room][timecode]];
} else {
url = schedule[room]['url']
}
cell = track_badge(schedule[room][timecode], url);
} }
} }
return new Handlebars.SafeString(cell); return new Handlebars.SafeString(cell);

View File

@ -313,6 +313,8 @@ class PTGBot(SASL, SSL, irc.bot.SingleServerIRCBot):
self.data.clean_tracks([track]) self.data.clean_tracks([track])
elif adverb == 'etherpad': elif adverb == 'etherpad':
self.data.add_etherpad(track, params) self.data.add_etherpad(track, params)
elif adverb == 'url':
self.data.add_url(track, params)
elif adverb == 'color': elif adverb == 'color':
self.data.add_color(track, params) self.data.add_color(track, params)
elif adverb == 'location': elif adverb == 'location':

View File

@ -36,6 +36,7 @@ class PTGDataBase():
'eventid': '', 'eventid': '',
'motd': {'message': '', 'level': 'info'}, 'motd': {'message': '', 'level': 'info'},
'links': OrderedDict(), 'links': OrderedDict(),
'urls': OrderedDict(),
# Keys for last_check_in are lower-cased nicks; # Keys for last_check_in are lower-cased nicks;
# values are in the same format as BASE_CHECK_IN # values are in the same format as BASE_CHECK_IN
'last_check_in': OrderedDict(), 'last_check_in': OrderedDict(),
@ -64,7 +65,7 @@ class PTGDataBase():
# Add tracks mentioned in configuration that are not in track list # Add tracks mentioned in configuration that are not in track list
for room, bookings in self.data['schedule'].items(): for room, bookings in self.data['schedule'].items():
for time, track in bookings.items(): for time, track in bookings.items():
if time in ['cap_icon', 'cap_desc']: if time in ['cap_icon', 'cap_desc', 'url']:
continue continue
if track and track not in self.data['tracks']: if track and track not in self.data['tracks']:
self.add_tracks([track]) self.add_tracks([track])
@ -89,6 +90,13 @@ class PTGDataBase():
self.data['etherpads'][track] = etherpad self.data['etherpads'][track] = etherpad
self.save() self.save()
def add_url(self, track, url):
if url == 'none':
del(self.data['urls'][track])
else:
self.data['urls'][track] = url
self.save()
def add_color(self, track, color): def add_color(self, track, color):
self.data['colors'][track] = color self.data['colors'][track] = color
self.save() self.save()