Half of features implemented #2
			
				
			
		
		
		
	
							
								
								
									
										6
									
								
								pom.xml
								
								
								
								
							
							
						
						
									
										6
									
								
								pom.xml
								
								
								
								
							| 
						 | 
				
			
			@ -73,6 +73,12 @@
 | 
			
		|||
            <artifactId>github-api</artifactId>
 | 
			
		||||
            <version>1.93</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <!-- SQLite JDBC Driver -->
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.xerial</groupId>
 | 
			
		||||
            <artifactId>sqlite-jdbc</artifactId>
 | 
			
		||||
            <version>3.23.1</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
    </dependencies>
 | 
			
		||||
    
 | 
			
		||||
</project>
 | 
			
		||||
| 
						 | 
				
			
			@ -56,8 +56,8 @@ public class Main {
 | 
			
		|||
        );
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            githubManager.initializeGithubRepos(studentTeams);
 | 
			
		||||
            //githubManager.deleteAllRepositories();
 | 
			
		||||
            //githubManager.initializeGithubRepos(studentTeams);
 | 
			
		||||
            //githubManager.archiveAllRepositories("team");
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,14 @@
 | 
			
		|||
package nl.andrewlalis.git_api;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.databind.ObjectMapper;
 | 
			
		||||
import com.fasterxml.jackson.databind.node.ObjectNode;
 | 
			
		||||
import nl.andrewlalis.model.Student;
 | 
			
		||||
import nl.andrewlalis.model.StudentTeam;
 | 
			
		||||
import org.apache.http.HttpResponse;
 | 
			
		||||
import org.apache.http.client.methods.HttpPatch;
 | 
			
		||||
import org.apache.http.entity.StringEntity;
 | 
			
		||||
import org.apache.http.impl.client.CloseableHttpClient;
 | 
			
		||||
import org.apache.http.impl.client.HttpClientBuilder;
 | 
			
		||||
import org.kohsuke.github.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
| 
						 | 
				
			
			@ -15,16 +22,6 @@ import java.util.logging.Logger;
 | 
			
		|||
 */
 | 
			
		||||
public class GithubManager {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The name of the organization to operate on.
 | 
			
		||||
     */
 | 
			
		||||
    private String organizationName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The object which simplifies creating REST URL's for most of the requests.
 | 
			
		||||
     */
 | 
			
		||||
    private URLBuilder urlBuilder;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The assignments repository where students will get assignments from.
 | 
			
