lpschedule-generator

libreplanet schedule generator - ricketyspace.net/lpschedule-generator
git clone git://git.ricketyspace.net/lpschedule-generator.git
Log | Files | Refs

commit 77aa5dad923f4efad2e271ca3f38a7585ab2680b
parent 7ca74c9b9470b8773358f22b011136e5579237f6
Author: rsiddharth <rsd@gnu.org>
Date:   Thu, 28 Jan 2016 08:39:17 -0500

lps_gen accepts template as arg.

As per Zak's request, the script now requires the user to pass the
template as (the first) argument to the script.

The script does not use the template that is part of the
lpschedule-generator module; indeed the internal template will be
deleted later.

Diffstat:
README.rst | 7+------
lps_gen.py | 31+++++++++++++++----------------
tests/files/lp-sch-2016.jinja2 | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tests/test_lps_gen.py | 12+++++++-----
4 files changed, 140 insertions(+), 27 deletions(-)

diff --git a/README.rst b/README.rst @@ -47,12 +47,7 @@ Usage :: - $ lps_gen YEAR path/to/lp-sch.md > path/to/program-schedule.html - -Replace ``YEAR`` with LP year; for example, for generating LP 2016 -schedule, the command will be:: - - $ lps_gen 2016 path/to/lp-sch.md > path/to/program-schedule.html + $ lps_gen path/to/lp-sch.jinja2 path/to/lp-sch.md > path/to/program-schedule.html LP schedule markdown structure diff --git a/lps_gen.py b/lps_gen.py @@ -26,7 +26,7 @@ from collections import OrderedDict from os import path from bs4 import BeautifulSoup -from jinja2 import Environment, PackageLoader +from jinja2 import Environment, FileSystemLoader from jinja2.exceptions import TemplateNotFound from mistune import Renderer, Markdown @@ -144,16 +144,15 @@ class LPSMarkdown(Markdown): return lps_dict -def RenderHTML(lps_dict, year): +def RenderHTML(lps_dict, template): """Renders LP schedule in HTML from a python dictionary. Returns the HTML as a string. """ - env = Environment(loader=PackageLoader('lpschedule_generator', - 'templates'), + env = Environment(loader=FileSystemLoader(path.dirname(template)), trim_blocks=True, lstrip_blocks=True) - template_name = 'lp-sch-%s.jinja2' % year + template_name = path.basename(template) template = None try: @@ -172,25 +171,25 @@ def main(): parser.add_argument("--version", action="version", version='lpschedule-generator version %s' % __version__, help="Show version number and exit.") - parser.add_argument("year", - help="LP Schedule year.") - parser.add_argument("lps_md", - help="Path to the markdown version of LP Schedule.") + parser.add_argument("lp_t", + help="Path to the LP template.") + parser.add_argument("lp_md", + help="Path to the LP markdown.") args = parser.parse_args() - lps_md_content = read_file(path.abspath(args.lps_md)) - lp_year = args.year + lp_template = args.lp_t + lp_md_content = read_file(path.abspath(args.lp_md)) - if lps_md_content: + if path.exists(lp_template) and lp_md_content: markdown = LPSMarkdown() - lps_dict = markdown(lps_md_content) - lps_html = RenderHTML(lps_dict, lp_year) + lp_dict = markdown(lp_md_content) + lp_html = RenderHTML(lp_dict, lp_template) else: exit(1) - if lps_html: + if lp_html: # stdout lps html - print lps_html + print lp_html else: print 'Error generating LP HTML.' diff --git a/tests/files/lp-sch-2016.jinja2 b/tests/files/lp-sch-2016.jinja2 @@ -0,0 +1,117 @@ +{# -*- mode: jinja2; -*- #} +{# + Copyright (C) 2015 lpschedule-generator contributors. See CONTRIBUTORS. + + This file is part of lpschedule-generator. + + lpschedule-generator is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License + as published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + lpschedule-generator is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with lpschedule-generator (see COPYING). If not, see + <http://www.gnu.org/licenses/>. +#} + +{# macros start #} + +{# make speakers macro #} +{% macro mk_speakers(speakers) %} + <span class="program-session-speaker"> + {% for speaker in speakers %} + {% if loop.last %} + {{ speaker }} + {% else %} + {{ speaker }}, + {% endif %} + {% endfor %} + </span> +{% endmacro %} + +{# make room macro #} +{% macro mk_room(room) %} + <span class="label label-default">{{ room }}</span> +{% endmacro %} + +{# make day header macro #} +{% macro mk_day_header(day, collapse_area) %} + <header class="program-day-header"> + <hgroup> + <h2>{{ day }}</h2> + </hgroup> + </header> +{% endmacro %} + +{# make timeslot header macro #} +{% macro mk_timeslot_header(timeslot, collapse, collapse_area='') %} + <header class="program-timeslot-header"> + <hgroup> + <h2>{{ timeslot }}</h2> + </hgroup> + </header> +{% endmacro %} + +{# make session header macro #} +{% macro mk_session_header(session) %} + <header class="program-session-header"> + <hgroup> + <h2>{{ session }}</h2> + </hgroup> + </header> +{% endmacro %} + +{# desc macro #} +{% macro desc(disc_list) %} + {% for desc_p in disc_list %} + <p>{{ desc_p }}</p> + {% endfor %} +{% endmacro %} + +{# populate sessions macro #} +{% macro populate_sessions(sessions, day_index, timeslot_index) %} + {% for session, session_info in sessions.iteritems() %} {# session start #} + <section id="day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }}" class="program-session"> + {{ mk_session_header(session) }} + {{ mk_speakers(session_info['speakers']) }} + <p class="program-session-room-details"> + {{ mk_room(session_info['room']) }} + <button class="btn btn-default btn-xs" + data-toggle="collapse" aria-expanded="false" + aria-controls="day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }}-collapse" + data-target="#day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }}-collapse"> + Details + </button> + </p> + <div class="collapse in" + id="day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }}-collapse"> + {{ desc(session_info['desc']) }} + </div> <!-- day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }}-collapse end --> + </section> <!-- day-{{ day_index }}-timeslot-{{ timeslot_index }}-session-{{ loop.index }} end --> + {% endfor %} {# session end #} +{% endmacro %} + +{# populate timeslots macro #} +{% macro populate_timeslots(timeslots, day_index) %} + {% for timeslot, sessions in timeslots.iteritems() %} {# timeslot start #} + <article id="day-{{ day_index }}-timeslot-{{ loop.index }}" class="program-timeslot"> + {{ mk_timeslot_header(timeslot) }} + {% if sessions|length > 0 %} + {{ populate_sessions(sessions, day_index, loop.index) }} + {% endif %} + </article> <!-- day-{{ day_index }}-timeslot-{{ loop.index }} end --> + {% endfor %} {# timeslot start #} +{% endmacro %} + +{# lp 2016 template start #} +{% for day, timeslots in schedule.iteritems() %} {# day start #} + <article id="day-{{ loop.index }}-program" class="program-day"> + {{ mk_day_header(day) }} + {{ populate_timeslots(timeslots, loop.index) }} + </article> <!-- day-{{ loop.index }} end --> +{% endfor %} {# day loop end #} diff --git a/tests/test_lps_gen.py b/tests/test_lps_gen.py @@ -42,6 +42,9 @@ class TestLpsGen(object): self.MD_FILE = path.join('tests', 'files', 'lp-sch.md') self.MD_FILE_CONTENT = read_file(self.MD_FILE) + self.SCH_TEMPLATE = path.join('tests', 'files', + 'lp-sch-2016.jinja2') + self.markdown = LPSMarkdown() self.lps_dict = self.markdown(self.MD_FILE_CONTENT) @@ -160,19 +163,18 @@ class TestLpsGen(object): def test_RenderHTML(self): """Testing `RenderHTML` function """ - lps_html = RenderHTML(self.lps_dict, '2016') + lps_html = RenderHTML(self.lps_dict, self.SCH_TEMPLATE) print lps_html @raises(SystemExit) def test_RenderHTML_invalid_year(self): - """Testing `RenderHTML` function - with invalid year + """Testing `RenderHTML` function - with non-existent template """ with mock.patch('sys.stdout', new_callable=StringIO) as out: - invalid_year = '2016_invalid' - template_name = 'lp-sch-%s.jinja2' % invalid_year + nonexistent_template = 'lpsch-template.null' - lps_html = RenderHTML(self.lps_dict, invalid_year) + lps_html = RenderHTML(self.lps_dict, nonexistent_template) expected_out = 'Template %s not found.\n' % template_name assert out.getvalue() == expected_out