Esempio n. 1
0
    def init_src(self):
        if self.coursedir.course_id == "":
            self.fail("No course id specified. Re-run with --course flag.")
        if not self.authenticator.has_access(self.coursedir.student_id,
                                             self.coursedir.course_id):
            self.fail("You do not have access to this course.")

        self.course_path = os.path.join(self.root, self.coursedir.course_id)
        self.outbound_path = os.path.join(self.course_path,
                                          self.outbound_directory)
        if self.personalized_outbound:
            self.src_path = os.path.join(
                self.outbound_path,
                os.getenv("JUPYTERHUB_USER"),
                self.coursedir.assignment_id,
            )
        else:
            self.src_path = os.path.join(self.outbound_path,
                                         self.coursedir.assignment_id)

        if not os.path.isdir(self.src_path):
            self._assignment_not_found(self.src_path,
                                       os.path.join(self.outbound_path, "*"))
        if not check_mode(self.src_path, read=True, execute=True):
            self.fail(
                "You don't have read permissions for the directory: {}".format(
                    self.src_path))
Esempio n. 2
0
    def init_dest(self):
        if self.coursedir.course_id == '':
            self.fail("No course id specified. Re-run with --course flag.")
        if not self.authenticator.has_access(self.coursedir.student_id, self.coursedir.course_id):
            self.fail("You do not have access to this course.")

        self.inbound_path = os.path.join(self.root, self.coursedir.course_id, 'inbound')
        if not os.path.isdir(self.inbound_path):
            self.fail("Inbound directory doesn't exist: {}".format(self.inbound_path))
        if not check_mode(self.inbound_path, write=True, execute=True):
            self.fail("You don't have write permissions to the directory: {}".format(self.inbound_path))

        self.cache_path = os.path.join(self.cache, self.coursedir.course_id)
        if self.coursedir.student_id != '*':
            # An explicit student id has been specified on the command line; we use it as student_id
            if '*' in self.coursedir.student_id or '+' in self.coursedir.student_id:
                self.fail("The student ID should contain no '*' nor '+'; got {}".format(self.coursedir.student_id))
            student_id = self.coursedir.student_id
        else:
            student_id = get_username()
        if self.add_random_string:
            random_str = base64.urlsafe_b64encode(os.urandom(9)).decode('ascii')
            self.assignment_filename = '{}+{}+{}+{}'.format(
                student_id, self.coursedir.assignment_id, self.timestamp, random_str)
        else:
            self.assignment_filename = '{}+{}+{}'.format(
                student_id, self.coursedir.assignment_id, self.timestamp)
    def init_src(self):
        if self.coursedir.course_id == '':
            self.fail("No course id specified. Re-run with --course flag.")

        self.course_path = os.path.join(self.root, self.coursedir.course_id)
        self.inbound_path = os.path.join(self.course_path, 'inbound')
        if not os.path.isdir(self.inbound_path):
            self.fail("Course not found: {}".format(self.inbound_path))
        if not check_mode(self.inbound_path, read=True, execute=True):
            self.fail("You don't have read permissions for the directory: {}".format(self.inbound_path))
        student_id = self.coursedir.student_id if self.coursedir.student_id else '*'
        pattern = os.path.join(self.inbound_path, '{}+{}+*'.format(student_id, self.coursedir.assignment_id))
        records = [self._path_to_record(f) for f in glob.glob(pattern)]
        usergroups = groupby(records, lambda item: item['username'])

        with Gradebook(self.coursedir.db_url, self.coursedir.course_id) as gb:
            try:
                assignment = gb.find_assignment(self.coursedir.assignment_id)
                self.duedate = assignment.duedate
            except MissingEntry:
                self.duedate = None
        if self.duedate is None or not self.before_duedate:
            self.src_records = [self._sort_by_timestamp(v)[0] for v in usergroups.values()]
        else:
            self.src_records = []
            for v in usergroups.values():
                records = self._sort_by_timestamp(v)
                records_before_duedate = [record for record in records if record['timestamp'] <= self.duedate]
                if records_before_duedate:
                    self.src_records.append(records_before_duedate[0])
                else:
                    self.src_records.append(records[0])
