Coverage for e2xgrader/exchange/fetch_assignment.py: 27%
48 statements
« prev ^ index » next coverage.py v7.4.2, created at 2024-03-14 13:22 +0100
« prev ^ index » next coverage.py v7.4.2, created at 2024-03-14 13:22 +0100
1import glob
2import os
3from textwrap import dedent
5import nbformat
6from nbgrader.exchange.default import ExchangeFetchAssignment
7from nbgrader.utils import check_mode
9from ..preprocessors import PermuteTasks, Scramble
10from .exchange import E2xExchange
13class E2xExchangeFetchAssignment(E2xExchange, ExchangeFetchAssignment):
14 def init_src(self):
15 if self.coursedir.course_id == "":
16 self.fail("No course id specified. Re-run with --course flag.")
17 if not self.authenticator.has_access(
18 self.coursedir.student_id, self.coursedir.course_id
19 ):
20 self.fail("You do not have access to this course.")
22 self.course_path = os.path.join(self.root, self.coursedir.course_id)
23 self.outbound_path = os.path.join(self.course_path, self.outbound_directory)
24 if self.personalized_outbound:
25 self.src_path = os.path.join(
26 self.outbound_path,
27 os.getenv("JUPYTERHUB_USER"),
28 self.coursedir.assignment_id,
29 )
30 else:
31 self.src_path = os.path.join(
32 self.outbound_path, self.coursedir.assignment_id
33 )
35 if not os.path.isdir(self.src_path):
36 self._assignment_not_found(
37 self.src_path, os.path.join(self.outbound_path, "*")
38 )
39 if not check_mode(self.src_path, read=True, execute=True):
40 self.fail(
41 "You don't have read permissions for the directory: {}".format(
42 self.src_path
43 )
44 )
46 def do_scrambling(self, dest, student_id):
47 self.log.info(f"Scrambling for {student_id}")
48 scrambler = Scramble(seed=hash(student_id))
49 permuter = PermuteTasks(seed=hash(student_id))
50 for nb_path in glob.glob(os.path.join(dest, "*.ipynb")):
51 nb = nbformat.read(nb_path, as_version=4)
52 if len(nb.cells) > 0 and nb.cells[0].source.startswith("%% scramble"):
53 resources = {}
54 nb, resources = scrambler.preprocess(nb, resources)
55 nb, resources = permuter.preprocess(nb, resources)
56 nbformat.write(nb, nb_path)
57 self.log.info("Scrambled")
59 def copy_files(self):
60 self.log.info("Source: {}".format(self.src_path))
61 self.log.info("Destination: {}".format(self.dest_path))
62 self.do_copy(self.src_path, self.dest_path)
63 self.do_scrambling(self.dest_path, os.getenv("JUPYTERHUB_USER"))
64 self.log.info(
65 "Fetched as: {} {}".format(
66 self.coursedir.course_id, self.coursedir.assignment_id
67 )
68 )
70 def do_copy(self, src, dest):
71 if self.personalized_outbound:
72 personalized_src = os.path.join(src, os.getenv("JUPYTERHUB_USER"))
73 if os.path.exists(personalized_src):
74 src = personalized_src
75 else:
76 self.log.warning(
77 dedent(
78 f"""
79 Using personalized outbound, but no directory for
80 user {os.getenv('JUPYTERHUB_USER')} exists.
81 """
82 )
83 )
84 super().do_copy(src, dest)