diff --git a/pom.xml b/pom.xml index 640ee77..9da5ccd 100644 --- a/pom.xml +++ b/pom.xml @@ -85,6 +85,18 @@ commons-csv 1.5 + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + + org.kohsuke + github-api + 1.95 + diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CourseEntity.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CourseEntity.java index 612d8ca..a052060 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CourseEntity.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/CourseEntity.java @@ -29,7 +29,8 @@ public class CourseEntity { */ @GetMapping("/courses/{code}") public String get(@PathVariable String code, Model model) { - this.addCourseToModelIfExists(code, model); + Optional courseOptional = this.courseRepository.findByCode(code); + courseOptional.ifPresent(course -> model.addAttribute("course", course)); return "courses/entity"; } @@ -41,10 +42,24 @@ public class CourseEntity { */ @GetMapping("/courses/{code}/student_teams") public String getStudentTeams(@PathVariable String code, Model model) { - this.addCourseToModelIfExists(code, model); + Optional courseOptional = this.courseRepository.findByCode(code); + courseOptional.ifPresent(course -> model.addAttribute("course", course)); return "courses/entity/student_teams"; } + /** + * Gets the teaching assistant teams for a particular course. + * @param code The course code. + * @param model The view model. + * @return The template for viewing the list of student teams. + */ + @GetMapping("/courses/{code}/teaching_assistant_teams") + public String getTeachingAssistantTeams(@PathVariable String code, Model model) { + Optional courseOptional = this.courseRepository.findByCode(code); + courseOptional.ifPresent(course -> model.addAttribute("course", course)); + return "courses/entity/teaching_assistant_teams"; + } + /** * Gets the students for a particular course. * @param code The course code. @@ -53,18 +68,22 @@ public class CourseEntity { */ @GetMapping("/courses/{code}/students") public String getStudents(@PathVariable String code, Model model) { - this.addCourseToModelIfExists(code, model); + Optional courseOptional = this.courseRepository.findByCode(code); + courseOptional.ifPresent(course -> model.addAttribute("course", course)); return "courses/entity/students"; } /** - * Adds the course found by a certain code to the list of model attributes. - * @param courseCode The unique code used to identify this course. - * @param model The view model to add the course data to. + * Gets the teaching assistants for a particular course. + * @param code The course code. + * @param model The view model. + * @return The template for viewing the list of teaching assistants. */ - private void addCourseToModelIfExists(String courseCode, Model model) { - Optional courseOptional = this.courseRepository.findByCode(courseCode); + @GetMapping("/courses/{code}/teaching_assistants") + public String getTeachingAssistants(@PathVariable String code, Model model) { + Optional courseOptional = this.courseRepository.findByCode(code); courseOptional.ifPresent(course -> model.addAttribute("course", course)); + return "courses/entity/teaching_assistants"; } } diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/GenerateRepositories.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/GenerateRepositories.java index a3aa0bc..a0818a4 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/GenerateRepositories.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/controllers/courses/entity/student_teams/GenerateRepositories.java @@ -2,12 +2,14 @@ package nl.andrewlalis.teaching_assistant_assistant.controllers.courses.entity.s import nl.andrewlalis.teaching_assistant_assistant.model.Course; import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository; +import nl.andrewlalis.teaching_assistant_assistant.util.github.GithubManager; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import java.io.IOException; import java.util.Optional; @Controller @@ -33,6 +35,16 @@ public class GenerateRepositories { ) public String post(@PathVariable String courseCode) { System.out.println("Post received for " + courseCode); + Optional optionalCourse = this.courseRepository.findByCode(courseCode); + optionalCourse.ifPresent(course -> { + course.setGithubOrganizationName("InitializerTesting"); + try { + GithubManager manager = new GithubManager("andrewlalis", "scrubstub43"); + manager.generateStudentTeamRepository(course.getStudentTeams().get(0)); + } catch (IOException e) { + e.printStackTrace(); + } + }); return "redirect:/courses/{courseCode}"; } diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java index 058984c..4e65534 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/Course.java @@ -3,6 +3,7 @@ package nl.andrewlalis.teaching_assistant_assistant.model; import nl.andrewlalis.teaching_assistant_assistant.model.assignments.Assignment; import nl.andrewlalis.teaching_assistant_assistant.model.people.Person; import nl.andrewlalis.teaching_assistant_assistant.model.people.Student; +import nl.andrewlalis.teaching_assistant_assistant.model.people.TeachingAssistant; import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam; import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam; @@ -155,6 +156,16 @@ public class Course extends BasicEntity { return students; } + public List getTeachingAssistants() { + List teachingAssistants = new ArrayList<>(); + this.participants.forEach(participant -> { + if (participant instanceof TeachingAssistant) { + teachingAssistants.add((TeachingAssistant) participant); + } + }); + return teachingAssistants; + } + @Override public String toString() { StringBuilder sb = new StringBuilder(this.getName()).append('\n'); diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java index d323e49..dad4d47 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/StudentTeam.java @@ -4,10 +4,7 @@ import nl.andrewlalis.teaching_assistant_assistant.model.assignments.grades.Assi import nl.andrewlalis.teaching_assistant_assistant.model.people.Person; import nl.andrewlalis.teaching_assistant_assistant.model.people.Student; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; +import javax.persistence.*; import java.util.ArrayList; import java.util.List; @@ -23,6 +20,14 @@ public class StudentTeam extends Team { @Column private String githubRepositoryName; + /** + * The teaching assistant team to which this student team is assigned. + */ + @ManyToOne( + fetch = FetchType.LAZY + ) + private TeachingAssistantTeam assignedTeachingAssistantTeam; + /** * The list of assignment grades which this student group has received. */ @@ -53,4 +58,12 @@ public class StudentTeam extends Team { this.githubRepositoryName = name; } + public TeachingAssistantTeam getAssignedTeachingAssistantTeam() { + return this.assignedTeachingAssistantTeam; + } + + public void setAssignedTeachingAssistantTeam(TeachingAssistantTeam team) { + this.assignedTeachingAssistantTeam = team; + } + } diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java index 830a89f..85fb7a5 100644 --- a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/model/people/teams/TeachingAssistantTeam.java @@ -24,12 +24,24 @@ public class TeachingAssistantTeam extends Team { @Column private TeachingAssistantRole role; + /** + * The string name of this team. + */ + @Column + private String githubTeamName; + @OneToMany @JoinColumn( name = "teaching_assistant_team_id" ) private List sectionGrades; + @OneToMany + @JoinColumn( + name = "teaching_assistant_team_id" + ) + private List assignedStudentTeams; + /** * Default constructor for JPA. */ @@ -41,4 +53,12 @@ public class TeachingAssistantTeam extends Team { people.forEach(person -> teachingAssistants.add((TeachingAssistant) person)); return teachingAssistants; } + + public String getGithubTeamName() { + return this.githubTeamName; + } + + public void setGithubTeamName(String name) { + this.githubTeamName = name; + } } diff --git a/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java new file mode 100644 index 0000000..5925a87 --- /dev/null +++ b/src/main/java/nl/andrewlalis/teaching_assistant_assistant/util/github/GithubManager.java @@ -0,0 +1,82 @@ +package nl.andrewlalis.teaching_assistant_assistant.util.github; + +import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.StudentTeam; +import org.kohsuke.github.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +public class GithubManager { + + private GitHub github; + + public GithubManager(String apiKey) throws IOException { + this.github = GitHub.connectUsingOAuth(apiKey); + } + + public GithubManager(String username, String password) throws IOException { + this.github = GitHub.connectUsingPassword(username, password); + } + + public void generateStudentTeamRepository(StudentTeam team) throws IOException { + GHOrganization organization = this.github.getOrganization(team.getCourse().getGithubOrganizationName()); + Calendar today = Calendar.getInstance(); + int year = today.get(Calendar.YEAR); + String repositoryName = year + "_Team_" + team.getId(); + + // Get the TA team which manages this repository. + GHTeam teachingAssistantGithubTeam = organization.getTeamByName(team.getAssignedTeachingAssistantTeam().getGithubTeamName()); + + // Create the repo + GHCreateRepositoryBuilder repositoryBuilder = organization.createRepository(repositoryName); + repositoryBuilder.wiki(false); + repositoryBuilder.issues(false); + repositoryBuilder.description("University of Groningen OOP Student Repository"); + repositoryBuilder.private_(false); + repositoryBuilder.autoInit(false); + repositoryBuilder.team(teachingAssistantGithubTeam); + GHRepository repository = repositoryBuilder.create(); + + // Add getting started file. + GHContentBuilder contentBuilder = repository.createContent(); + contentBuilder.branch("master"); + contentBuilder.message("Initial Commit"); + File f = new File(getClass().getClassLoader().getResource("program_resources/getting_started.md").getFile()); + contentBuilder.content(Files.readAllBytes(f.toPath())); + contentBuilder.path("getting_started.md"); + contentBuilder.commit(); + + // Create the development branch. + try { + String sha1 = repository.getBranch(repository.getDefaultBranch()).getSHA1(); + repository.createRef("refs/heads/development", sha1); + } catch (IOException e) { + e.printStackTrace(); + } + + // Protect master branch. + GHBranchProtectionBuilder protectionBuilder = repository.getBranch("master").enableProtection(); + protectionBuilder.includeAdmins(false); + protectionBuilder.restrictPushAccess(); + protectionBuilder.teamPushAccess(teachingAssistantGithubTeam); + protectionBuilder.addRequiredChecks("ci/circleci"); + protectionBuilder.enable(); + + List studentUsers = new ArrayList<>(team.getMembers().size()); + team.getStudents().forEach(student -> { + try { + studentUsers.add(this.github.getUser(student.getGithubUsername())); + } catch (IOException e) { + e.printStackTrace(); + } + }); + + //repository.addCollaborators(studentUsers); + + } + +} diff --git a/src/main/resources/program_resources/getting_started.md b/src/main/resources/program_resources/getting_started.md new file mode 100644 index 0000000..c4db326 --- /dev/null +++ b/src/main/resources/program_resources/getting_started.md @@ -0,0 +1,22 @@ +# Getting Started +Welcome to the University of Groningen's Object Oriented Programming course! We're glad to have you. Read the instructions provided here carefully so that you can have a smooth start to the course. + +## Setting Up +To begin, you'll need to download this repository you're looking at right now. To do that, run the following command (where `repository_url` is the URL of this repository): +``` +git clone +``` + +Now you should have a local directory with the same name as this repository. Checkout your `development` branch, since you do not have permission as a student to make changes to the master branch. From here, we need to copy the files from the assignments repository into ours. To do this, we first add a new 'remote' to our git repository, and then pull from that repository's `master` branch. +``` +git checkout development + +git remote add assignments https://github.com/rug-oop/2019_assignments + +git pull assignments master --allow-unrelated-histories +``` + +Now you should see all the files just as they appear in the assignments repository. + +## Developing Your Code and Submitting +While previous knowledge of git may be useful, it should not really be needed for you to do well in this course. \ No newline at end of file diff --git a/src/main/resources/templates/courses/entity.html b/src/main/resources/templates/courses/entity.html index fb2c3e2..842362a 100644 --- a/src/main/resources/templates/courses/entity.html +++ b/src/main/resources/templates/courses/entity.html @@ -12,7 +12,7 @@ diff --git a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html index 894b13a..07123a5 100644 --- a/src/main/resources/templates/courses/entity/teaching_assistant_teams.html +++ b/src/main/resources/templates/courses/entity/teaching_assistant_teams.html @@ -9,8 +9,23 @@

Teaching Assistant Teams for

+
+

No teaching assistant teams.

+
- + + + + +
+ + Teaching Assistant Team + + + +
diff --git a/src/main/resources/templates/courses/entity/teaching_assistants.html b/src/main/resources/templates/courses/entity/teaching_assistants.html new file mode 100644 index 0000000..9ca9361 --- /dev/null +++ b/src/main/resources/templates/courses/entity/teaching_assistants.html @@ -0,0 +1,26 @@ + + + + Teaching Assistants + + + +
+

Teaching Assistants for

+ + + + + + +
+ +
+
+ + + + + \ No newline at end of file diff --git a/src/main/resources/templates/fragments/header.html b/src/main/resources/templates/fragments/header.html index 2cd3521..1e60e1d 100644 --- a/src/main/resources/templates/fragments/header.html +++ b/src/main/resources/templates/fragments/header.html @@ -13,6 +13,7 @@