def update(data: DataDirectory) -> None: backend = data.get_backend().client current = get_current_version() available = backend.get_current_version() if current < available: interface_print("Update available") if prompt("Do you want to view the changelog?", YesNoParser(True)): changelogs = backend.get_changelogs() for key in sorted(changelogs.keys()): interface_print("=== Changes in version %s ===" % str(key)) interface_print(changelogs[key]) interface_print() if prompt("Do you want to download the update now?", YesNoParser(True)): with TemporaryDirectory() as temp_dir: path = Path(temp_dir) / "client.tgz" with path.open("wb") as f: f.write(backend.get()) with tarfile.open(str(path)) as f: f.extractall(str(Path.cwd().parent)) interface_print("Update complete. Restarting script.") execute_subprocess(["./main.sh"], capture_output=False) exit(0)
def ensure_team_existence(data: DataDirectory, can_be_skipped: bool = False) -> None: if not data.team.has_value(): interface_print( "There is no team.json saved yet. You will need to provide information about your team before you can submit solutions." ) if not can_be_skipped or prompt( "Do you want to create a team.json now?", YesNoParser(True)): create_team_json(data) else: interface_print( "Please review the currently saved information about your team:") i = 1 for member in data.team.get().members: interface_print( " %d - First name: %s; Last name: %s; Matriculation number: %s" % (i, member.first_name, member.last_name, member.matriculation_number)) i += 1 if not prompt("Is this information up to date?", YesNoParser(True)): create_team_json(data) interface_print()
def start_submission(): interface_print() success = submit(root_directory, data_directory) interface_print() if success: if prompt("Do you want to submit another solution?", YesNoParser(True)): start_submission() else: if prompt("Do you want to try again?", YesNoParser(True)): start_submission()
def check_for_new_results(data_directory: DataDirectory): # Check every submission for new results try: for assignment in data_directory.get_assignments(): for submission in assignment.get_submissions(): if not submission.bookkeeping_data.get( ).status == SubmissionStatus.accepted: continue if submission.check_for_evaluation_results(): submission.print_evaluation_results() continue # Check if the submission still exists (may have been removed) and if it is eligible for result subscription if submission.bookkeeping_data.get( ).status == SubmissionStatus.accepted and submission.submission_response.get( ).immediate_evaluation: if prompt( "Do you want to subscribe to the results of submission %s?" % submission.submission_data.get().submission_id, YesNoParser(True)): submission.wait_for_evaluation_results() except Exception as e: global_log_file.error("".join( traceback.format_exception(*sys.exc_info()))) # Errors when checking for new results should never prevent students from submitting, so we are a fault tolerant. interface_print("Error while checking for new results: %s" % str(e)) interface_print( "Please report this issue. You will still be able to submit a solution." )
def print_evaluation_results(self) -> None: score_percentage = \ 100 * self.submission_data.get().evaluation_result.score / self.submission_data.get().evaluation_result.max_score \ if self.submission_data.get().evaluation_result.max_score != 0 \ else 0 interface_print( "You achieved the score %d/%d (%d%%)." % (self.submission_data.get().evaluation_result.score, self.submission_data.get().evaluation_result.max_score, score_percentage)) if self.submission_data.get().evaluation_result.comment is not None: interface_print("The following comment was left by your teacher:") interface_print( self.submission_data.get().evaluation_result.comment) if self.submission_data.get().evaluation_result.passed: interface_print("You have PASSED this assignment.") else: interface_print("You have NOT PASSED this assignment.") if self.submission_data.get().evaluation_result.log is not None: if prompt("Do you want to view the evaluation log now?", YesNoParser(True)): interface_print("=== BEGIN Evaluation Log") interface_print( self.submission_data.get().evaluation_result.log) interface_print("=== END Evaluation Log") interface_print("NOTE: This evaluation log is also available at '%s'" % self.evaluation_log.path.absolute())
def main(): root_directory = Path.cwd().parent.parent data_directory = DataDirectory(Path.cwd().parent / "data") set_global_log_file(data_directory.create_logfile()) bootstrap_log_path = Path("bootstrap.log") if bootstrap_log_path.is_file(): global_log_file.log("Bootstrap log:\n%s" % bootstrap_log_path.open().read()) interface_print("=== Welcome ===") update(data_directory) check_for_new_results(data_directory) ensure_team_existence(data_directory) def start_submission(): interface_print() success = submit(root_directory, data_directory) interface_print() if success: if prompt("Do you want to submit another solution?", YesNoParser(True)): start_submission() else: if prompt("Do you want to try again?", YesNoParser(True)): start_submission() if prompt("Do you want to submit a solution now?", YesNoParser(True)): start_submission()
def prompt_evaluation_wait(self): if not self.submission_response.has_value( ) or not self.submission_response.get().immediate_evaluation: return if prompt( "This submission will be evaluated immediately. Do you want to wait for results now?", YesNoParser(True)): self.wait_for_evaluation_results()
def prompt_student(member_number: int) -> Student: while True: interface_print("Please enter details of team member %d." % member_number) lastname = prompt("Last Name:", NameParser()) firstname = prompt("First Name:", NameParser()) matriculation_number = prompt("Matriculation number:", MatriculationNumberParser()) member = Student(lastname, firstname, matriculation_number) interface_print() interface_print( "First name: %s; Last name: %s; Matriculation number: %s" % (member.first_name, member.last_name, member.matriculation_number)) if prompt("Is this correct?", YesNoParser(False)): return member
def select_assignment(options: List[Assignment]) -> Optional[Assignment]: if len(options) == 0: return None if len(options) == 1: return options[0] return prompt( "Please choose the assignment you want to submit.", SelectionParser([(a.assignment_id, a) for a in options], None))
def create_team_json(data: DataDirectory) -> None: members = [] interface_print("A new team.json will now be created.\n") while True: members.append(prompt_student(len(members) + 1)) if len(members) >= data.config.get().max_team_size or not prompt( "Another?", YesNoParser(True)): break data.team.set(Team(members)) interface_print("team.json successfully created.\n")
def build_solution(directory: Path, selected_variant: SkeletonVariant) -> bool: interface_print("=== Building submission ===") interface_print("Running '%s'." % selected_variant.build) interface_print("=== Building submission finished ===") build_result = execute_subprocess([selected_variant.build], cwd=directory, is_shell_command=True, merge_stdout_stderr=True) if not build_result.is_success(): interface_print("Building your solution failed!") if prompt("Do you want to view the build log?", YesNoParser(True)): interface_print("=== BEGIN Build Log ===") interface_print(build_result.stdout, end='') interface_print("=== END Build Log ===") if not prompt( "Do you want to submit your solution anyway, despite the failing build?", YesNoParser(False)): interface_print("Aborting submission.") return False return True
def select_variant(root_directory: Path, data: DataDirectory) -> Optional[SkeletonVariant]: found_options = [ v for v in data.config.get().skeleton_variants if (root_directory / v.root).is_dir() ] if len(found_options) == 0: interface_print( "No skeleton variant found! Did you delete all of them?") return None if len(found_options) == 1: return found_options[0] return prompt("Please choose the variant you want to submit.", SelectionParser([(a.name, a) for a in found_options], None))