Esempio n. 4
0
    def init_release(self):
        if self.coursedir.course_id == "":
            self.fail("No course id specified. Re-run with --course flag.")

        course_path = os.path.join(self.root, self.coursedir.course_id)
        outbound_path = os.path.join(course_path, self.outbound_directory)
        if self.personalized_outbound:
            self.release_path = os.path.join(
                outbound_path,
                os.getenv("JUPYTERHUB_USER"),
                self.coursedir.assignment_id,
            )
        else:
            self.release_path = os.path.join(
                outbound_path, self.coursedir.assignment_id
            )

        if not os.path.isdir(self.release_path):
            self.fail("Assignment not found: {}".format(self.release_path))
        if not check_mode(self.release_path, read=True, execute=True):
            self.fail(
                "You don't have read permissions for the directory: {}".format(
                    self.release_path
                )
            )
Esempio n. 5
0
 def init_src(self):
     self.course_path = os.path.join(self.exchange_directory, self.course_id)
     self.outbound_path = os.path.join(self.course_path, 'outbound')
     self.src_path = os.path.join(self.outbound_path, self.assignment_id)
     if not os.path.isdir(self.src_path):
         self.fail("Assignment not found: {}".format(self.src_path))
     if not check_mode(self.src_path, read=True, execute=True):
         self.fail("You don't have read permissions for the directory: {}".format(self.src_path))
Esempio n. 6
0
 def init_dest(self):
     self.course_path = os.path.join(self.exchange_directory, self.course_id)
     self.inbound_path = os.path.join(self.course_path, 'inbound')
     self.assignment_filename = get_username() + '+' + self.assignment_id + '+' + self.timestamp
     self.dest_path = os.path.join(self.inbound_path, self.assignment_filename)
     if not os.path.isdir(self.inbound_path):
         self.fail("Inbound directory doesn't exist: {}".format(self.inbound_path))
     if not check_mode(self.inbound_path, write=True, execute=True):
         self.fail("You don't have write permissions to the directory: {}".format(self.inbound_path))
Esempio n. 7
0
 def init_dest(self):
     self.course_path = os.path.join(self.exchange_directory, self.course_id)
     self.inbound_path = os.path.join(self.course_path, 'inbound')
     self.assignment_filename = get_username() + '+' + self.assignment_id + '+' + self.timestamp
     self.dest_path = os.path.join(self.inbound_path, self.assignment_filename)
     if not os.path.isdir(self.inbound_path):
         self.fail("Inbound directory doesn't exist: {}".format(self.inbound_path))
     if not check_mode(self.inbound_path, write=True, execute=True):
         self.fail("You don't have write permissions to the directory: {}".format(self.inbound_path))
Esempio n. 8
0
    def init_release(self):
        if self.coursedir.course_id == '':
            self.fail("No course id specified. Re-run with --course flag.")

        course_path = os.path.join(self.root, self.coursedir.course_id)
        outbound_path = os.path.join(course_path, 'outbound')
        self.release_path = os.path.join(outbound_path, self.coursedir.assignment_id)
        if not os.path.isdir(self.release_path):
            self.fail("Assignment not found: {}".format(self.release_path))
        if not check_mode(self.release_path, read=True, execute=True):
            self.fail("You don't have read permissions for the directory: {}".format(self.release_path))
Esempio n. 9
0
 def init_src(self):
     self.course_path = os.path.join(self.exchange_directory,
                                     self.course_id)
     self.outbound_path = os.path.join(self.course_path, 'outbound')
     self.src_path = os.path.join(self.outbound_path, self.assignment_id)
     if not os.path.isdir(self.src_path):
         self.fail("Assignment not found: {}".format(self.src_path))
     if not check_mode(self.src_path, read=True, execute=True):
         self.fail(
             "You don't have read permissions for the directory: {}".format(
                 self.src_path))
Esempio n. 10
0
    def init_dest(self):
        if self.course_id == '':
            self.fail("No course id specified. Re-run with --course flag.")

        self.inbound_path = os.path.join(self.exchange_directory, self.course_id, 'inbound')
        if not os.path.isdir(self.inbound_path):
            self.fail("Inbound directory doesn't exist: {}".format(self.inbound_path))
        if not check_mode(self.inbound_path, write=True, execute=True):
            self.fail("You don't have write permissions to the directory: {}".format(self.inbound_path))

        self.cache_path = os.path.join(self.cache_directory, self.course_id)
        self.assignment_filename = '{}+{}+{}'.format(get_username(), self.assignment_id, self.timestamp)
