talk grid

This commit is contained in:
boyska 2017-05-06 03:24:17 +02:00 committed by dbz
parent 83b581f3b7
commit e16ba4ee2f
4 changed files with 110 additions and 4 deletions

View file

@ -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::

View file

@ -12,5 +12,7 @@ Leggi l'`invito a presentare dei contenuti
<http://lists.autistici.org/message/20170502.165954.0e930b75.en.html>`_, fatti coraggio e proponi il tuo contenuto in `mailing
list <{filename}contatti.rst>`_
.. talkgrid::
.. talklist::

View file

@ -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('', '<h4>%s</h4>' %
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)

View file

@ -0,0 +1,39 @@
<style>
.talk-grid {
table-layout: fixed;
width: 100%;
}
.talk-grid > thead th:first-child {
max-width: 5em;
}
td.talk {
border: 1px solid;
}
</style>
<table class="talk-grid">
<thead>
<tr>
<th></th>
{% for room in rooms %}
<th>{{room}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for time in range (mintime, maxtime, timestep) %}
<tr>
<td>{{time//60}}:{{time % 60}}</td>
{% for talk in times[time / timestep * timestep] %}
{% if talk == None %}
<td></td>
{% elif talk != 'skip' %}
<td class="talk" rowspan="{{talk.duration // timestep}}">
<a href="#talk-{{talk.id}}"> {{talk.title}}</a>
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{# vim: set ft=jinja: #}