Added teaching assistant relation to student teams and proper generation of repositories with readme.

This commit is contained in:
Andrew Lalis 2019-04-20 15:39:42 +02:00 committed by andrewlalis
parent 10403b4be5
commit a5cfdfbbc9
12 changed files with 250 additions and 14 deletions

12
pom.xml
View File

@ -85,6 +85,18 @@
<artifactId>commons-csv</artifactId> <artifactId>commons-csv</artifactId>
<version>1.5</version> <version>1.5</version>
</dependency> </dependency>
<!-- Apache HTTP Library -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<!-- Github API Object Library -->
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>github-api</artifactId>
<version>1.95</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -29,7 +29,8 @@ public class CourseEntity {
*/ */
@GetMapping("/courses/{code}") @GetMapping("/courses/{code}")
public String get(@PathVariable String code, Model model) { public String get(@PathVariable String code, Model model) {
this.addCourseToModelIfExists(code, model); Optional<Course> courseOptional = this.courseRepository.findByCode(code);
courseOptional.ifPresent(course -> model.addAttribute("course", course));
return "courses/entity"; return "courses/entity";
} }
@ -41,10 +42,24 @@ public class CourseEntity {
*/ */
@GetMapping("/courses/{code}/student_teams") @GetMapping("/courses/{code}/student_teams")
public String getStudentTeams(@PathVariable String code, Model model) { public String getStudentTeams(@PathVariable String code, Model model) {
this.addCourseToModelIfExists(code, model); Optional<Course> courseOptional = this.courseRepository.findByCode(code);
courseOptional.ifPresent(course -> model.addAttribute("course", course));
return "courses/entity/student_teams"; 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<Course> 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. * Gets the students for a particular course.
* @param code The course code. * @param code The course code.
@ -53,18 +68,22 @@ public class CourseEntity {
*/ */
@GetMapping("/courses/{code}/students") @GetMapping("/courses/{code}/students")
public String getStudents(@PathVariable String code, Model model) { public String getStudents(@PathVariable String code, Model model) {
this.addCourseToModelIfExists(code, model); Optional<Course> courseOptional = this.courseRepository.findByCode(code);
courseOptional.ifPresent(course -> model.addAttribute("course", course));
return "courses/entity/students"; return "courses/entity/students";
} }
/** /**
* Adds the course found by a certain code to the list of model attributes. * Gets the teaching assistants for a particular course.
* @param courseCode The unique code used to identify this course. * @param code The course code.
* @param model The view model to add the course data to. * @param model The view model.
* @return The template for viewing the list of teaching assistants.
*/ */
private void addCourseToModelIfExists(String courseCode, Model model) { @GetMapping("/courses/{code}/teaching_assistants")
Optional<Course> courseOptional = this.courseRepository.findByCode(courseCode); public String getTeachingAssistants(@PathVariable String code, Model model) {
Optional<Course> courseOptional = this.courseRepository.findByCode(code);
courseOptional.ifPresent(course -> model.addAttribute("course", course)); courseOptional.ifPresent(course -> model.addAttribute("course", course));
return "courses/entity/teaching_assistants";
} }
} }

View File

@ -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.Course;
import nl.andrewlalis.teaching_assistant_assistant.model.repositories.CourseRepository; 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.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;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import java.io.IOException;
import java.util.Optional; import java.util.Optional;
@Controller @Controller
@ -33,6 +35,16 @@ public class GenerateRepositories {
) )
public String post(@PathVariable String courseCode) { public String post(@PathVariable String courseCode) {
System.out.println("Post received for " + courseCode); System.out.println("Post received for " + courseCode);
Optional<Course> 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}"; return "redirect:/courses/{courseCode}";
} }

View File

@ -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.assignments.Assignment;
import nl.andrewlalis.teaching_assistant_assistant.model.people.Person; 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.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.StudentTeam;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam; import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.TeachingAssistantTeam;
@ -155,6 +156,16 @@ public class Course extends BasicEntity {
return students; return students;
} }
public List<TeachingAssistant> getTeachingAssistants() {
List<TeachingAssistant> teachingAssistants = new ArrayList<>();
this.participants.forEach(participant -> {
if (participant instanceof TeachingAssistant) {
teachingAssistants.add((TeachingAssistant) participant);
}
});
return teachingAssistants;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(this.getName()).append('\n'); StringBuilder sb = new StringBuilder(this.getName()).append('\n');

View File

@ -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.Person;
import nl.andrewlalis.teaching_assistant_assistant.model.people.Student; import nl.andrewlalis.teaching_assistant_assistant.model.people.Student;
import javax.persistence.Column; import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -23,6 +20,14 @@ public class StudentTeam extends Team {
@Column @Column
private String githubRepositoryName; 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. * The list of assignment grades which this student group has received.
*/ */
@ -53,4 +58,12 @@ public class StudentTeam extends Team {
this.githubRepositoryName = name; this.githubRepositoryName = name;
} }
public TeachingAssistantTeam getAssignedTeachingAssistantTeam() {
return this.assignedTeachingAssistantTeam;
}
public void setAssignedTeachingAssistantTeam(TeachingAssistantTeam team) {
this.assignedTeachingAssistantTeam = team;
}
} }

