talk grid
This commit is contained in:
parent
83b581f3b7
commit
e16ba4ee2f
4 changed files with 110 additions and 4 deletions
|
@ -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::
|
||||
|
||||
|
||||
|
|
|
@ -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::
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
39
talks/_templates/grid.html
Normal file
39
talks/_templates/grid.html
Normal 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: #}
|
Loading…
Reference in a new issue