introduce script class

A course now does not handle its lectures directly, but has a
'script' property. The script essentially works as the course before,
except that some methods have been moved from the lectures class to the
script class as well.

This ensures further modulation of the course class, to introduce e.g.
an exercise class in the future that a course can also have.

Additionally, with this come further configurations in the info.yaml
file so that the script can have a different relative path from the
course, and the lectures a relative path from the script.
This commit is contained in:
Maximilian Keßler 2021-09-16 14:59:00 +02:00
parent b8c2f236a4
commit 13b4852051
3 changed files with 89 additions and 50 deletions

View file

@ -3,6 +3,7 @@ from pathlib import Path
import yaml import yaml
from lectures import Lectures from lectures import Lectures
from script import Script
from config import ROOT, CURRENT_COURSE_ROOT, CURRENT_COURSE_SYMLINK, CURRENT_COURSE_WATCH_FILE, COURSE_IGNORE_FILE, \ from config import ROOT, CURRENT_COURSE_ROOT, CURRENT_COURSE_SYMLINK, CURRENT_COURSE_WATCH_FILE, COURSE_IGNORE_FILE, \
COURSE_INFO_FILE COURSE_INFO_FILE
@ -13,13 +14,13 @@ class Course:
self.name = path.stem self.name = path.stem
self.info = yaml.safe_load((path / COURSE_INFO_FILE).open()) self.info = yaml.safe_load((path / COURSE_INFO_FILE).open())
self._lectures = None self._script = None
@property @property
def lectures(self): def script(self):
if not self._lectures: if not self._script:
self._lectures = Lectures(self) self._script = Script(self)
return self._lectures return self._script
def __eq__(self, other): def __eq__(self, other):
if other is None: if other is None:

View file

@ -54,13 +54,17 @@ class Lecture:
class Lectures(list): class Lectures(list):
def __init__(self, course): def __init__(self, script):
self.course = course self.course = script.course
self.root = course.path self.script = script
if 'master_file' in course.info: if 'lectures' in script.info:
self.master_file = self.root / course.info['master_file'] self.info = script.info['lectures']
else: else:
self.master_file = self.root / DEFAULT_MASTER_FILE_NAME self.info = []
if 'path' in self.info:
self.root = script.root / self.info['path']
else:
self.root = script.root
list.__init__(self, self.read_files()) list.__init__(self, self.read_files())
def read_files(self): def read_files(self):
@ -89,32 +93,6 @@ class Lectures(list):
return [self.parse_lecture_spec(arg)] return [self.parse_lecture_spec(arg)]
@staticmethod
def get_header_footer(filepath):
part = 0
header = ''
footer = ''
with filepath.open() as f:
for line in f:
# order of if-statements is important here!
if 'end lectures' in line:
part = 2
if part == 0:
header += line
if part == 2:
footer += line
if 'start lectures' in line:
part = 1
return header, footer
def update_lectures_in_master(self, r):
header, footer = self.get_header_footer(self.master_file)
body = ''.join(
' ' * 4 + r'\input{' + number2filename(number) + '}\n' for number in r)
self.master_file.write_text(header + body + footer)
def new_lecture(self): def new_lecture(self):
if len(self) != 0: if len(self) != 0:
new_lecture_number = self[-1].number + 1 new_lecture_number = self[-1].number + 1
@ -129,22 +107,9 @@ class Lectures(list):
new_lecture_path.touch() new_lecture_path.touch()
new_lecture_path.write_text(f'\\lecture{{{new_lecture_number}}}{{{date}}}{{}}\n') new_lecture_path.write_text(f'\\lecture{{{new_lecture_number}}}{{{date}}}{{}}\n')
if new_lecture_number == 1:
self.update_lectures_in_master([1])
else:
self.update_lectures_in_master([new_lecture_number - 1, new_lecture_number])
self.read_files() self.read_files()
lec = Lecture(new_lecture_path, self.course) lec = Lecture(new_lecture_path, self.course)
return lec return lec
def compile_master(self):
result = subprocess.run(
['latexmk', '-f', '-interaction=nonstopmode', str(self.master_file)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
cwd=str(self.root)
)
return result.returncode

73
scripts/script.py Normal file
View file

@ -0,0 +1,73 @@
#!/usr/bin/python3
from pathlib import Path
import subprocess
from lectures import Lectures, number2filename
from config import *
class Script:
def __init__(self, course):
self.course = course
if 'script' in course.info:
self.info = course.info['script']
else:
self.info = []
if 'path' in self.info:
self.root = course.path / self.info['path']
else:
self.root = course.path
if 'master_file' in self.info:
self.master_file = self.root / self.info['master_file']
else:
self.master_file = self.root / DEFAULT_MASTER_FILE_NAME
self._lectures = None
@staticmethod
def get_header_footer(filepath):
part = 0
header = ''
footer = ''
with filepath.open() as f:
for line in f:
# order of if-statements is important here!
if 'end lectures' in line:
part = 2
if part == 0:
header += line
if part == 2:
footer += line
if 'start lectures' in line:
part = 1
return header, footer
def new_lecture(self):
lec = self.lectures.new_lecture()
if lec.number == 1:
self.update_lectures_in_master([1])
else:
self.update_lectures_in_master([lec.number - 1, lec.number])
return lec
def update_lectures_in_master(self, r):
header, footer = self.get_header_footer(self.master_file)
body = ''.join(
' ' * 4 + r'\input{' + number2filename(number) + '}\n' for number in r)
self.master_file.write_text(header + body + footer)
def compile_master(self):
result = subprocess.run(
['latexmk', '-f', '-interaction=nonstopmode', str(self.master_file)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
cwd=str(self.root)
)
return result.returncode
@property
def lectures(self):
if not self._lectures:
self._lectures = Lectures(self)
return self._lectures