Skip to content

Commit

Permalink
Fix for issue hub4j#330. Added statistics API.
Browse files Browse the repository at this point in the history
  • Loading branch information
martinvanzijl committed Aug 12, 2018
1 parent d61697a commit 706c946
Show file tree
Hide file tree
Showing 2 changed files with 333 additions and 0 deletions.
326 changes: 326 additions & 0 deletions src/main/java/org/kohsuke/github/GHRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
package org.kohsuke.github;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.codec.binary.Base64;
Expand Down Expand Up @@ -1539,6 +1541,330 @@ public boolean equals(Object obj) {
}
}

/**
* Get contributors list with additions, deletions, and commit count.
* See https://developer.github.com/v3/repos/statistics/#get-contributors-list-with-additions-deletions-and-commit-counts
*/
public PagedIterable<ContributorStats> getContributorStats() throws IOException {
return new PagedIterable<ContributorStats>() {
public PagedIterator<ContributorStats> _iterator(int pageSize) {
return new PagedIterator<ContributorStats>(root.retrieve().asIterator(getApiTailUrl("stats/contributors"), ContributorStats[].class, pageSize)) {
@Override
protected void wrapUp(ContributorStats[] page) {
for (ContributorStats c : page) {
c.wrapUp(root);
}
}
};
}
};
}

public static class ContributorStats extends GHObject {
/*package almost final*/ private GitHub root;
private GHUser author;
private int total;
private List<Week> weeks;

@Override
public URL getHtmlUrl() throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}

public GitHub getRoot() {
return root;
}

public GHUser getAuthor() {
return author;
}

/**
* @return The total number of commits authored by the contributor.
*/
public int getTotal() {
return total;
}

public List<Week> getWeeks() {
return weeks;
}

public static class Week {
private long w;
private int a;
private int d;
private int c;

/**
* @return Start of the week, as a UNIX timestamp.
*/
public long getWeekTimestamp() {
return w;
}

/**
* @return The number of additions for the week.
*/
public int getNumberOfAdditions() {
return a;
}

/**
* @return The number of deletions for the week.
*/
public int getNumberOfDeletions() {
return d;
}

/**
* @return The number of commits for the week.
*/
public int getNumberOfCommits() {
return c;
}
}

/*package*/ ContributorStats wrapUp(GitHub root) {
this.root = root;
return this;
}
}

/**
* Get the last year of commit activity data.
* See https://developer.github.com/v3/repos/statistics/#get-the-last-year-of-commit-activity-data
*/
public PagedIterable<CommitActivity> getCommitActivity() throws IOException {
return new PagedIterable<CommitActivity>() {
public PagedIterator<CommitActivity> _iterator(int pageSize) {
return new PagedIterator<CommitActivity>(root.retrieve().asIterator(getApiTailUrl("stats/commit_activity"), CommitActivity[].class, pageSize)) {
@Override
protected void wrapUp(CommitActivity[] page) {
for (CommitActivity c : page) {
c.wrapUp(root);
}
}
};
}
};
}

