From e16ba4ee2f3983cc19c061708b565c25d15b27d6 Mon Sep 17 00:00:00 2001 From: boyska Date: Sat, 6 May 2017 03:24:17 +0200 Subject: [PATCH] talk grid --- content/pages/programma.en.rst | 2 + content/pages/programma.rst | 2 + plugins/talks.py | 71 ++++++++++++++++++++++++++++++++-- talks/_templates/grid.html | 39 +++++++++++++++++++ 4 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 talks/_templates/grid.html diff --git a/content/pages/programma.en.rst b/content/pages/programma.en.rst index 668cf5c..44eda1b 100644 --- a/content/pages/programma.en.rst +++ b/content/pages/programma.en.rst @@ -17,6 +17,8 @@ appreciated! Hackmeeting (still) hasn't a proper translation system, but you can find a bunch of people to ask to do translations when you need it. +.. talkgrid:: + .. talklist:: diff --git a/content/pages/programma.rst b/content/pages/programma.rst index daabcda..a98196e 100644 --- a/content/pages/programma.rst +++ b/content/pages/programma.rst @@ -12,5 +12,7 @@ Leggi l'`invito a presentare dei contenuti `_, fatti coraggio e proponi il tuo contenuto in `mailing list <{filename}contatti.rst>`_ +.. talkgrid:: + .. talklist:: diff --git a/plugins/talks.py b/plugins/talks.py index b7e5e41..387c0e0 100644 --- a/plugins/talks.py +++ b/plugins/talks.py @@ -20,6 +20,9 @@ import jinja2 TALKS_PATH = 'talks' +TALK_ATTACHMENT_PATH = 'res' +TALK_ICS = 'schedule.ics' +GRID_STEP = 15 def memoize(function): @@ -49,6 +52,10 @@ def all_talks(): return [get_talk_data(tn) for tn in get_talk_names()] +def unique_attr(iterable, attr): + return {x[attr] for x in iterable + if attr in x} + @memoize def get_global_data(): @@ -108,7 +115,7 @@ def get_talk_data(talkname): else: logging.error("Talk <{}> has malformed `time`".format(talkname)) data['id'] = talkname - resdir = os.path.join(TALKS_PATH, talkname, 'res') + resdir = os.path.join(TALKS_PATH, talkname, TALK_ATTACHMENT_PATH) if os.path.isdir(resdir) and os.listdir(resdir): data['resources'] = resdir return data @@ -152,6 +159,59 @@ class TalkDirective(Directive): ] +class TalkGridDirective(Directive): + '''A complete grid''' + required_arguments = 0 + + optional_arguments = 0 + final_argument_whitespace = True + has_content = True + + def run(self): + tmpl = jinja_env.get_template('grid.html') + output = [] + days = unique_attr(all_talks(), 'day') + for day in sorted(days): + talks = {talk['id'] for talk in all_talks() + if talk.get('day', None) == day + and 'time' in talk + and 'room' in talk} + if not talks: + continue + talks = [get_talk_data(t) for t in talks] + rooms = tuple(sorted(unique_attr(talks, 'room'))) + mintime = min({talk['time'].hour * 60 + + talk['time'].minute + for talk in talks}) / GRID_STEP * GRID_STEP + maxtime = max({talk['time'].hour * 60 + + talk['time'].minute + + talk['duration'] + for talk in talks}) + times = {} + + for t in range(mintime, maxtime, GRID_STEP): + times[t] = [None] * len(rooms) + for talk in talks: + talktime = talk['time'].hour * 60 + talk['time'].minute + position = talktime // GRID_STEP * GRID_STEP # round + assert position in times + roomnum = rooms.index(talk['room']) + times[position][roomnum] = talk + for i in range(1, talk['duration'] / GRID_STEP): + times[position + i*GRID_STEP][roomnum] = 'skip' + + render = tmpl.render(times=times, + rooms=rooms, + mintime=mintime, maxtime=maxtime, + timestep=GRID_STEP, + ) + output.append(nodes.raw('', '

%s

' % + day.strftime('%A %d').title(), + format='html')) + output.append(nodes.raw('', render, format='html')) + return output + + def talks_to_ics(): content = 'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:pelican\n' for t in all_talks(): @@ -161,6 +221,8 @@ def talks_to_ics(): def talk_to_ics(talk): + if 'time' not in talk: + return '' start = talk['time'] end = start + datetime.timedelta(minutes=talk['duration']) content = 'BEGIN:VEVENT\n' @@ -191,12 +253,12 @@ class TalksGenerator(generators.Generator): def generate_output(self, writer=None): for talkname in self.talks: if 'resources' in self.talks[talkname]: - outdir = os.path.join(self.output_path, 'talks', talkname, - 'res') + outdir = os.path.join(self.output_path, TALKS_PATH, talkname, + TALK_ATTACHMENT_PATH) if os.path.isdir(outdir): shutil.rmtree(outdir) shutil.copytree(self.talks[talkname]['resources'], outdir) - with open(os.path.join(self.output_path, 'talks.ics'), 'w') as buf: + with open(os.path.join(self.output_path, TALK_ICS), 'w') as buf: buf.write(talks_to_ics()) @@ -222,3 +284,4 @@ else: signals.initialized.connect(add_talks_option_defaults) directives.register_directive('talklist', TalkListDirective) directives.register_directive('talk', TalkDirective) + directives.register_directive('talkgrid', TalkGridDirective) diff --git a/talks/_templates/grid.html b/talks/_templates/grid.html new file mode 100644 index 0000000..99d9c57 --- /dev/null +++ b/talks/_templates/grid.html @@ -0,0 +1,39 @@ + + + + + + {% for room in rooms %} + + {% endfor %} + + + + {% for time in range (mintime, maxtime, timestep) %} + + + {% for talk in times[time / timestep * timestep] %} + {% if talk == None %} + + {% elif talk != 'skip' %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
{{room}}
{{time//60}}:{{time % 60}} + {{talk.title}} +
+{# vim: set ft=jinja: #}