# L-24 MCS 507 Mon 16 Oct 2023 : courselistings.py
"""
Prompts the user for a subject, year, and semester.
Then connects to the web site that archives course offerings.

This runs with version 3.5 of Python.
Later version complain about the certificate of the web site ...

Exploits that names of courses are attributes
of 'a' tags and that course titles are following in 'b' tags.

The format of the archived data changed since 2020 ...
"""

import ssl

# To browse sites that have no certificates 
context = ssl._create_unverified_context()
# urllib.urlopen("https://no-valid-cert", context=context)

from html.parser import HTMLParser
from urllib.request import urlopen

# the office of student systems services site
# OSSS = 'http://osss.uic.edu/ims/classschedule/'
OSSS = 'https://webcs7.osss.uic.edu/schedule-of-classes/archive/pre-proof/'

class Courses(HTMLParser):
    """
    Shows attributes for 'a' tags
    and makes a tally of ending tags.
    """
    def __init__(self, sub):
        """
        Initializes for the subject sub.
        """
        HTMLParser.__init__(self)
        self.courses = []
        self.titles = []
        self.isbold = True
        self.readtitle = 0
        self.subject = sub

    def handle_starttag(self, tag, attrs):
        """
        Looks for tags equal to 'a' and
        stores MCS courses.
        """
        if tag == 'a':
            A = [y for (x, y) in attrs]
            n = len(self.subject)
            L = [x for x in A if len(x) >= n]
            F = [x for x in L if x[:n] == self.subject]
            self.courses = self.courses + F
            if len(F) > 0:
                self.readtitle = 1
        elif tag == 'b':
            self.isbold = True
            if self.readtitle > 0:
                self.readtitle = self.readtitle + 1

    def handle_endtag(self, tag):
        """
        Flips off the isbold if tag is 'b'.
        """
        if tag == 'b':
            self.isbold = False

    def add_title(self, title):
        """
        Adds a course title to the list.
        """
        self.titles.append(title)

def update_title(s, p, d):
    """
    Updates the title string.
    """
    if p.isbold and p.readtitle == 3:
        s = s + d
    else:
        if s != '':
            p.add_title(s[1:-3])
            s = ''
    return s

def course_list(page, subject):
    """
    Opens the page and lists all courses
    with the given subject.
    """
    f = urlopen(page, context=context)
    p = Courses(subject)
    s = ''
    while True:
        data = f.read(1).decode()
        if data == '':
            break
        p.feed(data)
        s = update_title(s, p, data)
    return (p.courses, p.titles)

def schedulepage():
    """
    Prompts the user for subject and term.
    Returns the page where to look.
    """
    subject = input('Give a subject : ').upper()
    year = input('Give the year (4 digits) : ')
    sem = input('Spring, Fall, or Summer (0, 1, or 2) : ')
    term = ('spring' if sem == '0' else ('fall' if sem == '1' else 'summer'))
    term = term + '-' + year
    if int(year) < 2020:
        page = OSSS + term + '/' + subject + '.htm'
    else:
        page = OSSS + term + '/' + subject + '.html'
    return (page, subject)

def main():
    """
    Opens a web page and parses it.
    """
    (page, subject) = schedulepage()
    print('opening %s ...' % page)
    courses, titles = course_list(page, subject)
    print('courses on ' + page + ' :')
    for course, title in zip(courses, titles):
        print(course, title)

if __name__ == "__main__":
    main()
