""" 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()