Newer
Older
Handbook / calendar / generate_dates / app.py
import argparse
import copy
import pathlib
import sys

from generate_dates import TeachingCalendar, config, templates
from generate_dates.config import parse_command_line


class PeriodError(KeyError):
    pass

class PaperError(KeyError):
    pass

class LectureStyleError(KeyError):
    pass


def parse_config(config, args):
    """Validate and filter the top-level configuration.

    Returns separate references to the period configuration and the
    paper configuration, as applicable. (Yes, the period configuration
    includes the paper configuration, but it may also include other
    papers, so it's more convenient to return a separate reference
    for the specified paper.)

    The configuration file will normally contain specifications for
    several teaching periods and papers. We don't need all of this:
    usually we're only interested in one teaching period and one
    paper (if relevant).
    """
    period_config = paper_config = None
    # this is all irrelevant if we're going ISO style
    if args.style != "iso":
        if args.period not in config.keys():
            raise PeriodError()

        period_config = config[args.period]
        # raises KeyError if source key is missing
        period_config["name"] and period_config["weeks"]

        # papers are irrelevant in "calendar" style
        if args.style == "lecture":
            if "papers" in period_config.keys():
                if args.paper in period_config["papers"].keys():
                    paper_config = period_config["papers"][args.paper]
                    # we expect at least a "lectures" entry
                    paper_config["lectures"]
                else:
                    raise PaperError()
            else:
                raise LectureStyleError()
    
    return period_config, paper_config


def run():
    args = parse_command_line()
    if args.debug:
        print("DEBUG: args: {0}".format(args))

    try:
        period_config, paper_config = parse_config(args.config, args)
        if args.debug:
            print("DEBUG: period config: {0}".format(period_config))
            print("DEBUG: paper config: {0}".format(paper_config))
        # priority: year on command line (defaults to current year),
        # year in config
        if period_config:
            args.year = (
                args.config["year"] if "year" in args.config.keys()
                else args.year)
        cal = TeachingCalendar.TeachingCalendar(
            args.year, args.period, args.paper,
            period_config, paper_config)
        print("Period = {p}".format(p=args.period))
        print(cal.calendar())
        print(cal.lecture_dates())
    except LectureStyleError as e:
        print("ERROR: 'lecture' style was requested but {c} contains no "
            "papers for {t}.".format(c=args.config, t=args.period))
    except PaperError as e:
        print("ERROR: no entry in {c} for paper {p} ({t}).".format(
            c=args.config, p=args.paper, t=args.period))
    except PeriodError as e:
        print("ERROR: no entry in {c} for teaching period "
            "{p}.".format(c=args.config_file, p=args.period))
    except KeyError as e:
        print("ERROR: teaching period {p} in {c} is missing required "
            "key {k}.".format(p=args.period, c=args.config, k=e))