		||||
     */
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +44,7 @@ public class GithubManager {
 | 
			
		|||
     */
 | 
			
		||||
    private GitHub github;
 | 
			
		||||
    private GHOrganization organization;
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The logger for outputting debug info.
 | 
			
		||||
| 
						 | 
				
			
			@ -57,15 +55,14 @@ public class GithubManager {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    public GithubManager(String organizationName, String accessToken, String assignmentsRepo, String teachingAssistantsTeamName, String studentRepoPrefix) {
 | 
			
		||||
        this.organizationName = organizationName;
 | 
			
		||||
        this.assignmentsRepoName = assignmentsRepo;
 | 
			
		||||
        this.teachingAssistantsTeamName = teachingAssistantsTeamName;
 | 
			
		||||
        this.studentRepoPrefix = studentRepoPrefix;
 | 
			
		||||
        this.urlBuilder = new URLBuilder(organizationName, accessToken);
 | 
			
		||||
        this.accessToken = accessToken;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            this.github = GitHub.connectUsingOAuth(accessToken);
 | 
			
		||||
            this.organization = this.github.getOrganization(this.organizationName);
 | 
			
		||||
            this.organization = this.github.getOrganization(organizationName);
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +101,13 @@ public class GithubManager {
 | 
			
		|||
     * @throws IOException If an HTTP request failed.
 | 
			
		||||
     */
 | 
			
		||||
    private void setupAssignmentsRepo(GHTeam allTeachingAssistants) throws IOException {
 | 
			
		||||
        // Check if the repository already exists.
 | 
			
		||||
        GHRepository existingRepo = this.organization.getRepository(this.assignmentsRepoName);
 | 
			
		||||
        if (existingRepo != null) {
 | 
			
		||||
            existingRepo.delete();
 | 
			
		||||
            logger.fine("Deleted pre-existing assignments repository.");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create the repository.
 | 
			
		||||
        GHCreateRepositoryBuilder builder = this.organization.createRepository(this.assignmentsRepoName);
 | 
			
		||||
        builder.description("Assignments repository for Advanced Object Oriented Programming");
 | 
			
		||||
| 
						 | 
				
			
			@ -113,6 +117,7 @@ public class GithubManager {
 | 
			
		|||
        builder.team(allTeachingAssistants);
 | 
			
		||||
        builder.gitignoreTemplate("Java");
 | 
			
		||||
        this.assignmentsRepo = builder.create();
 | 
			
		||||
        logger.info("Created assignments repository.");
 | 
			
		||||
 | 
			
		||||
        // Protect the master branch.
 | 
			
		||||
        GHBranchProtectionBuilder protectionBuilder = this.assignmentsRepo.getBranch("master").enableProtection();
 | 
			
		||||
| 
						 | 
				
			
			@ -121,9 +126,11 @@ public class GithubManager {
 | 
			
		|||
        protectionBuilder.teamPushAccess(allTeachingAssistants);
 | 
			
		||||
        protectionBuilder.addRequiredChecks("ci/circleci");
 | 
			
		||||
        protectionBuilder.enable();
 | 
			
		||||
        logger.fine("Protected master branch of assignments repository.");
 | 
			
		||||
 | 
			
		||||
        // Grant all teaching assistants write access.
 | 
			
		||||
        allTeachingAssistants.add(this.assignmentsRepo, GHOrganization.Permission.ADMIN);
 | 
			
		||||
        logger.fine("Gave admin rights to all teaching assistants in team: " + allTeachingAssistants.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			@ -185,9 +192,9 @@ public class GithubManager {
 | 
			
		|||
     * @throws IOException if an error occurs with sending requests.
 | 
			
		||||
     */
 | 
			
		||||
    public void deleteAllRepositories() throws IOException {
 | 
			
		||||
        Map<String, GHRepository> repoMap = this.organization.getRepositories();
 | 
			
		||||
        for (Map.Entry<String, GHRepository> repoEntry : repoMap.entrySet()) {
 | 
			
		||||
            repoEntry.getValue().delete();
 | 
			
		||||
        List<GHRepository> repositories = this.organization.listRepositories().asList();
 | 
			
		||||
        for (GHRepository repo : repositories) {
 | 
			
		||||
            repo.delete();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -195,8 +202,25 @@ public class GithubManager {
 | 
			
		|||
     * Archives all repositories whose name contains the given substring.
 | 
			
		||||
     * @param sub Any repository containing this substring will be archived.
 | 
			
		||||
     */
 | 
			
		||||
    public void archiveAllRepositories(String sub) {
 | 
			
		||||
 | 
			
		||||
    public void archiveAllRepositories(String sub) throws IOException {
 | 
			
		||||
        List<GHRepository> repositories = this.organization.listRepositories().asList();
 | 
			
		||||
        for (GHRepository repo : repositories) {
 | 
			
		||||
            if (repo.getName().contains(sub)) {
 | 
			
		||||
                HttpPatch patch = new HttpPatch("https://api.github.com/repos/" + repo.getFullName() + "?access_token=" + this.accessToken);
 | 
			
		||||
                CloseableHttpClient client = HttpClientBuilder.create().build();
 | 
			
		||||
                ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
                ObjectNode root = mapper.createObjectNode();
 | 
			
		||||
                root.put("archived", true);
 | 
			
		||||
                String json = mapper.writeValueAsString(root);
 | 
			
		||||
                patch.setEntity(new StringEntity(json));
 | 
			
		||||
                HttpResponse response = client.execute(patch);
 | 
			
		||||
                if (response.getStatusLine().getStatusCode() != 200) {
 | 
			
		||||
                    throw new IOException("Could not archive repository: " + repo.getName() + ". Code: " + response.getStatusLine().getStatusCode());
 | 
			
		||||
                }
 | 
			
		||||
                logger.info("Archived repository: " + repo.getFullName());
 | 
			
		||||
                // TODO: archive repository using Github Java API, instead of Apache HttpUtils.
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,140 +0,0 @@
 | 
			
		|||
package nl.andrewlalis.git_api;
 | 
			
		||||
 | 
			
		||||
public class URLBuilder {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The main URL from which all requests must be formed.
 | 
			
		||||
     */
 | 
			
		||||
    private static final String baseURL = "https://api.github.com";
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The name of the github organization in which to create repositories.
 | 
			
		||||
     */
 | 
			
		||||
    private String organizationName;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The token needed to use the API.
 | 
			
		||||
     */
 | 
			
		||||
    private String accessToken;
 | 
			
		||||
 | 
			
		||||
    public URLBuilder(String organizationName, String accessToken) {
 | 
			
		||||
        this.organizationName = organizationName;
 | 
			
		||||
        this.accessToken = accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return The URL for adding a repository.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildRepoURL() {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/orgs/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + "/repos?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The name of the repository.
 | 
			
		||||
     * @param branch The name of the branch in the repository above.
 | 
			
		||||
     * @return The URL for setting branch protection.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildBranchProtectionURL(String repoName, String branch) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "/branches/"
 | 
			
		||||
                + branch
 | 
			
		||||
                + "/protection?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The name of the repository the branch is in.
 | 
			
		||||
     * @return The URL for getting a branch reference.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildReferenceGetURL(String repoName) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "/git/refs/heads/master?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The repository name.
 | 
			
		||||
     * @return The URL for creating a new branch, once a reference has been obtained.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildReferencePostURL(String repoName) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "/git/refs?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The name of the repository.
 | 
			
		||||
     * @param collaborator The collaborator's name.
 | 
			
		||||
     * @return The URL for adding a collaborator to a repository.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildCollaboratorURL(String repoName, String collaborator) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "/collaborators/"
 | 
			
		||||
                + collaborator
 | 
			
		||||
                + "?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return The URL for obtaining the teams.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildTeamURL() {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/orgs/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + "/teams?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The name of the repository.
 | 
			
		||||
     * @param teamName The name of the team to set permissions for.
 | 
			
		||||
     * @return The URL for setting team permissions of a repository.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildTeamPermissionsURL(String repoName, String teamName) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/teams/"
 | 
			
		||||
                + teamName
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param repoName The name of the repository.
 | 
			
		||||
     * @return The URL for archiving a repository.
 | 
			
		||||
     */
 | 
			
		||||
    public String buildArchiveRepoURL(String repoName) {
 | 
			
		||||
        return baseURL
 | 
			
		||||
                + "/repos/"
 | 
			
		||||
                + this.organizationName
 | 
			
		||||
                + '/'
 | 
			
		||||
                + repoName
 | 
			
		||||
                + "?access_token="
 | 
			
		||||
                + this.accessToken;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Contains all logic which directly interacts with the Github API. All methods which need to perform an action on a
 | 
			
		||||
 * repository or team should find it within this package.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andrew Lalis
 | 
			
		||||
 */
 | 
			
		||||
package nl.andrewlalis.git_api;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,5 @@
 | 
			
		|||
package nl.andrewlalis.model;
 | 
			
		||||
 | 
			
		||||
import org.kohsuke.github.GHTeam;
 | 
			
		||||
 | 
			
		||||
public class TeachingAssistant extends Person {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Contains all objects which form the conceptual basis for this application, such as Students, Teams, and any other
 | 
			
		||||
 * abstract data containers.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Andrew Lalis
 | 
			
		||||
 */
 | 
			
		||||
package nl.andrewlalis.model;
 | 
			
		||||
		Loading…
	
		Reference in New Issue