university-setup/scripts/courses.py

92 lines
3.1 KiB
Python
Raw Permalink Normal View History

2019-09-15 20:42:11 +02:00
#!/usr/bin/python3
import warnings
2019-09-15 20:42:11 +02:00
2021-09-17 10:49:48 +02:00
import yaml
from typing import List
2021-09-17 10:49:48 +02:00
2021-09-16 13:28:51 +02:00
from config import ROOT, CURRENT_COURSE_ROOT, CURRENT_COURSE_SYMLINK, CURRENT_COURSE_WATCH_FILE, COURSE_IGNORE_FILE, \
COURSE_INFO_FILE_NAME, FALLBACK_COURSE_INFO_FILE
2021-09-17 10:49:48 +02:00
from notes import Notes
from links import Links
from utils import merge_dictionaries
from exercises import Exercises
2021-09-16 13:28:51 +02:00
class Course:
2019-09-15 20:42:11 +02:00
def __init__(self, path):
self.path = path
self.name = path.stem
if (path / COURSE_INFO_FILE_NAME).is_file():
self.info = yaml.safe_load((path / COURSE_INFO_FILE_NAME).open())
else:
warnings.warn(f"No course info file found in directory '{path.stem}'. Place a {COURSE_INFO_FILE_NAME} "
f"file in the directory or add the directory to the course ignore file named"
f" '{COURSE_IGNORE_FILE}' in your root directory ({ROOT})")
self.info = {'title': str(path.stem) + ' (unnamed course)'}
if FALLBACK_COURSE_INFO_FILE.is_file():
fallback_file = yaml.safe_load(FALLBACK_COURSE_INFO_FILE.open())
else:
warnings.warn(f"No fallback course info file found. Program might crash if your provided info files do not"
f"have the correct file format or are missing specified values. Provide the fallback course"
f"file at {FALLBACK_COURSE_INFO_FILE}.")
fallback_file = {}
self.info = merge_dictionaries(self.info, fallback_file)
2021-09-16 18:02:36 +02:00
self._notes = None
self._links = None
self._exercises = None
@property
def links(self) -> Links:
if not self._links:
self._links = Links(self)
return self._links
2019-09-15 20:42:11 +02:00
@property
def notes(self) -> Notes:
2021-09-16 18:02:36 +02:00
if not self._notes:
self._notes = Notes(self)
return self._notes
2019-09-15 20:42:11 +02:00
@property
def exercises(self) -> Exercises:
if not self._exercises:
self._exercises = Exercises(self)
return self._exercises
2019-09-15 20:42:11 +02:00
def __eq__(self, other):
2021-09-16 13:28:51 +02:00
if other is None:
2019-09-15 20:42:11 +02:00
return False
return self.path == other.path
2021-09-16 13:28:51 +02:00
def ignored_courses() -> List[Course]:
if (ROOT / COURSE_IGNORE_FILE).is_file():
with open(ROOT / COURSE_IGNORE_FILE) as ignore:
lines = ignore.readlines()
paths = []
for line in lines:
paths.append(ROOT / line.strip())
return paths
return []
2021-09-16 13:28:51 +02:00
def read_files() -> List[Course]:
2021-09-16 13:28:51 +02:00
course_directories = [x for x in ROOT.iterdir() if x.is_dir() and x not in ignored_courses()]
_courses = [Course(path) for path in course_directories]
return sorted(_courses, key=lambda c: c.name)
2019-09-15 20:42:11 +02:00
class Courses(list):
def __init__(self):
2021-09-16 13:28:51 +02:00
list.__init__(self, read_files())
2019-09-15 20:42:11 +02:00
@property
def current(self) -> Course:
2019-09-15 20:42:11 +02:00
return Course(CURRENT_COURSE_ROOT.resolve())
@current.setter
def current(self, course):
CURRENT_COURSE_SYMLINK.unlink()
CURRENT_COURSE_SYMLINK.symlink_to(course.path)
CURRENT_COURSE_WATCH_FILE.write_text('{}\n'.format(course.info['short']))