plugin talks configurabile
This commit is contained in:
parent
3b80ed79b0
commit
3d172beb73
2 changed files with 50 additions and 35 deletions
|
@ -2,6 +2,7 @@
|
|||
Manage talks scheduling in a semantic way
|
||||
'''
|
||||
|
||||
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import io
|
||||
|
@ -23,11 +24,9 @@ from docutils.parsers.rst import directives, Directive
|
|||
from pelican import signals, generators
|
||||
import jinja2
|
||||
|
||||
pelican = None # This will be set during register()
|
||||
|
||||
|
||||
TALKS_PATH = 'talks'
|
||||
TALK_ATTACHMENT_PATH = 'res'
|
||||
TALK_ICS = 'schedule.ics'
|
||||
GRID_STEP = 30
|
||||
|
||||
|
||||
def memoize(function):
|
||||
|
@ -56,7 +55,7 @@ def setlocale(name):
|
|||
|
||||
@memoize
|
||||
def get_talk_names():
|
||||
return [name for name in os.listdir(TALKS_PATH)
|
||||
return [name for name in os.listdir(pelican.settings['TALKS_PATH'])
|
||||
if not name.startswith('_') and
|
||||
get_talk_data(name) is not None
|
||||
]
|
||||
|
@ -73,7 +72,7 @@ def unique_attr(iterable, attr):
|
|||
|
||||
@memoize
|
||||
def get_global_data():
|
||||
fname = os.path.join(TALKS_PATH, 'meta.yaml')
|
||||
fname = os.path.join(pelican.settings['TALKS_PATH'], 'meta.yaml')
|
||||
if not os.path.isfile(fname):
|
||||
return None
|
||||
with io.open(fname, encoding='utf8') as buf:
|
||||
|
@ -92,7 +91,7 @@ def get_global_data():
|
|||
|
||||
@memoize
|
||||
def get_talk_data(talkname):
|
||||
fname = os.path.join(TALKS_PATH, talkname, 'meta.yaml')
|
||||
fname = os.path.join(pelican.settings['TALKS_PATH'], talkname, 'meta.yaml')
|
||||
if not os.path.isfile(fname):
|
||||
return None
|
||||
with io.open(fname, encoding='utf8') as buf:
|
||||
|
@ -104,6 +103,7 @@ def get_talk_data(talkname):
|
|||
if data is None:
|
||||
return None
|
||||
try:
|
||||
gridstep = pelican.settings['TALKS_GRID_STEP']
|
||||
if 'title' not in data:
|
||||
logging.warn("Talk <{}> has no `title` field".format(talkname))
|
||||
data['title'] = talkname
|
||||
|
@ -115,10 +115,10 @@ def get_talk_data(talkname):
|
|||
.format(talkname))
|
||||
data['duration'] = 50
|
||||
data['duration'] = int(data['duration'])
|
||||
if data['duration'] < GRID_STEP:
|
||||
if data['duration'] < gridstep:
|
||||
logging.info("Talk <{}> lasts only {} minutes; changing to {}"
|
||||
.format(talkname, data['duration'], GRID_STEP))
|
||||
data['duration'] = GRID_STEP
|
||||
.format(talkname, data['duration'], gridstep))
|
||||
data['duration'] = gridstep
|
||||
if 'links' not in data or not data['links']:
|
||||
data['links'] = []
|
||||
if 'contacts' not in data or not data['contacts']:
|
||||
|
@ -145,7 +145,8 @@ def get_talk_data(talkname):
|
|||
else:
|
||||
logging.error("Talk <%s> has malformed `time`", talkname)
|
||||
data['id'] = talkname
|
||||
resdir = os.path.join(TALKS_PATH, talkname, TALK_ATTACHMENT_PATH)
|
||||
resdir = os.path.join(pelican.settings['TALKS_PATH'], talkname,
|
||||
pelican.settings['TALKS_ATTACHMENT_PATH'])
|
||||
if os.path.isdir(resdir) and os.listdir(resdir):
|
||||
data['resources'] = resdir
|
||||
return data
|
||||
|
@ -154,16 +155,19 @@ def get_talk_data(talkname):
|
|||
raise
|
||||
|
||||
|
||||
jinja_env = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(os.path.join(TALKS_PATH, '_templates')),
|
||||
autoescape=True,
|
||||
)
|
||||
jinja_env.filters['markdown'] = lambda text: \
|
||||
jinja2.Markup(markdown.Markdown(extensions=['meta']).
|
||||
convert(text))
|
||||
jinja_env.filters['dateformat'] = format_date
|
||||
jinja_env.filters['datetimeformat'] = format_datetime
|
||||
jinja_env.filters['timeformat'] = format_time
|
||||
@memoize
|
||||
def jinja_env():
|
||||
env = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(os.path.join(pelican.settings['TALKS_PATH'], '_templates')),
|
||||
autoescape=True,
|
||||
)
|
||||
env.filters['markdown'] = lambda text: \
|
||||
jinja2.Markup(markdown.Markdown(extensions=['meta']).
|
||||
convert(text))
|
||||
env.filters['dateformat'] = format_date
|
||||
env.filters['datetimeformat'] = format_datetime
|
||||
env.filters['timeformat'] = format_time
|
||||
return env
|
||||
|
||||
|
||||
class TalkListDirective(Directive):
|
||||
|
@ -175,7 +179,7 @@ class TalkListDirective(Directive):
|
|||
|
||||
def run(self):
|
||||
lang = self.options.get('lang', 'C')
|
||||
tmpl = jinja_env.get_template('talk.html')
|
||||
tmpl = jinja_env().get_template('talk.html')
|
||||
return [
|
||||
nodes.raw('', tmpl.render(lang=lang, **get_talk_data(n)),
|
||||
format='html')
|
||||
|
@ -193,7 +197,7 @@ class TalkDirective(Directive):
|
|||
|
||||
def run(self):
|
||||
lang = self.options.get('lang', 'C')
|
||||
tmpl = jinja_env.get_template('talk.html')
|
||||
tmpl = jinja_env().get_template('talk.html')
|
||||
data = get_talk_data(self.arguments[0])
|
||||
if data is None:
|
||||
return []
|
||||
|
@ -213,9 +217,10 @@ class TalkGridDirective(Directive):
|
|||
|
||||
def run(self):
|
||||
lang = self.options.get('lang', 'C')
|
||||
tmpl = jinja_env.get_template('grid.html')
|
||||
tmpl = jinja_env().get_template('grid.html')
|
||||
output = []
|
||||
days = unique_attr(all_talks(), 'day')
|
||||
gridstep = pelican.settings['TALKS_GRID_STEP']
|
||||
for day in sorted(days):
|
||||
talks = {talk['id'] for talk in all_talks()
|
||||
if talk.get('day', None) == day
|
||||
|
@ -231,18 +236,18 @@ class TalkGridDirective(Directive):
|
|||
del rooms[rooms.index('*')]
|
||||
mintime = min({talk['time'].hour * 60 +
|
||||
talk['time'].minute
|
||||
for talk in talks}) // GRID_STEP * GRID_STEP
|
||||
for talk in talks}) // gridstep * gridstep
|
||||
maxtime = max({talk['time'].hour * 60 +
|
||||
talk['time'].minute +
|
||||
talk['duration']
|
||||
for talk in talks})
|
||||
times = {}
|
||||
|
||||
for t in range(mintime, maxtime, GRID_STEP):
|
||||
for t in range(mintime, maxtime, gridstep):
|
||||
times[t] = [None] * len(rooms)
|
||||
for talk in sorted(talks, key=lambda x: x['time']):
|
||||
talktime = talk['time'].hour * 60 + talk['time'].minute
|
||||
position = talktime // GRID_STEP * GRID_STEP # round
|
||||
position = talktime // gridstep * gridstep # round
|
||||
assert position in times
|
||||
if talk['room'] == '*':
|
||||
roomnums = range(len(rooms))
|
||||
|
@ -258,14 +263,14 @@ class TalkGridDirective(Directive):
|
|||
continue
|
||||
times[position][roomnum] = copy(talk)
|
||||
times[position][roomnum]['skip'] = False
|
||||
for i in range(1, talk['duration'] // GRID_STEP):
|
||||
times[position + i*GRID_STEP][roomnum] = copy(talk)
|
||||
times[position + i*GRID_STEP][roomnum]['skip'] = True
|
||||
for i in range(1, talk['duration'] // gridstep):
|
||||
times[position + i*gridstep][roomnum] = copy(talk)
|
||||
times[position + i*gridstep][roomnum]['skip'] = True
|
||||
|
||||
render = tmpl.render(times=times,
|
||||
rooms=rooms,
|
||||
mintime=mintime, maxtime=maxtime,
|
||||
timestep=GRID_STEP,
|
||||
timestep=gridstep,
|
||||
lang=lang,
|
||||
)
|
||||
output.append(nodes.raw(
|
||||
|
@ -321,25 +326,33 @@ 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_PATH, talkname,
|
||||
TALK_ATTACHMENT_PATH)
|
||||
outdir = os.path.join(self.output_path,
|
||||
pelican.settings['TALKS_PATH'], talkname,
|
||||
pelican.settings['TALKS_ATTACHMENT_PATH'])
|
||||
if os.path.isdir(outdir):
|
||||
shutil.rmtree(outdir)
|
||||
shutil.copytree(self.talks[talkname]['resources'], outdir)
|
||||
with io.open(os.path.join(self.output_path, TALK_ICS),
|
||||
with io.open(os.path.join(self.output_path, pelican.settings.get('TALKS_ICS')),
|
||||
'w',
|
||||
encoding='utf8') as buf:
|
||||
buf.write(talks_to_ics())
|
||||
|
||||
|
||||
def add_talks_option_defaults(pelican):
|
||||
pelican.settings.setdefault('TALKS_PATH', TALKS_PATH)
|
||||
pelican.settings.setdefault('TALKS_PATH', 'talks')
|
||||
pelican.settings.setdefault('TALKS_ATTACHMENT_PATH', 'res')
|
||||
pelican.settings.setdefault('TALKS_ICS', 'schedule.ics')
|
||||
pelican.settings.setdefault('TALKS_GRID_STEP', 30)
|
||||
|
||||
|
||||
def get_generators(gen):
|
||||
return TalksGenerator
|
||||
|
||||
|
||||
def pelican_init(pelicanobj):
|
||||
global pelican
|
||||
pelican = pelicanobj
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
|
@ -350,6 +363,7 @@ except ImportError:
|
|||
else:
|
||||
|
||||
def register():
|
||||
signals.initialized.connect(pelican_init)
|
||||
signals.get_generators.connect(get_generators)
|
||||
signals.initialized.connect(add_talks_option_defaults)
|
||||
directives.register_directive('talklist', TalkListDirective)
|
||||
|
|
|
@ -12,6 +12,7 @@ from pelicanconf import *
|
|||
|
||||
SITEURL = '/hackit17'
|
||||
RELATIVE_URLS = True
|
||||
TALKS_GRID_STEP = 30
|
||||
|
||||
# DELETE_OUTPUT_DIRECTORY = True
|
||||
|
||||
|
|
Loading…
Reference in a new issue