Skip to content
Snippets Groups Projects
Commit de984265 authored by tuhe's avatar tuhe
Browse files

student files setup script

parent 5d289900
No related branches found
No related tags found
No related merge requests found
......@@ -15,7 +15,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
# beamer-slider
setuptools.setup(
name="coursebox",
version="0.1.18.2",
version="0.1.18.3",
author="Tue Herlau",
author_email="tuhe@dtu.dk",
description="A course management system currently used at DTU",
......
Metadata-Version: 2.1
Name: coursebox
Version: 0.1.18.2
Version: 0.1.18.3
Summary: A course management system currently used at DTU
Home-page: https://lab.compute.dtu.dk/tuhe/coursebox
Author: Tue Herlau
......
......@@ -22,5 +22,7 @@ src/coursebox/material/__init__.py
src/coursebox/material/homepage_lectures_exercises.py
src/coursebox/material/lecture_questions.py
src/coursebox/material/snipper.py
src/coursebox/student_files/__init__.py
src/coursebox/student_files/student_files.py
src/coursebox/testing/__init__.py
src/coursebox/testing/testing.py
\ No newline at end of file
......@@ -21,15 +21,6 @@ def get_paths():
root_02450public = root_02450public.replace("\\", "/")
root_02450private = root_02450private.replace("\\", "/")
# if not os.path.isdir(root_02450private):
# root_02450private = f'{root_02450public}/{num}private'
# warn('Private repository not found at the expected location.')
# warn('Using mock info from resources folder at:')
# warn(root_02450private)
# Tue: always overwrite semester path.
# semester_path = root_02450private +"/resources/mock_semesters/" + semester_id()
# else:
semester_path = root_02450private + "/semesters/" + semester_id()
if not os.path.isdir(semester_path):
......
import os, shutil
from coursebox.core.info_paths import get_paths
from coursebox.core.info import class_information
from snipper.snip_dir import snip_dir
from coursebox.material.homepage_lectures_exercises import fix_shared
from snipper.snipper_main import censor_file
from pathlib import Path
import fnmatch
def setup_student_files(run_files=True,
cut_files=True,
censor_files=True,
week=None, extra_dirs=None,
include_solutions=None,
projects=None,
setup_lectures=False, strict=True,
fix_shared_files=True,
include_exam_examples=False, # Include the directory with exam-related examples.
verbose=True,
students_irlc_tools=None, # Destination dir for the irlc folder (the one we really want to deploy).
midterms=None, # Can be a list: [0, 1]
include_docs=False, # Include the documentation directory, i.e. 02465public/pythontools/docs.
convert_svg=True, # Whether to convert SVG file when deploying. Leave to true, unless we are doing CI/CD in which case inkscape may not be installed.
package="cp",
fix_shared_files_func=None,
):
if midterms is None:
midterms = []
from coursebox.core import info_paths
week = [week] if isinstance(week, int) else week
if verbose:
print("toolbox running. Fixing student files by copying to student dir")
paths = get_paths()
if include_solutions is None:
include_solutions = []
if projects is None:
projects = []
public_irlc_tools = paths['02450public'] + "/src/cp"
if students_irlc_tools is None:
if censor_files:
students_irlc_tools = paths['02450students'] + "/cp"
else:
students_irlc_tools = paths['02450students'] + "_complete/cp"
if not os.path.isdir(students_irlc_tools):
os.makedirs(students_irlc_tools)
init_dest = students_irlc_tools+"/__init__.py"
shutil.copy(public_irlc_tools + "/__init__.py", init_dest)
censor_file(init_dest)
# Check for exclusion mask.
exclude = info_paths.core_conf.get('student_files', {}).get('exclude', [])
exclude += [f'tests_week{w if w >= 10 else f"0{w}"}.py' for w in range(0,14) if w not in week]
exclude = exclude + ["**/" + ex for ex in exclude]
if not include_exam_examples:
exclude += ['exam_tabular_examples']
inclusion = [] # 'ex09old/cache']
hws = []
for m in midterms:
# Copy the midterm from the exam directory into the public repository. This will ensure the midterm is later propagated to the student directory.
# The midterm should always be distributed as a .zip file: This is the only legal distribution mechanism.
# The midterm in the student directory does not need to be super-duper up to date. This is not the file which is distributed 'officially'.
if verbose:
print(m)
if extra_dirs is None:
extra_dirs = ['utils', 'tests', 'exam/exam2023spring'] # 'assignments',
for m in midterms:
if m == 0:
extra_dirs += ['exam/midterm2023a']
if m == 1:
extra_dirs += ['exam/midterm2023b']
# if include_exam_examples:
# extra_dirs += ['exam_tabular_examples']
if setup_lectures:
extra_dirs += [
# 'lectures/chapter0pythonC',
# 'lectures/chapter0pythonA',
# 'lectures/chapter0pythonB',
# 'lectures/chapter1',
'lectures',
'workshop'
]
import coursebox.core.info
for id in projects:
# if setup_projects:
if 'projects_all' in info_paths.core_conf:
p = info_paths.core_conf['projects_all'][id]['class']
extra_dirs += [os.path.basename(os.path.dirname(p.mfile()))]
else:
if id <= 3:
extra_dirs += [f'project{id}'] # , 'project1', 'project2', 'project3']
else:
extra_dirs.append(f'project3i')
if week is not None:
for w in week:
ex = str(w)
ex = "ex" + ("0" + ex if len(ex) < 2 else ex)
base = public_irlc_tools +"/"+ex
if not os.path.isdir(base):
continue
d = {'base': base,
'out': students_irlc_tools +"/"+ex,
'exclusion': exclude,
'inclusion': inclusion,
'include_solutions': w in include_solutions,
'week': w}
hws.append(d)
weekn = 101
for weekn, d in enumerate(extra_dirs):
dutil = {'base': public_irlc_tools + "/" + d,
'out': students_irlc_tools + "/" + d,
'exclusion': exclude,
'inclusion': inclusion,
'include_solutions': False,
'week': f'{weekn+100}'}
hws.append(dutil)
weekn += 1
else:
raise Exception("Specify a week")
if len(hws) > 0:
info = class_information(verbose=verbose)
# print("references") # Bad idea because of the very long output.
# print(info['references']['commands'])
else:
info = None
for hw in hws:
n = fix_hw(paths=paths, info=info, hw=hw, out= hw['out'], output_dir=paths['shared'] +"/output", run_files=run_files, cut_files=cut_files,
package_base_dir=os.path.dirname(students_irlc_tools), censor_files=censor_files, strict=strict,
include_solutions=hw.get('include_solutions', False),
verbose=verbose)
with open(paths['shared'] + f"/output/lines_{hw['week']}.txt", 'w') as f:
f.write(str(n))
if fix_shared_files:
if verbose:
print("> Homework fixed, copying shared files...")
fix_shared_files_func(paths=paths, compile_templates=False, verbose=verbose, dosvg=convert_svg)
if verbose:
print("> Removing excluded files from students gitlab directory...")
# for f in exclude + ["lectures"]:
for l in list(Path(students_irlc_tools).glob('**/*')):
if not os.path.exists(l): # May have been removed as part of a subtree
continue
m = [ ex for ex in exclude if fnmatch.fnmatch(l, ex)]
if len(m) > 0:
if os.path.isdir(l):
shutil.rmtree(l)
else:
os.remove(l)
shutil.copy(public_irlc_tools +"/../requirements.txt", students_irlc_tools +"/../requirements.txt")
# shutil.copy(public_irlc_tools +"/../requirements_conda.txt", students_irlc_tools +"/../requirements_conda.txt")
# Don't think we need this anymore. Why copy docs if they cannot be compiled anyway? Perhaps for the complete docs?
if include_docs:
if os.path.isdir(students_irlc_tools + "/../docs"):
shutil.rmtree(students_irlc_tools + "/../docs")
# if not censor_files:
shutil.copytree(public_irlc_tools + "/../docs", students_irlc_tools + "/../docs")
# Fix reference to output.
snip_dir(public_irlc_tools + "/../docs/source", students_irlc_tools + "/../docs/source", run_files=False, cut_files=False, censor_files=False, references=info['references'], verbose=verbose)
if verbose:
print("> All student file stuff completed.")
def fix_hw(paths, info, hw, out, output_dir, run_files=False, cut_files=False, censor_files=True,
include_solutions=False,
package_base_dir=None, # When runing files using #!o, this specify the base directory of the package the files resides in. Can be None.
verbose=True,
**kwargs):
n, cutouts = snip_dir(source_dir=hw['base'], dest_dir=out, output_dir=output_dir, exclude=hw['exclusion'], references=info['references'],
run_files=run_files, cut_files=cut_files, license_head=info.get('code_copyright', None),
censor_files=censor_files,verbose=verbose,package_base_dir=package_base_dir)
if include_solutions:
wk = hw['base'].split("/")[-1]
sp = paths['02450students'] + "/solutions/"
if not os.path.exists(sp):
os.mkdir(sp)
sp = sp + wk
if os.path.isdir(sp):
shutil.rmtree(sp)
# if not os.path.exists(sp):
os.mkdir(sp)
for f, cut in cutouts.items():
if len(cut) > 0:
fname = os.path.basename(f)
sols = []
stext = ["\n".join(lines) for lines in cut]
for i, sol in enumerate(stext):
sols.append((sol,))
sout = sp + f"/{os.path.basename(fname)[:-3]}_TODO_{i + 1}.py"
wsol = True
print(sout, "(published)" if wsol else "")
if wsol:
with open(sout, "w") as f:
f.write(sol)
return n
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment