[whiteship 라이브스터디]github.com/whiteship/live-study
이번에는 live-study 의 대시 보드 작성 과제를 작성할 것이다
요구사항은 아래 이미지와 같다
사실 이미지 중에 위에 두 가지가 이번 과제에 대한 요구사항인 것 같다.
이미지 상에 명시된 Github 자바 라이브러리의 링크 => github-api.kohsuke.org/
위의 API 를 사용하면 Github의 많은 동작을 사용할 수 있다.
그리고 이번 과제를 사용하면서 많이 봤던 apidocs...
이 문서를 보면 이번 과제를 해결하는데에는 크게 어려움은 없어보인다..(과연??)
github-api.kohsuke.org/apidocs/org/kohsuke/github/package-summary.html
그럼 어떻게 과제를 수행했는지 살펴보자
▶ 시작은 github api 에 연결하는거 부터
처음에는 이 과제를 git에 따로 올릴 것도 아니어서 git의 유저이름과 비밀번호를 가지고 인증하려고 했었다.
GitHub github = new GithubBuilder()
.withPassword("my-user-name", "my-password")
.build();
하지만 위와 같은 방법으로 인증을 시도하면 아래와 같은 에러 메세지를 볼 수 있다
<에러메세지 이미지 삽입>
그래서 어떻게 할까... 하다가 github 에서 OAuth 토큰을 생성하고 그 토큰을 가지고
인증을 진행하기로 했다.
※Github OAuth 토큰 발급 받는 방법
1. 먼저 github.com/settings/tokens로 진입한다
2. Generate new token 버튼을 클릭한다
3. 인증을 진행하고..
4. 이 화면 하단에서 Generate Token 버튼을 클릭하면 생성 완료! (체크박스는 아무것도 체크 안해도 된다)
¡ 주의사항
토큰이 생성되고 나면 토큰 목록 페이지에 우리가 생성한 토큰이 보여진다.
그런데 이 때 이 토큰을 어딘가에 보관해놓지 않으면 다시는 볼 수 없으므로 주의해야한다..
☞ 이제 토큰을 가지고 인증을 진행해보자
GitHub github = new GitHubBuilder().withOAuthToken("your-token").build();
your-token 자리에 여러분의 토큰을 집어넣으면 인증은 완료되고,
github 변수를 통해서 이 라이브러리에서 제공하는 다양한 API 를 이용해서 github 조작이 가능하다.
▶ 이제 우리가 관심있는 저장소의 Issue 에 접근을 해보자
저장소의 Issue 에 접근을 하려면 아래의 API 를 통해서 먼저 저장소 객체를 가져와야 한다
이제 코드로 어떻게 가져오는지 보자
GHRepository repository = github.getRepository("whiteship/live-study");
위의 API 설명에 나와있는대로, owner/repo 이름 형태의 문자열을 getRepository 메소드의 인자로 전달해주면
repository 변수를 이용해서 저장소의 issue 에 접근할 수 있게 된다.
issue 를 가져오기 위해서는 아래의 메소드를 이용하면 된다
위 메소드는 GHIssueState 타입의 인자를 받는데, 뜯어보면 enum 으로 되어있으며 ALL, CLOSED, OPEN 상태가 존재한다.
요구사항은 18일차에 대한 참여율을 구하는 것이고, issue 에는 이미 18일차까지의 Issue 가 생성되어 있다
생성된 Issue 중에는 OPEN 된 것도 있고 CLOSED 된 것도 있기 때문에 GHIssueState.ALL 을 인자로 전달하여
Issue 에 존재하는 모든 issue 들을 가져올 수 있도록 했다
List<GHIssue> issueList = repository.getIssues(GHIssueState.ALL);
▶ 각 Issue 에 달린 comment 들에 접근해보자!
Issue 들에 달린 comment 의 목록을 가져오는 API 는 아래와 같다
이미 issue 들을 순회하고 있고, 현재 issue 에 대한 comment 를 가져오면 되니까 아래처럼 작성하면 된다.
List<GHIssueComment> comments = issue.getComments();
이제 위의 메소드를 통해 구한 comment의 목록을 순회하면서 작성자들의 이름을 세면 된다
▶ comment 의 작성자를 가져와보자
GHIssueComment 클래스에는 유저의 정보를 가져올 수 있는 메소드가 존재한다
그리고 GHUser 의 API 를 살펴보니 딱 봐도 이름을 가져올 수 있는 메소드가 눈에 띄었다
그런데 이 메소드를 통해서 가져오게 되면 null 을 출력할 때가 있다
왜냐하면 유저이름을 설정하지 않은 사용자도 있기 때문에 그런 것 같다
그래서 대표적으로 보이는 이름을 가져오려면 어떻게 해야되나 하고 찾아보니 딱 맞는 메소드가 있다
위 메소드를 통해서 이름을 가져오면 null 을 출력하는 일이 없다
위에 나열된 내용을 가지고 코드를 작성하면 과제를 충분하게 수행할 수 있을 것이다
∴ 결론
- 공식문서에 API 에 대한 예제가 적어 애를 먹었다. (하지만 문서와 설명을 잘 보니 삽질을 했지만 해쳐나갈만 했다)
- 예외처리 할 것들이 있었다.
1. 현재 해당 저장소 issue 의 목록은 18개가 아닌 19개이다 (왜냐하면 다른 사용자가 올린 issue도 있기 때문)
owner 가 발행한 issue 에는 label 이 하나 이상 붙어있으므로 그걸 통해 걸러냈다
2. 하나의 issue 에 코멘트를 여러 개 달아놓은 사용자도 있다. 코멘트를 하나만 세도록 처리하는 작업도 필요했다
- VO 객체 비스무리 하게 만들어서 진행할까 했지만 간단하게 Map 을 통해서 진행했다. 그리고 사실 방법이 잘 떠오르지 않았다..
- 내가 짠 코드가 엉망이어서 그런지..... 이 코드를 수행하는 걸리는 시간이 꽤 걸린다ㅠㅠ
그리고 이번 과제를 계기로 처음 블로그에 글도 써보고, 자바를 다시 스터디 하게 되었다.
블로그에 기술관련 글들 등등을 써보고 싶다는 생각을 하고만 있었는데,
백기선님께서 주최하신 스터디 덕분에 실천으로 옮길 수 있게 되었다
이런 귀한 경험을 하게 해주신 백기선님께 감사드립니다!
[전체코드]
package com.live_study.chulphan;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHIssueComment;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
public class App
{
public static void main( String[] args )
{
try {
GitHub github = new GitHubBuilder().withOAuthToken("enter-your-api-key").build();
GHRepository repository = github.getRepository("whiteship/live-study");
List<GHIssue> issueList = repository.getIssues(GHIssueState.ALL);
issueList = issueList
.stream()
.filter(issue -> issue.getLabels().size() > 0)
.collect(Collectors.toList());
final int numOfHomework = issueList.size();
Map<String, Integer> attendeeList = new HashMap<String, Integer>();
Map<String, Double> attendeeListWithAttendanceRate = new HashMap<String, Double>();
for (GHIssue issue: issueList) {
if (issue.getState().equals(GHIssueState.OPEN)) {
continue;
}
List<String> tempUserNameList = new ArrayList<String>();
for (GHIssueComment comment: issue.getComments()) {
String attendeeName = comment.getUser().getLogin();
if (!tempUserNameList.contains(attendeeName)) {
tempUserNameList.add(attendeeName);
}
}
for (String attendeeName: tempUserNameList) {
if (attendeeList.containsKey(attendeeName)) {
int numOfAttendance = attendeeList.get(attendeeName);
attendeeList.put(attendeeName, ++numOfAttendance);
} else {
attendeeList.put(attendeeName, 1);
}
}
}
for (String attendee: attendeeList.keySet()) {
BigDecimal bd = new BigDecimal(attendeeList.get(attendee) / ((double) numOfHomework)).setScale(2, RoundingMode.HALF_UP);
double attendanceRate = bd.doubleValue();
attendeeListWithAttendanceRate.put(attendee, attendanceRate);
}
for (Map.Entry<String, Double> entry: attendeeListWithAttendanceRate.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
} catch (Exception e) {
System.out.println(e);
}
}
}
'공부 > whiteship-java' 카테고리의 다른 글
7주차: 패키지 (0) | 2021.01.01 |
---|---|
6주차: 상속 (0) | 2020.12.24 |
5주차: 클래스 (0) | 2020.12.19 |
4주차 과제: JUnit5 (0) | 2020.12.11 |
4주차: 조건문, 반복문 (0) | 2020.12.10 |