Esempio n. 11
0
 def init_src(self):
     self.course_path = os.path.join(self.exchange_directory, self.course_id)
     self.inbound_path = os.path.join(self.course_path, 'inbound')
     if not os.path.isdir(self.inbound_path):
         self.fail("Course not found: {}".format(self.inbound_path))
     if not check_mode(self.inbound_path, read=True, execute=True):
         self.fail("You don't have read permissions for the directory: {}".format(self.inbound_path))
     student_id = self.student_id if self.student_id else '*'
     pattern = os.path.join(self.inbound_path, '{}+{}+*'.format(student_id, self.assignment_id))
     records = [self._path_to_record(f) for f in glob.glob(pattern)]
     usergroups = groupby(records, lambda item: item['username'])
     self.src_records = [self._sort_by_timestamp(v)[0] for v in usergroups.values()]
Esempio n. 12
0
    def init_src(self):
        if self.coursedir.course_id == "":
            self.fail("No course id specified. Re-run with --course flag.")

        self.course_path = os.path.join(self.root, self.coursedir.course_id)
        self.inbound_path = os.path.join(self.course_path,
                                         self.inbound_directory)
        if not os.path.isdir(self.inbound_path):
            self.fail("Course not found: {}".format(self.inbound_path))
        if not check_mode(self.inbound_path, read=True, execute=True):
            self.fail(
                "You don't have read permissions for the directory: {}".format(
                    self.inbound_path))

        records, usergroups = self.init_submissions()

        with Gradebook(self.coursedir.db_url, self.coursedir.course_id) as gb:
            try:
                assignment = gb.find_assignment(self.coursedir.assignment_id)
                self.duedate = assignment.duedate
            except MissingEntry:
                self.duedate = None
        if self.duedate is None or not self.before_duedate:
            self.src_records = [
                self._sort_by_timestamp(v)[0] for v in usergroups.values()
            ]
        else:
            self.src_records = []
            for v in usergroups.values():
                records = self._sort_by_timestamp(v)
                records_before_duedate = [
                    record for record in records
                    if record["timestamp"] <= self.duedate
                ]
                if records_before_duedate:
                    self.src_records.append(records_before_duedate[0])
                else:
                    self.src_records.append(records[0])
Esempio n. 13
0
    def init_dest(self):
        if self.coursedir.course_id == "":
            self.fail("No course id specified. Re-run with --course flag.")
        if not self.authenticator.has_access(
            self.coursedir.student_id, self.coursedir.course_id
        ):
            self.fail("You do not have access to this course.")

        self.inbound_path = os.path.join(
            self.root, self.coursedir.course_id, self.inbound_directory
        )

        if self.personalized_inbound:
            self.inbound_path = os.path.join(
                self.inbound_path, os.getenv("JUPYTERHUB_USER")
            )

            if not os.path.isdir(self.inbound_path):
                self.log.warning(
                    "Inbound directory doesn't exist, creating {}".format(
                        self.inbound_path
                    )
                )
                # 0777 with set GID so student instructors can read students' submissions
                self.ensure_directory(
                    self.inbound_path,
                    S_ISGID
                    | S_IRUSR
                    | S_IWUSR
                    | S_IXUSR
                    | S_IRGRP
                    | S_IWGRP
                    | S_IXGRP
                    | S_IROTH
                    | S_IWOTH
                    | S_IXOTH
                    | (S_IRGRP if self.coursedir.groupshared else 0),
                )

        if not os.path.isdir(self.inbound_path):
            self.fail("Inbound directory doesn't exist: {}".format(self.inbound_path))
        if not check_mode(self.inbound_path, write=True, execute=True):
            self.fail(
                "You don't have write permissions to the directory: {}".format(
                    self.inbound_path
                )
            )

        self.cache_path = os.path.join(self.cache, self.coursedir.course_id)
        if self.coursedir.student_id != "*":
            # An explicit student id has been specified on the command line; we use it as student_id
            if "*" in self.coursedir.student_id or "+" in self.coursedir.student_id:
                self.fail(
                    "The student ID should contain no '*' nor '+'; got {}".format(
                        self.coursedir.student_id
                    )
                )
            student_id = self.coursedir.student_id
        else:
            student_id = get_username()
        if self.add_random_string:
            random_str = base64.urlsafe_b64encode(os.urandom(9)).decode("ascii")
            self.assignment_filename = "{}+{}+{}+{}".format(
                student_id, self.coursedir.assignment_id, self.timestamp, random_str
            )
        else:
            self.assignment_filename = "{}+{}+{}".format(
                student_id, self.coursedir.assignment_id, self.timestamp
            )
