Implement simpler API
Move from at/until to now/next API for the bot, which is simpler to explain. Adapt rendering so that it supports multiple "next" entries.
This commit is contained in:
parent
42339394d5
commit
465f277ccb
32
README.rst
32
README.rst
|
@ -3,12 +3,30 @@ OpenStack PTG Bot
|
||||||
=================
|
=================
|
||||||
|
|
||||||
ptgbot is the bot that PTG room moderators use to surface what's
|
ptgbot is the bot that PTG room moderators use to surface what's
|
||||||
currently happening at the event. It builds a static webpage that
|
currently happening at the event. Commands follow the following format:
|
||||||
attendees can query for up-to-date information.
|
|
||||||
|
|
||||||
Commands follow the following format:
|
@ROOMNAME [now|next] TIME TOPIC
|
||||||
|
|
||||||
@ROOMNAME [until|at] TIME TOPIC
|
From that information the bot builds a static webpage with discussion
|
||||||
|
topics currently discussed ("now") and an indicative set of discussion
|
||||||
|
topics coming up next ("next").
|
||||||
|
|
||||||
|
NB:
|
||||||
|
* There can only be one "now" topic at a time. If multiple topics are
|
||||||
|
discussed at the same time in various corners of the room, they should
|
||||||
|
all be specified in a single "now" command.
|
||||||
|
* In order to ensure that information is current, entering a "now" command
|
||||||
|
wipes out any "next" entry for the same room. You might want to refresh
|
||||||
|
those after entering a "now" topic.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
#swift now discussing ring placement
|
||||||
|
#swift next at 2pm we plan to discuss #glance support
|
||||||
|
#swift next around 3pm we plan to cover cold storage features
|
||||||
|
...
|
||||||
|
#swift now discussing #glance support, come over!
|
||||||
|
#swift next at 3pm we plan to cover cold storage features
|
||||||
|
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
|
@ -28,13 +46,13 @@ port=6667
|
||||||
channels=testptg
|
channels=testptg
|
||||||
db=html/ptg.json
|
db=html/ptg.json
|
||||||
|
|
||||||
In one terminal, run the bot:
|
In one terminal, run the bot::
|
||||||
|
|
||||||
tox -evenv -- ptgbot -d config.ini
|
tox -evenv -- ptgbot -d config.ini
|
||||||
|
|
||||||
Join that channel and give a command to the bot:
|
Join that channel and give a command to the bot::
|
||||||
|
|
||||||
@swift until 10:00 Discussing ring internals
|
@swift now discussing ring placement
|
||||||
|
|
||||||
(note, the bot currently only takes commands from Freenode identified users)
|
(note, the bot currently only takes commands from Freenode identified users)
|
||||||
|
|
||||||
|
|
|
@ -18,20 +18,34 @@
|
||||||
|
|
||||||
<script id="PTGtemplate" type="text/x-handlebars-template">
|
<script id="PTGtemplate" type="text/x-handlebars-template">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><h3 class="panel-title">Currently playing</h3></div>
|
<div class="panel-heading"><h3 class="panel-title">Currently playing...</h3></div>
|
||||||
<ul class="list-group">
|
<table class="table">
|
||||||
{{#each until}}
|
{{#each now}}
|
||||||
<li class="list-group-item"><span class="label label-primary">{{@key}}</span> {{this.msg}}</li>
|
<tr>
|
||||||
|
<td class="col-sm-1"><span class="label label-primary">{{@key}}</span></td>
|
||||||
|
<td>{{this}}</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><small><i>Nothing yet</i></small><td></tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><h3 class="panel-title">Next discussions</h3></div>
|
<div class="panel-heading"><h3 class="panel-title">Coming up next...</h3></div>
|
||||||
<ul class="list-group">
|
<table class="table">
|
||||||
{{#each at}}
|
{{#each next as |sessions room|}}
|
||||||
<li class="list-group-item"><span class="label label-primary">{{@key}}</span> {{this.msg}}</li>
|
<tr>
|
||||||
|
<td class="col-sm-1"><span class="label label-primary">{{room}}</span></td>
|
||||||
|
<td>
|
||||||
|
{{#each sessions}}
|
||||||
|
{{ this }}<br/>
|
||||||
|
{{/each}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{else}}
|
||||||
|
<tr><td><small><i>Nothing yet</i></small><td></tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -88,7 +88,7 @@ class PTGBot(irc.bot.SingleServerIRCBot):
|
||||||
self.identify_msg_cap = True
|
self.identify_msg_cap = True
|
||||||
|
|
||||||
def usage(self, channel):
|
def usage(self, channel):
|
||||||
self.send(channel, "Format is '@ROOM [until|at] HOUR SESSION'")
|
self.send(channel, "Format is '@ROOM [now|next] SESSION'")
|
||||||
|
|
||||||
def on_pubmsg(self, c, e):
|
def on_pubmsg(self, c, e):
|
||||||
if not self.identify_msg_cap:
|
if not self.identify_msg_cap:
|
||||||
|
@ -100,26 +100,23 @@ class PTGBot(irc.bot.SingleServerIRCBot):
|
||||||
msg = e.arguments[0][1:]
|
msg = e.arguments[0][1:]
|
||||||
chan = e.target
|
chan = e.target
|
||||||
|
|
||||||
if msg.startswith('@') and auth:
|
if msg.startswith('#') and auth:
|
||||||
words = msg.split()
|
words = msg.split()
|
||||||
if len(words) < 4:
|
if len(words) < 3:
|
||||||
self.send(chan, "%s: Incorrect number of arguments" % (nick,))
|
self.send(chan, "%s: Incorrect number of arguments" % (nick,))
|
||||||
self.usage(chan)
|
self.usage(chan)
|
||||||
return
|
return
|
||||||
room = words[0][1:].lower()
|
room = words[0][1:].lower()
|
||||||
# TODO: Add test for room/day/person match
|
# TODO: Add test for room/day/person match
|
||||||
adverb = words[1].lower()
|
adverb = words[1].lower()
|
||||||
if adverb not in ['until', 'at']:
|
session = str.join(' ', words[2:])
|
||||||
|
if adverb == 'now':
|
||||||
|
self.data.add_now(room, session)
|
||||||
|
elif adverb == 'next':
|
||||||
|
self.data.add_next(room, session)
|
||||||
|
else:
|
||||||
self.send(chan, "%s: unknown directive '%s'" % (nick, adverb))
|
self.send(chan, "%s: unknown directive '%s'" % (nick, adverb))
|
||||||
self.usage(chan)
|
self.usage(chan)
|
||||||
return
|
|
||||||
hour = words[2]
|
|
||||||
# TODO: Add test for hour format
|
|
||||||
session = str.join(' ', words[3:])
|
|
||||||
|
|
||||||
msg = '(%s %s) %s' % (adverb, hour, session)
|
|
||||||
self.data.add(room, adverb, hour, msg)
|
|
||||||
return
|
|
||||||
|
|
||||||
def send(self, channel, msg):
|
def send(self, channel, msg):
|
||||||
self.connection.privmsg(channel, msg)
|
self.connection.privmsg(channel, msg)
|
||||||
|
|
23
ptgbot/db.py
23
ptgbot/db.py
|
@ -26,28 +26,25 @@ class PTGDataBase():
|
||||||
with open(filename, 'r') as fp:
|
with open(filename, 'r') as fp:
|
||||||
self.data = json.load(fp)
|
self.data = json.load(fp)
|
||||||
else:
|
else:
|
||||||
self.data = {}
|
self.data = {'now': {}, 'next': {}}
|
||||||
|
|
||||||
def add(self, room, adverb, hour, msg):
|
def add_now(self, room, session):
|
||||||
if adverb not in self.data:
|
self.data['now'][room] = session
|
||||||
self.data[adverb] = {}
|
if room in self.data['next']:
|
||||||
self.data[adverb][room] = {'msg': msg, 'expiry': hour}
|
del self.data['next'][room]
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
def expire(self, now):
|
def add_next(self, room, session):
|
||||||
newdata = []
|
if room not in self.data['next']:
|
||||||
for room, infos in self.data.items():
|
self.data['next'][room] = []
|
||||||
for info, session in infos:
|
self.data['next'][room].append(session)
|
||||||
if session['expiry'] > now:
|
self.save()
|
||||||
newdata[room][info] = session
|
|
||||||
self.data = newdata
|
|
||||||
|
|
||||||
def from_ethercalc(self):
|
def from_ethercalc(self):
|
||||||
# TODO: Load from ethercalc
|
# TODO: Load from ethercalc
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
# self.expire()
|
|
||||||
# self.from_ethercalc()
|
# self.from_ethercalc()
|
||||||
with open(self.filename, 'w') as fp:
|
with open(self.filename, 'w') as fp:
|
||||||
json.dump(self.data, fp)
|
json.dump(self.data, fp)
|
||||||
|
|
Loading…
Reference in New Issue