Last active
December 20, 2015 20:38
-
-
Save monzou/6191398 to your computer and use it in GitHub Desktop.
Report outdated tickets from Redmine.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Map.Entry; | |
import javax.ws.rs.client.Client; | |
import javax.ws.rs.client.ClientBuilder; | |
import javax.ws.rs.core.MediaType; | |
import org.glassfish.jersey.filter.LoggingFilter; | |
import com.fasterxml.jackson.annotation.JsonProperty; | |
import com.fasterxml.jackson.databind.DeserializationFeature; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.google.common.base.Function; | |
import com.google.common.collect.Maps; | |
import com.google.common.collect.Ordering; | |
/** | |
* ReportOutdatedTickets | |
* | |
* @author monzou | |
*/ | |
public class ReportOutdatedTickets { | |
private static final boolean LOGGING_ENABLED = false; | |
private static final String REDMINE_URL = "PATH_TO_REDMINE"; | |
private static final String ISSUES_URL = String.format("%s/issues", REDMINE_URL); | |
private static final String ACCESS_KEY = "YOUR_ACCESS_KEY"; | |
private static final Integer QUERY_ID = YOUR_QUERY_ID; | |
private final API api; | |
private final Reporter reporter; | |
public static void main(String[] args) { | |
Reporter reporter = new Reporter() { | |
/** {@inheritDoc} */ | |
public void report(String message) { | |
System.out.println(message); | |
} | |
}; | |
try { | |
int resultCode = new ReportOutdatedTickets(reporter).report(QUERY_ID) ? 0 : -1; | |
System.exit(resultCode); | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
ReportOutdatedTickets(Reporter reporter) { | |
Client client = LOGGING_ENABLED ? ClientBuilder.newBuilder().register(LoggingFilter.class).build() : ClientBuilder.newClient(); | |
this.api = new API(client); | |
this.reporter = reporter; | |
} | |
boolean report(Integer queryId) throws IOException { | |
Issues issues = api.getIssues(queryId); | |
if (issues.isEmpty()) { | |
return true; | |
} | |
reporter.report(""); | |
reporter.report("--------------------------------------------------------------------------------------"); | |
reporter.report(" 期限切れチケット一覧"); | |
reporter.report("--------------------------------------------------------------------------------------"); | |
Map<String, Integer> counterByAssignee = Maps.newHashMap(); | |
for (Issue issue : issues.listByDueDate()) { | |
String assignee = issue.assigned.name; | |
Integer counter = counterByAssignee.get(assignee); | |
counterByAssignee.put(assignee, counter == null ? 1 : ++counter); | |
reporter.report(String.format("[ %s ] %s : %s", issue.dueDate, assignee, issue.subject)); | |
} | |
reporter.report(""); | |
reporter.report("--------------------------------------------------------------------------------------"); | |
reporter.report(" 期限切れチケット所有者ランキング"); | |
reporter.report("--------------------------------------------------------------------------------------"); | |
for (Entry<String, Integer> entry : Ordering.natural().reverse().onResultOf(new Function<Entry<String, Integer>, Integer>() { | |
/** {@inheritDoc} */ | |
public Integer apply(Entry<String, Integer> input) { | |
return input.getValue(); | |
} | |
}).sortedCopy(counterByAssignee.entrySet())) { | |
reporter.report(String.format("%s : %d", entry.getKey(), entry.getValue())); | |
} | |
reporter.report(""); | |
reporter.report(String.format("%s?query_id=%d", ISSUES_URL, queryId)); | |
return false; | |
} | |
private static class API { | |
private final Client client; | |
API(Client client) { | |
this.client = client; | |
} | |
Issues getIssues(Integer queryId) throws IOException { | |
String response = client.target(String.format("%s.json", ISSUES_URL)). // | |
queryParam("query_id", QUERY_ID). // | |
queryParam("key", ACCESS_KEY). // | |
request(MediaType.APPLICATION_JSON).get().readEntity(String.class); | |
return createMapper().readValue(response, Issues.class); | |
} | |
private ObjectMapper createMapper() { | |
ObjectMapper mapper = new ObjectMapper(); | |
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |
return mapper; | |
} | |
} | |
private static interface Reporter { | |
void report(String message); | |
} | |
private static class Issues { | |
public List<Issue> issues; | |
List<Issue> listByDueDate() { | |
return Ordering.natural().nullsLast().onResultOf(new Function<Issue, String>() { | |
/** {@inheritDoc} */ | |
public String apply(Issue input) { | |
return input.dueDate; | |
} | |
}).sortedCopy(issues); | |
} | |
boolean isEmpty() { | |
return issues.isEmpty(); | |
} | |
} | |
static class Issue { | |
public Long id; | |
public String subject; | |
public String description; | |
@JsonProperty("start_date") | |
public String startDate; | |
@JsonProperty("due_date") | |
public String dueDate; | |
public Field project; | |
public Field tracker; | |
public Field status; | |
public Field priority; | |
public Field author; | |
@JsonProperty("assigned_to") | |
public Field assigned; | |
public Field category; | |
@JsonProperty("fixed_version") | |
public Field version; | |
} | |
static class Field { | |
public Long id; | |
public String name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment