lpschedule-generator

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

commit 70126d67549ad060ab8f01cab6fabf31516bcf01
parent 0c4dad844c1bacc5d4fcd78ec46239654d576617
Author: rsiddharth <rsd@gnu.org>
Date:   Sat, 13 Feb 2016 18:54:22 -0500

Autolinking of speakers in sessions page ready.

If "John Hacker" is the speaker that has to be autolinked in the
sessions MD file; the markup to autolink is [John Hacker]().

[John Hacker]() -> <a href="speakers.html#hacker">John Hacker</a>, if id
for "John Hacker" is available in the `speaker.ids` file[1].

[1]: The `speakers.ids` file is automatically written to the disk (in
the current working directory) when the speakers' bio page is generated.

List of speakers that are autolinked but don't have an id, are written
to the `speakers.noid` file when the sessions page is generated.

Addresses issue #7.

Diffstat:
lps_gen.py | 57++++++++++++++++++++++++++++++++++++++++++++++++++++++---
tests/test_lps_gen.py | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 263 insertions(+), 7 deletions(-)

diff --git a/lps_gen.py b/lps_gen.py @@ -117,6 +117,51 @@ class LPSRenderer(Renderer): # "room" and session "description". self.no_paragraph = None + # Contains a list of speakers' names which are marked up for + # auto-linking[1], but don't have an id to link to. + # + # [1]: Markup for auto-linking speakers is [John Hacker](). + self.speakers_noids = [] + + # If it is 'False', then the 'speaker.ids' file was not found; + # otherwise it is an OrderedDict containing the mapping of + # speakers and their corresponding id. + self.speakers_ids = json_read('speakers.ids') + + + def get_uid(self, speaker): + """Returns unique id for `speaker` if it exists; `False` otherwise. + """ + if not self.speakers_ids: + # There is no speakers_ids OrderedDict available. + return False + + speaker = unicode(speaker) + if speaker in self.speakers_ids.keys(): + return self.speakers_ids[speaker] + else: + # speaker not found in speakers_ids OrderedDict. + return False + + + def link(self, link, title, text): + # Here, we catch speaker names that have to be autolinked and + # autolink them if there is an id available for the speaker. + if not link: + # We found a speaker that has to be autolinked. + + # Here, `text` is the speaker' name. + id_ = self.get_uid(text) + if id_: + link = 'speakers.html#%s' % id_ + else: + # Oh no, there is no id for this speaker. + self.speakers_noids.append(text) + # Don't linkify this speaker; they don't have an id. + return text + + return super(LPSRenderer, self).link(link, title, text) + def header(self, text, level, raw=None): global lps_dict @@ -261,9 +306,11 @@ class LPSMarkdown(Markdown): """ Initialize with LPSRenderer as the renderer. """ - super(LPSMarkdown, self).__init__(renderer=LPSRenderer(), - inline=None, block=None, - **kwargs) + self.sessions_renderer = LPSRenderer() + super(LPSMarkdown, self).__init__( + renderer=self.sessions_renderer, + inline=None, block=None, + **kwargs) def parse(self, text): @@ -271,6 +318,10 @@ class LPSMarkdown(Markdown): lps_dict = OrderedDict() html = super(LPSMarkdown, self).parse(text) + + # Write list of speakers with no ids to `speakers.noids`. + json_write('speakers.noids', self.sessions_renderer.speakers_noids) + return lps_dict diff --git a/tests/test_lps_gen.py b/tests/test_lps_gen.py @@ -118,10 +118,14 @@ class TestLPS(object): def setup_class(self): """Runs before running any tests in this class.""" - self.MD_FILE = path.join('tests', 'files', 'lp-sch.md') + # Change current working directory to the tests directory. + self.old_cwd = os.getcwd() + os.chdir('tests') + + self.MD_FILE = path.join('files', 'lp-sch.md') self.MD_FILE_CONTENT = read_file(self.MD_FILE) - self.SCH_TEMPLATE = path.join('tests', 'files', + self.SCH_TEMPLATE = path.join('files', 'lp-sch-2016.jinja2') self.markdown = LPSMarkdown() @@ -275,9 +279,14 @@ class TestLPS(object): @classmethod def teardown_class(self): - """Purge the mess created by this test.""" - pass + """Clean up the mess created by this test.""" + + # Remove `speakers.noids` file if it exists. + if path.isfile('speakers.noids'): + os.remove('speakers.noids') + # Change back to the old cwd + os.chdir(self.old_cwd) class TestLPSpeakers(object): """ @@ -549,3 +558,199 @@ class TestLPSpeakers(object): # Change back to the old cwd os.chdir(self.old_cwd) + + +class TestSpeakersAutoLinking(object): + """Class tests autolinking of speakers in sessions MD. + """ + @classmethod + def setup_class(self): + """Runs before running any tests in this class.""" + + # Change current working directory to the tests directory. + self.old_cwd = os.getcwd() + os.chdir('tests') + + self.ids_filename = 'speakers.ids' + self.noids_filename = 'speakers.noids' + + self.SPEAKERS_MD = path.join('files', 'lp-speakers-autolink.md') + self.SPEAKERS_MD_CONTENT = read_file(self.SPEAKERS_MD) + self.SPEAKERS_TEMPLATE = path.join('files', + 'lp-speakers-2016.jinja2') + + self.SESSIONS_MD = path.join('files', 'lp-sessions-autolink.md') + self.SESSIONS_MD_CONTENT = read_file(self.SESSIONS_MD) + self.SESSIONS_TEMPLATE = path.join('files', + 'lp-sch-2016.jinja2') + + + def setup(self): + """Runs before each test in this class.""" + pass + + + def test_sessions_autolinking(self): + """Testing autolinking of speakers in sessions. """ + self.speakers_markdown = LPSpeakersMarkdown() + self.lpspeakers_dict = self.speakers_markdown( + self.SPEAKERS_MD_CONTENT) + + assert (path.isfile(self.ids_filename) and + json.loads(read_file(self.ids_filename))) + + self.sessions_markdown = LPSMarkdown() + self.lps_dict = self.sessions_markdown(self.SESSIONS_MD_CONTENT) + + assert (path.isfile(self.noids_filename) and + json.loads(read_file(self.noids_filename))) + + speakers = [ + [ + '<a href="speakers.html#snowden">Edward Snowden</a>', + '<a href="speakers.html#gillmor">Daniel Kahn Gillmor</a>', + ], + [ + '<a href="speakers.html#nicholson">Deb Nicholson</a>', + '<a href="speakers.html#fontana">Richard Fontana</a>', + ], + [ + 'Paige Peterson', 'MaidSoft' + ], + [ + 'George Chriss', + 'Kat Walsh (moderator)', + ], + [ + '<a href="speakers.html#zacchiroli">Stefano Zacchiroli</a>', + 'Debian', 'OSI', 'IRILL' + ], + [ + '<a href="speakers.html#corvellec">Marianne Corvellec</a>', + 'April and Jonathan Le Lous', + 'April' + ], + [ + '<a href="speakers.html#brown">Michaela R. Brown</a>', + ], + [ + '<a href="speakers.html#gott">Molly Gott</a>' + ], + [ + 'Christopher Webber', + '<a href="speakers.html#thompson">David Thompson</a>', + 'Ludovic Courtès', + ], + ] + + i = 0 + for lps_timeslots in self.lps_dict.values(): + for lps_sessions in lps_timeslots.values(): + for session_info in lps_sessions.values(): + assert_equal(session_info['speakers'], speakers[i]) + i = i + 1 + + speakers_noids = [ + 'Paige Peterson', + 'George Chriss', + 'Kat Walsh', + 'Jonathan Le Lous', + 'Christopher Webber', + 'Ludovic Courtès', + ] + assert_equal(json_read(self.noids_filename), speakers_noids) + + + def test_sessions_autolinking_nospeakerids(self): + """Testing autolinked speakrs in sessions MD when speakers.id not available. """ + + assert not path.isfile(self.ids_filename) + + self.sessions_markdown = LPSMarkdown() + self.lps_dict = self.sessions_markdown(self.SESSIONS_MD_CONTENT) + + assert (path.isfile(self.noids_filename) and + json.loads(read_file(self.noids_filename))) + + speakers = [ + [ + 'Edward Snowden', + 'Daniel Kahn Gillmor', + ], + [ + 'Deb Nicholson', + 'Richard Fontana', + ], + [ + 'Paige Peterson', 'MaidSoft' + ], + [ + 'George Chriss', + 'Kat Walsh (moderator)', + ], + [ + 'Stefano Zacchiroli', + 'Debian', 'OSI', 'IRILL' + ], + [ + 'Marianne Corvellec', + 'April and Jonathan Le Lous', + 'April' + ], + [ + 'Michaela R. Brown', + ], + [ + 'Molly Gott' + ], + [ + 'Christopher Webber', + 'David Thompson', + 'Ludovic Courtès', + ], + ] + + i = 0 + for lps_timeslots in self.lps_dict.values(): + for lps_sessions in lps_timeslots.values(): + for session_info in lps_sessions.values(): + assert_equal(session_info['speakers'], speakers[i]) + i = i + 1 + + speakers_noids = [ + 'Edward Snowden', + 'Daniel Kahn Gillmor', + 'Deb Nicholson', + 'Richard Fontana', + 'Paige Peterson', + 'George Chriss', + 'Kat Walsh', + 'Stefano Zacchiroli', + 'Marianne Corvellec', + 'Jonathan Le Lous', + 'Michaela R. Brown', + 'Molly Gott', + 'Christopher Webber', + 'David Thompson', + 'Ludovic Courtès', + ] + + assert_equal(json_read(self.noids_filename), speakers_noids) + + + def teardown(self): + """Cleans up things after each test in this class.""" + # Remove `speakers.ids` file if it exists. + if path.isfile(self.ids_filename): + os.remove(self.ids_filename) + + # Remove `speakers.noids` file if it exists. + if path.isfile(self.noids_filename): + os.remove(self.noids_filename) + + + @classmethod + def teardown_class(self): + """Clean up the mess created by this test class""" + # Change back to the old cwd + os.chdir(self.old_cwd)