Esempio n. 14
0
    def init_src(self):
        if self.coursedir.course_id == "":
            self.fail("No course id specified. Re-run with --course flag.")

        self.course_path = os.path.join(self.root, self.coursedir.course_id)
        self.outbound_path = os.path.join(self.course_path,
                                          self.feedback_directory)
        self.src_path = os.path.join(self.outbound_path)
        self.cache_path = os.path.join(self.cache, self.coursedir.course_id)

        if self.coursedir.student_id != "*":
            # An explicit student id has been specified on the command line; we use it as student_id
            if "*" in self.coursedir.student_id or "+" in self.coursedir.student_id:
                self.fail(
                    "The student ID should contain no '*' nor '+'; got {}".
                    format(self.coursedir.student_id))
            student_id = self.coursedir.student_id
        else:
            student_id = get_username()

        if not os.path.isdir(self.src_path):
            self._assignment_not_found(self.src_path,
                                       os.path.join(self.outbound_path, "*"))
        if not check_mode(self.src_path, execute=True):
            self.fail(
                "You don't have execute permissions for the directory: {}".
                format(self.src_path))

        assignment_id = (self.coursedir.assignment_id
                         if self.coursedir.assignment_id else "*")
        pattern = os.path.join(self.cache_path, "*+{}+*".format(assignment_id))
        self.log.debug(
            "Looking for submissions with pattern: {}".format(pattern))

        self.feedback_files = []
        submissions = [os.path.split(x)[-1] for x in glob.glob(pattern)]
        for submission in submissions:
            _, assignment_id, timestamp = submission.split("/")[-1].split("+")

            self.log.debug(
                "Looking for feedback for '{}/{}' submitted at {}".format(
                    self.coursedir.course_id, assignment_id, timestamp))

            pattern = os.path.join(self.cache_path, submission, "*.ipynb")
            notebooks = glob.glob(pattern)
            for notebook in notebooks:
                notebook_id = os.path.splitext(os.path.split(notebook)[-1])[0]

                # Check if personalized_feedback is used
                if self.personalized_feedback:
                    feedbackpath = os.path.join(
                        self.outbound_path,
                        student_id,
                        assignment_id,
                        "{}.html".format(notebook_id),
                    )
                    self.log.debug("Feedback file: ", feedbackpath)
                    if os.path.exists(feedbackpath):
                        self.feedback_files.append(
                            (notebook_id, timestamp, feedbackpath))
                        self.log.info(
                            "Found feedback for '{}/{}/{}' submitted at {}".
                            format(
                                self.coursedir.course_id,
                                assignment_id,
                                notebook_id,
                                timestamp,
                            ))
                        continue

                    # If we reached here, then there's no feedback available
                    self.log.warning(
                        "Could not find feedback for '{}/{}/{}' submitted at {}"
                        .format(
                            self.coursedir.course_id,
                            assignment_id,
                            notebook_id,
                            timestamp,
                        ))
                else:
                    unique_key = make_unique_key(
                        self.coursedir.course_id,
                        assignment_id,
                        notebook_id,
                        student_id,
                        timestamp,
                    )

                    # Look for the feedback using new-style of feedback
                    self.log.debug("Unique key is: {}".format(unique_key))
                    nb_hash = notebook_hash(notebook, unique_key)
                    feedbackpath = os.path.join(self.outbound_path,
                                                "{0}.html".format(nb_hash))
                    if os.path.exists(feedbackpath):
                        self.feedback_files.append(
                            (notebook_id, timestamp, feedbackpath))
                        self.log.info(
                            "Found feedback for '{}/{}/{}' submitted at {}".
                            format(
                                self.coursedir.course_id,
                                assignment_id,
                                notebook_id,
                                timestamp,
                            ))
                        continue

                    # If it doesn't exist, try the legacy hashing
                    nb_hash = notebook_hash(notebook)
                    feedbackpath = os.path.join(self.outbound_path,
                                                "{0}.html".format(nb_hash))
                    if os.path.exists(feedbackpath):
                        self.feedback_files.append(
                            (notebook_id, timestamp, feedbackpath))
                        self.log.warning(
                            "Found legacy feedback for '{}/{}/{}' submitted at {}"
                            .format(
                                self.coursedir.course_id,
                                assignment_id,
                                notebook_id,
                                timestamp,
                            ))
                        continue

                    # If we reached here, then there's no feedback available
                    self.log.warning(
                        "Could not find feedback for '{}/{}/{}' submitted at {}"
                        .format(
                            self.coursedir.course_id,
                            assignment_id,
                            notebook_id,
                            timestamp,
                        ))