diff --git a/plugins/talks.py b/plugins/talks.py index 61ef8a5..b59f31f 100644 --- a/plugins/talks.py +++ b/plugins/talks.py @@ -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) diff --git a/publishconf.py b/publishconf.py index 7f0369c..b739a76 100644 --- a/publishconf.py +++ b/publishconf.py @@ -12,6 +12,7 @@ from pelicanconf import * SITEURL = '/hackit17' RELATIVE_URLS = True +TALKS_GRID_STEP = 30 # DELETE_OUTPUT_DIRECTORY = True