public static class CommitActivity extends GHObject {
/*package almost final*/ private GitHub root;
private List<Integer> days;
private int total;
private long week;

/**
* @return The number of commits for each day of the week.
* 0 = Sunday, 1 = Monday, etc.
*/
public List<Integer> getDays() {
return days;
}

/**
* @return The total number of commits for the week.
*/
public int getTotal() {
return total;
}

/**
* @return The start of the week as a UNIX timestamp.
*/
public long getWeek() {
return week;
}

/*package*/ CommitActivity wrapUp(GitHub root) {
this.root = root;
return this;
}

public GitHub getRoot() {
return root;
}

@Override
public URL getHtmlUrl() throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

/**
* Get the number of additions and deletions per week.
* See https://developer.github.com/v3/repos/statistics/#get-the-number-of-additions-and-deletions-per-week
*/
public List<CodeFrequency> getCodeFrequency() throws IOException {
// Map to ArrayLists first, since there are no field names in the
// returned JSON.
InputStream stream = root.retrieve().asStream(getApiTailUrl("stats/code_frequency"));

ObjectMapper mapper = new ObjectMapper();
TypeReference<ArrayList<ArrayList<Integer> > > typeRef =
new TypeReference<ArrayList< ArrayList<Integer> > >() {};
ArrayList<ArrayList <Integer> > list = mapper.readValue(stream, typeRef);

// Convert to proper objects.
ArrayList<CodeFrequency> returnList = new ArrayList<CodeFrequency>();
for(ArrayList<Integer> item: list)
{
CodeFrequency cf = new CodeFrequency(item);
returnList.add(cf);
}

return returnList;
}

public static class CodeFrequency {
private int week;
private int additions;
private int deletions;

private CodeFrequency(ArrayList<Integer> item) {
week = item.get(0);
additions = item.get(1);
deletions = item.get(2);
}

/**
* @return The start of the week as a UNIX timestamp.
*/
public int getWeekTimestamp() {
return week;
}

/**
* @return The number of additions for the week.
*/
public long getAdditions() {
return additions;
}

/**
* @return The number of deletions for the week.
* NOTE: This will be a NEGATIVE number.
*/
public long getDeletions() {
return deletions;
}

@Override
public String toString() {
return "Week starting " + getWeekTimestamp() + " has " + getAdditions() +
" additions and " + Math.abs(getDeletions()) + " deletions";
}
}

/**
* Get the weekly commit count for the repository owner and everyone else.
* See https://developer.github.com/v3/repos/statistics/#get-the-weekly-commit-count-for-the-repository-owner-and-everyone-else
*/
public Participation getParticipation() throws IOException {
return root.retrieve().to(getApiTailUrl("stats/participation"), Participation.class);
}

public static class Participation extends GHObject {
/*package almost final*/ private GitHub root;
private List<Integer> all;
private List<Integer> owner;

@Override
public URL getHtmlUrl() throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}

public GitHub getRoot() {
return root;
}

/**
* @return The list of commit counts for everyone combined, for the
* last 52 weeks.
*/
public List<Integer> getAllCommits() {
return all;
}

/**
* @return The list of commit counts for the owner, for the
* last 52 weeks.
*/
public List<Integer> getOwnerCommits() {
return owner;
}

/*package*/ Participation wrapUp(GitHub root) {
this.root = root;
return this;
}
}

/**
* Get the number of commits per hour in each day.
* See https://developer.github.com/v3/repos/statistics/#get-the-number-of-commits-per-hour-in-each-day
*/
public List<PunchCardItem> getPunchCard() throws IOException {
// Map to ArrayLists first, since there are no field names in the
// returned JSON.
InputStream stream = root.retrieve().asStream(getApiTailUrl("stats/punch_card"));

ObjectMapper mapper = new ObjectMapper();
TypeReference<ArrayList<ArrayList<Integer> > > typeRef =
new TypeReference<ArrayList< ArrayList<Integer> > >() {};
ArrayList<ArrayList <Integer> > list = mapper.readValue(stream, typeRef);

// Convert to proper objects.
ArrayList<PunchCardItem> returnList = new ArrayList<PunchCardItem>();
for(ArrayList<Integer> item: list) {
PunchCardItem pci = new PunchCardItem(item);
returnList.add(pci);
}

return returnList;
}

public static class PunchCardItem {
private int dayOfWeek;
private int hourOfDay;
private int numberOfCommits;

private PunchCardItem(ArrayList<Integer> item) {
dayOfWeek = item.get(0);
hourOfDay = item.get(1);
numberOfCommits = item.get(2);
}

/**
* @return The day of the week.
* 0 = Sunday, 1 = Monday, etc.
*/
public int getDayOfWeek() {
return dayOfWeek;
}

/**
* @return The hour of the day from 0 to 23.
*/
public long getHourOfDay() {
return hourOfDay;
}

/**
* @return The number of commits for the day and hour.
*/
public long getNumberOfCommits() {
return numberOfCommits;
}

public String toString() {
return "Day " + getDayOfWeek() + " Hour " + getHourOfDay() + ": " +
getNumberOfCommits() + " commits";
}
}

/**
* Render a Markdown document.
*
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/org/kohsuke/github/Requester.java
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,13 @@ private <T> T parse(Class<T> type, T instance, int timeouts) throws IOException
return type.cast(Array.newInstance(type.getComponentType(),0));
}

// Response code 202 means the statistics are still being cached.
// See https://developer.github.com/v3/repos/statistics/#a-word-about-caching
if (responseCode == 202) {
LOGGER.log(INFO, "The statistics are still being generated. Please try again in 5 seconds.");
return null;
}

r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8");
String data = IOUtils.toString(r);
if (type!=null)
Expand Down

0 comments on commit 706c946

Please sign in to comment.