"""
Generates an HTML file for each Session of CSSE 120.
The file contains instructions for students to do:
-- Preparation Videos and Reading and associated Quizzes in Moodle
-- A Start-the-Session quiz (and self-check answers and turn it in in Moodle)
-- Follow-Me videos
Author: David Mutchler and his colleagues.
"""
from Constants import * # All constants, and only constants, are in ALL_CAPS.
from TermInfo import TermInfo
from typing import List
class SessionTemplates:
def __init__(self):
with open(SESSION_TEMPLATE, "r") as file_handle:
self.session_template = file_handle.read()
with open(NAVIGATION_BAR_TEMPLATE, "r") as file_handle:
self.navigation_bar = file_handle.read()
self.navigation_bar = self.navigation_bar.replace(
'src="', 'src="../../').replace(
'href="', 'href="../../').replace(
"../../http", "http")
with open(SESSION_SECTION_VIDEOS_READING_TEMPLATE, "r") as file_handle:
self.videos_reading_template = file_handle.read()
with open(SESSION_SECTION_QUIZ_TEMPLATE, "r") as file_handle:
self.quiz_template = file_handle.read()
with open(SESSION_SECTION_FOLLOW_ME_TEMPLATE, "r") as file_handle:
self.follow_me_template = file_handle.read()
with open(FOOTER_TEMPLATE, "r") as file_handle:
self.footer = file_handle.read()
with open(SESSION_ITEM_VIDEO_TEMPLATE, "r") as file_handle:
self.item_video_template = file_handle.read()
with open(SESSION_ITEM_READING_TEMPLATE, "r") as file_handle:
self.item_reading_template = file_handle.read()
with open(SESSION_ITEM_OTHER_TEMPLATE, "r") as file_handle:
self.item_other_template = file_handle.read()
class SessionPageItem:
def __init__(self, data: str, templates: SessionTemplates):
self.data = data
self.lines = data.split("\n")
print("Lines:")
print(self.lines)
if self.lines[0] == "": # CONSIDER: fix this more elegantly??
self.lines = self.lines[1:]
self.item_type = self.lines[0]
self.title = self.lines[1]
self.url = ""
self.minutes = ""
self.note = []
if self.item_type == "VIDEO":
self.url = self.lines[2]
self.minutes = self.lines[3]
note_starts_at = 4
self.template = templates.item_video_template
elif self.item_type == "READING":
self.url = self.lines[2]
note_starts_at = 3
self.template = templates.item_reading_template
elif self.item_type == "OTHER":
note_starts_at = 2
self.template = templates.item_other_template
elif self.item_type == "EXAM": # FIXME
note_starts_at = 2 # FIXME
self.template = templates.item_other_template # FIXME
else:
message = "Bad data in an item for a session page: {}"
raise ValueError(message.format(data))
self.note = self.lines[note_starts_at:]
def make_html(self):
note_string = self.make_html_for_note()
html = self.template.replace(
"__TITLE__", self.title).replace(
"__URL__", self.url).replace(
"__MINUTES__", self.minutes).replace(
"__NOTE__", note_string)
lines = html.split("\n")
html = ""
for line in lines:
html += " " + line + "\n"
return html
def make_html_for_note(self) -> str:
note_string = ""
inside_note = False
for line in self.note:
if line == "":
if inside_note:
note_string += " \n"
inside_note = False
else:
pass # Extra blank line, ignore it
else:
if not inside_note:
inside_note = True
note_string += "
\n"
note_string += " " + line + "\n"
# if inside_note:
# note_string += " \n"
return note_string
class SessionSection:
def __init__(self, data: str, templates: SessionTemplates,
section_type: SessionSectionType):
self.data = data
self.templates = templates
self.section_type = section_type
if not data:
self.raw_items = []
else:
self.raw_items = self.data.split("---")
self.items = []
for k in range(len(self.raw_items)):
if self.raw_items[k].replace("\n", "") == "": # Just empty lines
continue
self.items.append(SessionPageItem(self.raw_items[k],
self.templates))
def make_html(self) -> str:
""" Returns the HTML for this SessionSection on a Session page. """
if self.section_type == SessionSectionType.VIDEOS_READING:
template = self.templates.videos_reading_template
elif self.section_type == SessionSectionType.QUIZ:
template = self.templates.quiz_template
elif self.section_type == SessionSectionType.FOLLOW_ME:
template = self.templates.follow_me_template
else:
raise ValueError("Bad SessionSectionType: {}".format(
self.section_type))
html = ""
for item in self.items:
html = html + item.make_html() # FIXME to add spaces
return template.replace(" __SESSION_SECTION_ITEMS__", html) #
# FIXME
class SessionPage:
def __init__(self, session_number: int,
term_info: TermInfo,
session_templates: SessionTemplates):
self.session_number = session_number
self.term_info = term_info
self.templates = session_templates
if self.session_number < 10:
self.session_number_string = "0{}".format(session_number)
else:
self.session_number_string = "{}".format(session_number)
self.session_folder = "{}/Session{}".format(
SESSIONS_FOLDER, self.session_number_string)
self.filename = "{}/index.html".format(self.session_folder)
processed_lines = [[], [], []]
# for filename in (SESSION_VIDEOS_READING_FILENAME,
# SESSION_QUIZ_FILENAME,
# SESSION_FOLLOW_ME_FILENAME):
# full_filename = "{}/{}".format(self.session_folder, filename)
# with open(full_filename, "r") as file_handle:
# lines = file_handle.readlines()
# processed_lines.append(
# self.strip_comments(self.handle_line_continuations(lines)))
self.videos_reading_data = "".join(processed_lines[0])
self.quiz_data = "".join(processed_lines[1])
self.follow_me_data = "".join(processed_lines[2])
self.videos_reading = SessionSection(self.videos_reading_data,
self.templates,
SessionSectionType.VIDEOS_READING)
self.quiz = SessionSection(self.quiz_data,
self.templates,
SessionSectionType.QUIZ)
self.follow_me = SessionSection(self.follow_me_data,
self.templates,
SessionSectionType.FOLLOW_ME)
@staticmethod
def strip_comments(lines: List[str]) -> List[str]:
non_comment_lines = []
for line in lines:
if len(line) > 0 and line[0] == "#":
continue
non_comment_lines.append(line)
return non_comment_lines
@staticmethod
def handle_line_continuations(lines: List[str]) -> List[str]:
print("lines =", lines)
lines_after_continuations = []
in_continuation = False
continuation_line = ""
for line in lines:
if in_continuation:
continuation_line = continuation_line + line
print("in continuation:", continuation_line)
else:
continuation_line = line
in_continuation = (len(continuation_line) > 1
and continuation_line[-2] == "\\")
if in_continuation:
continuation_line = continuation_line[:-2]
print("in continuation again:", continuation_line)
else:
lines_after_continuations.append(continuation_line)
# Assumes that the last line does NOT end with \
return lines_after_continuations
def make_html(self) -> str:
videos_reading = self.videos_reading.make_html()
quiz = self.quiz.make_html()
follow_me = self.follow_me.make_html()
return self.templates.session_template.replace(
"__NAVIGATION_BAR__", self.templates.navigation_bar).replace(
"__VIDEOS_READING_SECTION__", videos_reading).replace(
"__QUIZ_SECTION__", quiz).replace(
"__FOLLOW_ME_SECTION__", follow_me).replace(
"__FOOTER__", self.templates.footer).replace(
"TERM_AND_YEAR", self.term_info.term_and_year).replace(
"TERM_PER_BANNER", self.term_info.banner_term).replace(
"__PIAZZA_URL__", self.term_info.piazza_url).replace(
"__QUIZ_NUMBER__", self.session_number_string).replace(
"__SESSION_NUMBER__", str(self.session_number)).replace(
"../../http", "http")
class SessionPagesMaker:
""" Generates the HTML for a CSSE 120 Session. """
def __init__(self, banner_term: str):
"""
The parameter banner_term should be a string like 202110
(for the fall term of the 2020-21 academic year).
"""
self.term_info = TermInfo(banner_term)
self.templates = SessionTemplates()
self.session_pages = []
for k in range(NUMBER_OF_SESSIONS):
session_page = SessionPage(k + 1, self.term_info, self.templates)
self.session_pages.append(session_page)
def print_html(self, session_index: int):
session_page = self.session_pages[session_index]
print(session_page)
print(session_page.make_html())
def write_html_files(self):
for k in range(NUMBER_OF_SESSIONS):
session_page = self.session_pages[k]
print("Writing {}".format(session_page.filename))
with open(session_page.filename, "w") as file_handle:
file_handle.write(session_page.make_html())
def main():
""" Make the HTML for the CSSE 120 HomePage for the indicated term. """
maker = SessionPagesMaker(TERM)
maker.write_html_files()
# ----------------------------------------------------------------------
# If this module is running at the top level (as opposed to being
# imported by another module), then call the 'main' function.
# ----------------------------------------------------------------------
if __name__ == '__main__':
main()