View File

@ -24,12 +24,24 @@ public class TeachingAssistantTeam extends Team {
@Column @Column
private TeachingAssistantRole role; private TeachingAssistantRole role;
/**
* The string name of this team.
*/
@Column
private String githubTeamName;
@OneToMany @OneToMany
@JoinColumn( @JoinColumn(
name = "teaching_assistant_team_id" name = "teaching_assistant_team_id"
) )
private List<SectionGrade> sectionGrades; private List<SectionGrade> sectionGrades;
@OneToMany
@JoinColumn(
name = "teaching_assistant_team_id"
)
private List<StudentTeam> assignedStudentTeams;
/** /**
* Default constructor for JPA. * Default constructor for JPA.
*/ */
@ -41,4 +53,12 @@ public class TeachingAssistantTeam extends Team {
people.forEach(person -> teachingAssistants.add((TeachingAssistant) person)); people.forEach(person -> teachingAssistants.add((TeachingAssistant) person));
return teachingAssistants; return teachingAssistants;
} }
public String getGithubTeamName() {
return this.githubTeamName;
}
public void setGithubTeamName(String name) {
this.githubTeamName = name;
}
} }

View File

@ -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<GHUser> 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);
}
}

View File

@ -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 <repository_url>
```
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.

View File

@ -12,7 +12,7 @@
<ul> <ul>
<li> <li>
<a th:href="@{${'https://www.github.com/' + course.getGithubOrganizationName()}}">Github Organization</a> Github Organization: <a th:href="@{${'https://www.github.com/' + course.getGithubOrganizationName()}}" th:text="${course.getGithubOrganizationName()}"></a>
</li> </li>
<li> <li>
<a th:href="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}">Teaching Assistant Teams</a> <a th:href="@{/courses/{code}/teaching_assistant_teams(code=${course.getCode()})}">Teaching Assistant Teams</a>
@ -23,6 +23,9 @@
<li> <li>
<a th:href="@{/courses/{code}/students(code=${course.getCode()})}">All Students</a> <a th:href="@{/courses/{code}/students(code=${course.getCode()})}">All Students</a>
</li> </li>
<li>
<a th:href="@{/courses/{code}/teaching_assistants(code=${course.getCode()})}">All Teaching Assistants</a>
</li>
</ul> </ul>
</div> </div>

View File

@ -9,8 +9,23 @@
<div id="content"> <div id="content">
<h1>Teaching Assistant Teams for <span th:text="${course.getName()}"></span></h1> <h1>Teaching Assistant Teams for <span th:text="${course.getName()}"></span></h1>
<div th:if="${course.getTeachingAssistantTeams().isEmpty()}">
<p>No teaching assistant teams.</p>
</div>
<table> <table>
<tr th:each="taTeam: ${course.getTeachingAssistantTeams()}">
<td>
<a
th:href="@{/courses/{code}/teaching_assistant_teams/{team_id}
(code=${course.getCode()}, team_id=${taTeam.getId()})}">
Teaching Assistant Team <span th:text="${taTeam.getId()}"></span>
</a>
</td>
<td th:each="ta: ${taTeam.getStudents()}">
<span th:text="${ta.getFullName()}"></span>
</td>
<td th:text="${taTeam.getGithubRepositoryName()}"></td>
</tr>
</table> </table>
</div> </div>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" th:replace="~{layouts/basic_page :: layout (~{::title}, ~{::#content}, ~{::#sidebar})}">
<head>
<title>Teaching Assistants</title>
</head>
<body>
<div id="content">
<h1>Teaching Assistants for <span th:text="${course.getName()}"></span></h1>
<table>
<tr th:each="teachingAssistant: ${course.getTeachingAssistants()}">
<td>
<a th:href="@{/teaching_assistants/{id}(id=${teachingAssistant.getId()})}"><span th:text="${teachingAssistant.getFullName()}"></span></a>
</td>
<td th:text="${teachingAssistant.getEmailAddress()}"></td>
</tr>
</table>
</div>
<div id="sidebar">
</div>
</body>
</html>

View File

@ -13,6 +13,7 @@
<ul class="header_link_list"> <ul class="header_link_list">
<li><a href="/" th:href="@{/}">Home</a> <li><a href="/" th:href="@{/}">Home</a>
<li><a href="/courses" th:href="@{/courses}">Courses</a> <li><a href="/courses" th:href="@{/courses}">Courses</a>
<li><a href="/students" th:href="@{/students}">Students</a></li>
</ul> </ul>
</nav> </nav>