diff options
-rw-r--r-- | README.rst | 7 | ||||
-rw-r--r-- | lps_gen.py | 31 | ||||
-rw-r--r-- | tests/files/lp-sch-2016.jinja2 | 117 | ||||
-rw-r--r-- | tests/test_lps_gen.py | 12 |
4 files changed, 140 insertions, 27 deletions
@@ -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 @@ -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 new file mode 100644 index 0000000..f7cb0de --- /dev/null +++ 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 index e964a5a..a84ca78 100644 --- 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 |