Added a StudentTeamService and cleaned up controllers which can now make
use of it.
This commit is contained in:
parent
6653047263
commit
ae2886fe63
|
@ -13,6 +13,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for operations dealing with the global collection of students, not particular to one course.
|
||||||
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class Students {
|
public class Students {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.student_teams;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentTeamRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.services.StudentTeamService;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class MergeSingleTeams {
|
||||||
|
|
||||||
|
private Logger logger = LogManager.getLogger(MergeSingleTeams.class);
|
||||||
|
|
||||||
|
private CourseRepository courseRepository;
|
||||||
|
private StudentTeamRepository studentTeamRepository;
|
||||||
|
|
||||||
|
private StudentTeamService studentTeamService;
|
||||||
|
|
||||||
|
protected MergeSingleTeams(CourseRepository courseRepository, StudentTeamRepository studentTeamRepository, StudentTeamService studentTeamService) {
|
||||||
|
this.courseRepository = courseRepository;
|
||||||
|
this.studentTeamRepository = studentTeamRepository;
|
||||||
|
this.studentTeamService = studentTeamService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/courses/{code}/student_teams/merge_single_teams")
|
||||||
|
public String get(@PathVariable String code) {
|
||||||
|
Optional<Course> optionalCourse = this.courseRepository.findByCode(code);
|
||||||
|
if (optionalCourse.isPresent()) {
|
||||||
|
Course course = optionalCourse.get();
|
||||||
|
List<StudentTeam> singleTeams = this.getAllSingleTeams(course);
|
||||||
|
singleTeams.forEach(team -> logger.info("Team " + team.getId() + " is a single team."));
|
||||||
|
|
||||||
|
// while (singleTeams.size() > 1) {
|
||||||
|
// StudentTeam single1 = singleTeams.remove(0);
|
||||||
|
// StudentTeam single2 = singleTeams.remove(0);
|
||||||
|
//
|
||||||
|
// // Todo: use a service here and when removing a team in another location to avoid duplication.
|
||||||
|
// StudentTeam newTeam = this.studentTeamService.createNewStudentTeam(course);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/courses/{code}/student_teams";
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<StudentTeam> getAllSingleTeams(Course course) {
|
||||||
|
List<StudentTeam> allTeams = course.getStudentTeams();
|
||||||
|
List<StudentTeam> singleTeams = new ArrayList<>();
|
||||||
|
for (StudentTeam team : allTeams) {
|
||||||
|
if (team.getMembers().size() == 1) {
|
||||||
|
singleTeams.add(team);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return singleTeams;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepo
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentTeamRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentTeamRepository;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantTeamRepository;
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantTeamRepository;
|
||||||
import nl.andrewlalis.teaching_assistant_assistant.util.github.GithubManager;
|
import nl.andrewlalis.teaching_assistant_assistant.services.StudentTeamService;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -16,7 +16,6 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ -27,17 +26,20 @@ public class StudentTeamEntity {
|
||||||
private CourseRepository courseRepository;
|
private CourseRepository courseRepository;
|
||||||
private StudentRepository studentRepository;
|
private StudentRepository studentRepository;
|
||||||
private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
|
private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
|
||||||
|
private StudentTeamService studentTeamService;
|
||||||
|
|
||||||
protected StudentTeamEntity(
|
protected StudentTeamEntity(
|
||||||
StudentTeamRepository studentTeamRepository,
|
StudentTeamRepository studentTeamRepository,
|
||||||
CourseRepository courseRepository,
|
CourseRepository courseRepository,
|
||||||
StudentRepository studentRepository,
|
StudentRepository studentRepository,
|
||||||
TeachingAssistantTeamRepository teachingAssistantTeamRepository
|
TeachingAssistantTeamRepository teachingAssistantTeamRepository,
|
||||||
|
StudentTeamService studentTeamService
|
||||||
) {
|
) {
|
||||||
this.studentTeamRepository = studentTeamRepository;
|
this.studentTeamRepository = studentTeamRepository;
|
||||||
this.courseRepository = courseRepository;
|
this.courseRepository = courseRepository;
|
||||||
this.studentRepository = studentRepository;
|
this.studentRepository = studentRepository;
|
||||||
this.teachingAssistantTeamRepository = teachingAssistantTeamRepository;
|
this.teachingAssistantTeamRepository = teachingAssistantTeamRepository;
|
||||||
|
this.studentTeamService = studentTeamService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,14 +65,16 @@ public class StudentTeamEntity {
|
||||||
return "courses/entity/student_teams/create";
|
return "courses/entity/student_teams/create";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping for creating a new student team.
|
||||||
|
* @param courseCode The course code.
|
||||||
|
* @param model The view model.
|
||||||
|
* @return A redirect to the list of student teams.
|
||||||
|
*/
|
||||||
@PostMapping("/courses/{courseCode}/student_teams/create")
|
@PostMapping("/courses/{courseCode}/student_teams/create")
|
||||||
public String postCreate(@PathVariable String courseCode, Model model) {
|
public String postCreate(@PathVariable String courseCode, Model model) {
|
||||||
Optional<Course> optionalCourse = this.courseRepository.findByCode(courseCode);
|
Optional<Course> optionalCourse = this.courseRepository.findByCode(courseCode);
|
||||||
optionalCourse.ifPresent(course -> {
|
optionalCourse.ifPresent(course -> this.studentTeamService.createNewStudentTeam(course));
|
||||||
StudentTeam team = new StudentTeam(course);
|
|
||||||
course.addStudentTeam(team);
|
|
||||||
this.courseRepository.save(course);
|
|
||||||
});
|
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams";
|
return "redirect:/courses/{courseCode}/student_teams";
|
||||||
}
|
}
|
||||||
|
@ -91,6 +95,13 @@ public class StudentTeamEntity {
|
||||||
return "courses/entity/student_teams/entity/add_student";
|
return "courses/entity/student_teams/entity/add_student";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mapping for adding a new student to this team.
|
||||||
|
* @param courseCode The course code.
|
||||||
|
* @param teamId The id of the team to add the student to.
|
||||||
|
* @param studentId The id of an existing student to add to this team.
|
||||||
|
* @return A redirect to the list of student teams.
|
||||||
|
*/
|
||||||
@PostMapping("/courses/{courseCode}/student_teams/{teamId}/add_student")
|
@PostMapping("/courses/{courseCode}/student_teams/{teamId}/add_student")
|
||||||
public String postAddStudent(
|
public String postAddStudent(
|
||||||
@PathVariable String courseCode,
|
@PathVariable String courseCode,
|
||||||
|
@ -102,16 +113,10 @@ public class StudentTeamEntity {
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(studentId);
|
Optional<Student> optionalStudent = this.studentRepository.findById(studentId);
|
||||||
|
|
||||||
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent() && optionalStudent.isPresent()) {
|
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent() && optionalStudent.isPresent()) {
|
||||||
StudentTeam team = optionalStudentTeam.get();
|
this.studentTeamService.addStudent(optionalStudentTeam.get(), optionalStudent.get());
|
||||||
Student student = optionalStudent.get();
|
|
||||||
|
|
||||||
team.addMember(student);
|
|
||||||
student.assignToTeam(team);
|
|
||||||
this.studentTeamRepository.save(team);
|
|
||||||
this.studentRepository.save(student);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams";
|
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/courses/{courseCode}/student_teams/{teamId}/assign_teaching_assistant_team")
|
@GetMapping("/courses/{courseCode}/student_teams/{teamId}/assign_teaching_assistant_team")
|
||||||
|
@ -131,6 +136,13 @@ public class StudentTeamEntity {
|
||||||
return "courses/entity/student_teams/entity/assign_teaching_assistant_team";
|
return "courses/entity/student_teams/entity/assign_teaching_assistant_team";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint for assigning a teaching assistant team to this student team.
|
||||||
|
* @param courseCode The course code.
|
||||||
|
* @param teamId The id of the student team.
|
||||||
|
* @param teachingAssistantTeamId The id of the teaching assistant team.
|
||||||
|
* @return A redirect to the team responsible.
|
||||||
|
*/
|
||||||
@PostMapping("/courses/{courseCode}/student_teams/{teamId}/assign_teaching_assistant_team")
|
@PostMapping("/courses/{courseCode}/student_teams/{teamId}/assign_teaching_assistant_team")
|
||||||
public String postAssignTeachingAssistantTeam(
|
public String postAssignTeachingAssistantTeam(
|
||||||
@PathVariable String courseCode,
|
@PathVariable String courseCode,
|
||||||
|
@ -147,29 +159,19 @@ public class StudentTeamEntity {
|
||||||
teachingAssistantTeam = optionalTeachingAssistantTeam.get();
|
teachingAssistantTeam = optionalTeachingAssistantTeam.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
StudentTeam studentTeam = optionalStudentTeam.get();
|
this.studentTeamService.assignTeachingAssistantTeam(optionalStudentTeam.get(), teachingAssistantTeam);
|
||||||
TeachingAssistantTeam oldTeam = studentTeam.getAssignedTeachingAssistantTeam();
|
|
||||||
|
|
||||||
// Unset old TA team if it exists.
|
|
||||||
if (oldTeam != null) {
|
|
||||||
oldTeam.removeAssignedStudentTeam(studentTeam);
|
|
||||||
studentTeam.setAssignedTeachingAssistantTeam(null);
|
|
||||||
this.teachingAssistantTeamRepository.save(oldTeam);
|
|
||||||
this.studentTeamRepository.save(studentTeam);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new TA team if it exists.
|
|
||||||
if (teachingAssistantTeam != null) {
|
|
||||||
studentTeam.setAssignedTeachingAssistantTeam(teachingAssistantTeam);
|
|
||||||
teachingAssistantTeam.addAssignedStudentTeam(studentTeam);
|
|
||||||
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
|
||||||
this.studentTeamRepository.save(studentTeam);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams";
|
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint for removing a student from the student team.
|
||||||
|
* @param courseCode The code for the course.
|
||||||
|
* @param teamId The id of the team.
|
||||||
|
* @param studentId The student's id.
|
||||||
|
* @return A redirect to the team after the student is removed.
|
||||||
|
*/
|
||||||
@GetMapping("/courses/{courseCode}/student_teams/{teamId}/remove_student/{studentId}")
|
@GetMapping("/courses/{courseCode}/student_teams/{teamId}/remove_student/{studentId}")
|
||||||
public String getRemoveStudent(
|
public String getRemoveStudent(
|
||||||
@PathVariable String courseCode,
|
@PathVariable String courseCode,
|
||||||
|
@ -181,26 +183,7 @@ public class StudentTeamEntity {
|
||||||
Optional<Student> optionalStudent = this.studentRepository.findById(studentId);
|
Optional<Student> optionalStudent = this.studentRepository.findById(studentId);
|
||||||
|
|
||||||
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent() && optionalStudent.isPresent()) {
|
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent() && optionalStudent.isPresent()) {
|
||||||
Student student = optionalStudent.get();
|
this.studentTeamService.removeStudent(optionalStudentTeam.get(), optionalStudent.get());
|
||||||
StudentTeam team = optionalStudentTeam.get();
|
|
||||||
Course course = optionalCourse.get();
|
|
||||||
|
|
||||||
// If the team has a github repository, remove this student as a collaborator.
|
|
||||||
if (team.getGithubRepositoryName() != null) {
|
|
||||||
try {
|
|
||||||
GithubManager manager = new GithubManager(course.getApiKey());
|
|
||||||
manager.removeCollaborator(team, student);
|
|
||||||
System.out.println("Removed " + student.getGithubUsername() + " from " + team.getGithubRepositoryName());
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Could not remove student from repository: " + team.getGithubRepositoryName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
team.removeMember(student);
|
|
||||||
student.removeFromAssignedTeam(team);
|
|
||||||
|
|
||||||
this.studentTeamRepository.save(team);
|
|
||||||
this.studentRepository.save(student);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
||||||
|
@ -215,26 +198,7 @@ public class StudentTeamEntity {
|
||||||
Optional<StudentTeam> optionalStudentTeam = this.studentTeamRepository.findById(teamId);
|
Optional<StudentTeam> optionalStudentTeam = this.studentTeamRepository.findById(teamId);
|
||||||
|
|
||||||
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent()) {
|
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent()) {
|
||||||
StudentTeam team = optionalStudentTeam.get();
|
this.studentTeamService.generateRepository(optionalStudentTeam.get());
|
||||||
Course course = optionalCourse.get();
|
|
||||||
|
|
||||||
if (team.getGithubRepositoryName() == null) {
|
|
||||||
System.out.println("Generating repository.");
|
|
||||||
try {
|
|
||||||
GithubManager manager = new GithubManager(course.getApiKey());
|
|
||||||
String name = manager.generateStudentTeamRepository(team);
|
|
||||||
team.setGithubRepositoryName(name);
|
|
||||||
this.studentTeamRepository.save(team);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Could not generate repository.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.err.println("Repository already exists.");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
System.err.println("Could not find all objects.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
return "redirect:/courses/{courseCode}/student_teams/{teamId}";
|
||||||
|
@ -246,38 +210,7 @@ public class StudentTeamEntity {
|
||||||
Optional<StudentTeam> optionalStudentTeam = this.studentTeamRepository.findById(teamId);
|
Optional<StudentTeam> optionalStudentTeam = this.studentTeamRepository.findById(teamId);
|
||||||
|
|
||||||
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent()) {
|
if (optionalCourse.isPresent() && optionalStudentTeam.isPresent()) {
|
||||||
StudentTeam team = optionalStudentTeam.get();
|
this.studentTeamService.removeTeam(optionalStudentTeam.get());
|
||||||
Course course = optionalCourse.get();
|
|
||||||
|
|
||||||
// Remove the student team at all costs!
|
|
||||||
if (team.getGithubRepositoryName() != null) {
|
|
||||||
// First remove all student collaborators.
|
|
||||||
try {
|
|
||||||
GithubManager manager = new GithubManager(course.getApiKey());
|
|
||||||
manager.deactivateRepository(team);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
System.err.println("Could not deactivate repository.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove all students from this team.
|
|
||||||
for (Student s : team.getStudents()) {
|
|
||||||
s.removeFromAssignedTeam(team);
|
|
||||||
team.removeMember(s);
|
|
||||||
this.studentRepository.save(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the TA team assignment.
|
|
||||||
TeachingAssistantTeam teachingAssistantTeam = team.getAssignedTeachingAssistantTeam();
|
|
||||||
teachingAssistantTeam.removeAssignedStudentTeam(team);
|
|
||||||
team.setAssignedTeachingAssistantTeam(null);
|
|
||||||
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
|
||||||
|
|
||||||
// Remove the repository from the course and delete it.
|
|
||||||
course.removeStudentTeam(team);
|
|
||||||
this.studentTeamRepository.delete(team);
|
|
||||||
this.courseRepository.save(course);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "redirect:/courses/{courseCode}/student_teams";
|
return "redirect:/courses/{courseCode}/student_teams";
|
||||||
|
|
|
@ -0,0 +1,213 @@
|
||||||
|
package nl.andrewlalis.teaching_assistant_assistant.services;
|
||||||
|
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.Course;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.StudentTeamRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.TeachingAssistantTeamRepository;
|
||||||
|
import nl.andrewlalis.teaching_assistant_assistant.util.github.GithubManager;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service is used to control the manipulation, creation and deletion of student teams.
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class StudentTeamService {
|
||||||
|
|
||||||
|
private Logger logger = LogManager.getLogger(StudentTeamService.class);
|
||||||
|
|
||||||
|
private StudentTeamRepository studentTeamRepository;
|
||||||
|
private StudentRepository studentRepository;
|
||||||
|
private CourseRepository courseRepository;
|
||||||
|
private TeachingAssistantTeamRepository teachingAssistantTeamRepository;
|
||||||
|
|
||||||
|
public StudentTeamService(
|
||||||
|
StudentTeamRepository studentTeamRepository,
|
||||||
|
StudentRepository studentRepository,
|
||||||
|
CourseRepository courseRepository,
|
||||||
|
TeachingAssistantTeamRepository teachingAssistantTeamRepository
|
||||||
|
) {
|
||||||
|
this.studentTeamRepository = studentTeamRepository;
|
||||||
|
this.studentRepository = studentRepository;
|
||||||
|
this.courseRepository = courseRepository;
|
||||||
|
this.teachingAssistantTeamRepository = teachingAssistantTeamRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty student team.
|
||||||
|
* @param course The course that the student team is in.
|
||||||
|
* @return The newly created student team.
|
||||||
|
*/
|
||||||
|
public StudentTeam createNewStudentTeam(Course course) {
|
||||||
|
StudentTeam newTeam = new StudentTeam(course);
|
||||||
|
course.addStudentTeam(newTeam);
|
||||||
|
this.courseRepository.save(course);
|
||||||
|
logger.info("Created new team: " + newTeam.getId());
|
||||||
|
|
||||||
|
return newTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new student team, and populates it with some students and automatically assigns a teaching assistant
|
||||||
|
* team.
|
||||||
|
* @param course The course to which the team will belong.
|
||||||
|
* @param students The list of students to add to the team.
|
||||||
|
* @param teachingAssistantTeam The teaching assistant team responsible for this new team.
|
||||||
|
* @return The newly created student team.
|
||||||
|
*/
|
||||||
|
public StudentTeam createNewStudentTeam(Course course, List<Student> students, TeachingAssistantTeam teachingAssistantTeam) {
|
||||||
|
StudentTeam emptyTeam = this.createNewStudentTeam(course);
|
||||||
|
|
||||||
|
emptyTeam.setAssignedTeachingAssistantTeam(teachingAssistantTeam);
|
||||||
|
teachingAssistantTeam.addAssignedStudentTeam(emptyTeam);
|
||||||
|
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
||||||
|
|
||||||
|
for (Student student : students) {
|
||||||
|
this.addStudent(emptyTeam, student);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptyTeam;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new student to this team.
|
||||||
|
* @param team The team to add the student to.
|
||||||
|
* @param student The student to add.
|
||||||
|
*/
|
||||||
|
public void addStudent(StudentTeam team, Student student) {
|
||||||
|
team.addMember(student);
|
||||||
|
student.assignToTeam(team);
|
||||||
|
this.studentTeamRepository.save(team);
|
||||||
|
this.studentRepository.save(student);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a single student from a team, and if that team has a github repository, tries to remove the student from
|
||||||
|
* that as well.
|
||||||
|
* @param studentTeam The student team to remove the student from.
|
||||||
|
* @param student The student to remove.
|
||||||
|
*/
|
||||||
|
public void removeStudent(StudentTeam studentTeam, Student student) {
|
||||||
|
studentTeam.removeMember(student);
|
||||||
|
student.removeFromAssignedTeam(studentTeam);
|
||||||
|
|
||||||
|
this.studentTeamRepository.save(studentTeam);
|
||||||
|
this.studentRepository.save(student);
|
||||||
|
|
||||||
|
if (studentTeam.getGithubRepositoryName() != null) {
|
||||||
|
try {
|
||||||
|
logger.debug("Removing " + student.getGithubUsername() + " from repository " + studentTeam.getGithubRepositoryName());
|
||||||
|
GithubManager manager = new GithubManager(studentTeam.getCourse().getApiKey());
|
||||||
|
manager.removeCollaborator(studentTeam, student);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.catching(e);
|
||||||
|
logger.error("Could not remove student from repository: " + studentTeam.getGithubRepositoryName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Removed student " + student.getFullName() + " from team " + studentTeam.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a new teaching assistant team to a student team.
|
||||||
|
* @param studentTeam The student team.
|
||||||
|
* @param teachingAssistantTeam The teaching assistant team to assign the student team to.
|
||||||
|
* This may be null.
|
||||||
|
*/
|
||||||
|
public void assignTeachingAssistantTeam(StudentTeam studentTeam, TeachingAssistantTeam teachingAssistantTeam) {
|
||||||
|
TeachingAssistantTeam oldTeachingAssistantTeam = studentTeam.getAssignedTeachingAssistantTeam();
|
||||||
|
|
||||||
|
if (oldTeachingAssistantTeam != null) {
|
||||||
|
oldTeachingAssistantTeam.removeAssignedStudentTeam(studentTeam);
|
||||||
|
studentTeam.setAssignedTeachingAssistantTeam(null);
|
||||||
|
this.teachingAssistantTeamRepository.save(oldTeachingAssistantTeam);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (teachingAssistantTeam != null) {
|
||||||
|
studentTeam.setAssignedTeachingAssistantTeam(teachingAssistantTeam);
|
||||||
|
teachingAssistantTeam.addAssignedStudentTeam(studentTeam);
|
||||||
|
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.studentTeamRepository.save(studentTeam);
|
||||||
|
|
||||||
|
logger.info("Assigned teaching assistant team " + teachingAssistantTeam + " to student team " + studentTeam.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uses a {@link GithubManager} to generate a repository for this student team.
|
||||||
|
* @param team The team to generate a repository for.
|
||||||
|
*/
|
||||||
|
public void generateRepository(StudentTeam team) {
|
||||||
|
if (team.getGithubRepositoryName() == null) {
|
||||||
|
try {
|
||||||
|
GithubManager manager = new GithubManager(team.getCourse().getApiKey());
|
||||||
|
String name = manager.generateStudentTeamRepository(team);
|
||||||
|
team.setGithubRepositoryName(name);
|
||||||
|
this.studentTeamRepository.save(team);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error("Could not generate repository.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn("Repository " + team.getGithubRepositoryName() + " already exists.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given team, archives the repository if one exists.
|
||||||
|
* @param team The team to remove.
|
||||||
|
*/
|
||||||
|
public void removeTeam(StudentTeam team) {
|
||||||
|
Course course = team.getCourse();
|
||||||
|
|
||||||
|
// Remove the student team at all costs!
|
||||||
|
if (team.getGithubRepositoryName() != null) {
|
||||||
|
// First remove all student collaborators.
|
||||||
|
try {
|
||||||
|
GithubManager manager = new GithubManager(course.getApiKey());
|
||||||
|
manager.deactivateRepository(team);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
logger.error("Could not deactivate repository.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all students from this team.
|
||||||
|
for (Student s : team.getStudents()) {
|
||||||
|
s.removeFromAssignedTeam(team);
|
||||||
|
team.removeMember(s);
|
||||||
|
this.studentRepository.save(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the TA team assignment.
|
||||||
|
TeachingAssistantTeam teachingAssistantTeam = team.getAssignedTeachingAssistantTeam();
|
||||||
|
teachingAssistantTeam.removeAssignedStudentTeam(team);
|
||||||
|
team.setAssignedTeachingAssistantTeam(null);
|
||||||
|
this.teachingAssistantTeamRepository.save(teachingAssistantTeam);
|
||||||
|
|
||||||
|
// Remove the repository from the course and delete it.
|
||||||
|
course.removeStudentTeam(team);
|
||||||
|
this.studentTeamRepository.delete(team);
|
||||||
|
this.courseRepository.save(course);
|
||||||
|
|
||||||
|
logger.info("Removed team " + team.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merges all teams consisting of a single student so that new teams are generated.
|
||||||
|
*
|
||||||
|
* TODO: Make this team size independent.
|
||||||
|
*/
|
||||||
|
public void mergeSingleTeams() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ import org.apache.http.client.methods.HttpPut;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClientBuilder;
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.kohsuke.github.*;
|
import org.kohsuke.github.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
@ -26,6 +28,8 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
public class GithubManager {
|
public class GithubManager {
|
||||||
|
|
||||||
|
Logger logger = LogManager.getLogger(GithubManager.class);
|
||||||
|
|
||||||
private GitHub github;
|
private GitHub github;
|
||||||
private String apiKey;
|
private String apiKey;
|
||||||
|
|
||||||
|
@ -55,13 +59,14 @@ public class GithubManager {
|
||||||
* @return The name of the created repository.
|
* @return The name of the created repository.
|
||||||
*/
|
*/
|
||||||
public String generateStudentTeamRepository(StudentTeam team) {
|
public String generateStudentTeamRepository(StudentTeam team) {
|
||||||
GHOrganization organization;
|
logger.info("Generating repository for student team " + team.getId());
|
||||||
|
|
||||||
|
GHOrganization organization;
|
||||||
try {
|
try {
|
||||||
organization = this.github.getOrganization(team.getCourse().getGithubOrganizationName());
|
organization = this.github.getOrganization(team.getCourse().getGithubOrganizationName());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not get Github organization with name: " + team.getCourse().getGithubOrganizationName());
|
logger.error("Could not get Github organization with name: " + team.getCourse().getGithubOrganizationName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,12 +76,11 @@ public class GithubManager {
|
||||||
|
|
||||||
// Get the TA team which manages this repository.
|
// Get the TA team which manages this repository.
|
||||||
GHTeam teachingAssistantGithubTeam;
|
GHTeam teachingAssistantGithubTeam;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
teachingAssistantGithubTeam = organization.getTeamByName(team.getAssignedTeachingAssistantTeam().getGithubTeamName());
|
teachingAssistantGithubTeam = organization.getTeamByName(team.getAssignedTeachingAssistantTeam().getGithubTeamName());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not get team by name: " + team.getAssignedTeachingAssistantTeam().getGithubTeamName());
|
logger.error("Could not get team by name: " + team.getAssignedTeachingAssistantTeam().getGithubTeamName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,50 +93,56 @@ public class GithubManager {
|
||||||
repositoryBuilder.autoInit(false);
|
repositoryBuilder.autoInit(false);
|
||||||
GHRepository repository;
|
GHRepository repository;
|
||||||
try {
|
try {
|
||||||
repository = repositoryBuilder.create();
|
logger.debug("Creating empty repository " + repositoryName);
|
||||||
|
repository = repositoryBuilder.create();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not create repository: " + repositoryName);
|
logger.error("Could not create repository: " + repositoryName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.debug("Assigning teaching assistant team " + teachingAssistantGithubTeam.getName() + " to repository.");
|
||||||
this.addRepositoryToTeam(teachingAssistantGithubTeam, repository);
|
this.addRepositoryToTeam(teachingAssistantGithubTeam, repository);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not add repository " + repositoryName + " to team " + teachingAssistantGithubTeam.getName());
|
logger.error("Could not add repository " + repositoryName + " to team " + teachingAssistantGithubTeam.getName());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.debug("Adding starting file to the repository.");
|
||||||
this.addStarterFile(repository, "program_resources/getting_started.md", "getting_started.md");
|
this.addStarterFile(repository, "program_resources/getting_started.md", "getting_started.md");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not add the starter file to the repository: " + repositoryName);
|
logger.error("Could not add the starter file to the repository: " + repositoryName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.debug("Creating development branch.");
|
||||||
this.createDevelopmentBranch(repository);
|
this.createDevelopmentBranch(repository);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not create development branch for repository: " + repositoryName);
|
logger.error("Could not create development branch for repository: " + repositoryName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.debug("Adding protections to the master branch.");
|
||||||
this.protectMasterBranch(repository, teachingAssistantGithubTeam);
|
this.protectMasterBranch(repository, teachingAssistantGithubTeam);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not add protections to the master branch of " + repositoryName);
|
logger.error("Could not add protections to the master branch of " + repositoryName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
logger.debug("Adding students as collaborators.");
|
||||||
this.addStudentsAsCollaborators(repository, team);
|
this.addStudentsAsCollaborators(repository, team);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("Could not add students as collaborators to " + repositoryName);
|
logger.error("Could not add students as collaborators to " + repositoryName);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +221,7 @@ public class GithubManager {
|
||||||
* Deactivates a repository by removing all collaborator students, unassigning the repository from the TA team that
|
* Deactivates a repository by removing all collaborator students, unassigning the repository from the TA team that
|
||||||
* was responsible for it, and archiving it.
|
* was responsible for it, and archiving it.
|
||||||
* @param studentTeam The student team for which to archive.
|
* @param studentTeam The student team for which to archive.
|
||||||
* @throws IOException
|
* @throws IOException If an io exception occurred, duh!
|
||||||
*/
|
*/
|
||||||
public void deactivateRepository(StudentTeam studentTeam) throws IOException {
|
public void deactivateRepository(StudentTeam studentTeam) throws IOException {
|
||||||
GHOrganization organization = this.github.getOrganization(studentTeam.getCourse().getGithubOrganizationName());
|
GHOrganization organization = this.github.getOrganization(studentTeam.getCourse().getGithubOrganizationName());
|
||||||
|
|
|
@ -69,6 +69,9 @@
|
||||||
<div class="sidebar_block">
|
<div class="sidebar_block">
|
||||||
<a th:href="@{/courses/{code}/student_teams/create(code=${course.getCode()})}">Create New Student Team</a>
|
<a th:href="@{/courses/{code}/student_teams/create(code=${course.getCode()})}">Create New Student Team</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sidebar_block">
|
||||||
|
<a th:href="@{/courses/{code}/student_teams/merge_single_teams(code=${course.getCode()})}">Merge Single Teams</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue