-
Notifications
You must be signed in to change notification settings - Fork 1
/
gh-query.controller.ts
134 lines (117 loc) · 3.99 KB
/
gh-query.controller.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Uncomment these imports to begin using these cool features!
import {inject} from '@loopback/context';
import {get, getModelSchemaRef, param} from '@loopback/openapi-v3';
import {QueryResult, ResultIssueInfo} from '../models';
import {GhQueryService, IssueInfo, QueryResponse} from '../services';
// import {inject} from '@loopback/core';
export class GhQueryController {
// inject the GhQueryService service proxy
constructor(@inject('services.GhQueryService') protected queryService:GhQueryService) {}
// create the API that get the issues by providing:
// repo: <GitHub org>/<GitHub repo>. For example, `strongloop/loopback-next`
// label: If it has special characters, you need to escape it.
// For example, if the label is "help wanted", it will be "help+wanted".
@get('/issues/repo/{repo}/label/{label}', {
responses: {
'200': {
description: 'Array of GitHub issues info',
content: {
'application/json': {
schema: getModelSchemaRef(QueryResult)
}
}
}
}
})
async getIssuesByLabel(
@param.path.string('repo') repo: string,
@param.path.string('label') label:string): Promise<QueryResult> {
let result:QueryResponse = await this.queryService.getIssuesByLabel(repo, label);
let queryResult = new QueryResult();
queryResult.items = [];
queryResult.total_count = result.body.total_count;
result.body.items.forEach(issue => {
this.addToResult(issue, queryResult);
});
// check if there is next page of the results
const nextLink = this.getNextLink(result.headers.link);
if (nextLink == null) return queryResult;
await this.getIssueByURL(nextLink, this.queryService, queryResult);
return queryResult;
}
/**
* Get issues from URL
* @param nextLinkURL
* @param queryService
* @param queryResult
* @returns
*/
async getIssueByURL(nextLinkURL: string, queryService: GhQueryService, queryResult:QueryResult) {
let result = await queryService.getIssuesByURL(nextLinkURL);
result.body.items.forEach(issue => {
this.addToResult(issue, queryResult);
});
const nextLink2 = this.getNextLink(result.headers.link);
if (nextLink2 == null) return;
await this.getIssueByURL(nextLink2, queryService, queryResult);
}
/**
* Get the URL for the "next" page.
* The Link header is in the format of:
* Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=2>; rel="next",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last"
* @param link
* @returns
*/
getNextLink(link: string): string|null {
if (link == undefined) return null;
let tokens: string[] = link.split(',');
let url: string|null = null;
tokens.forEach(token => {
if (token.indexOf('rel="next"')!=-1) {
url = token.substring(token.indexOf('<')+1, token.indexOf(';')-1);
}
});
return url;
}
/**
* Add the issue to the QueryResult object
* @param issue
* @param queryResult
*/
addToResult(issue: IssueInfo, queryResult: QueryResult) {
let issueInfo:ResultIssueInfo = new ResultIssueInfo();
issueInfo.html_url = issue.html_url;
issueInfo.title = issue.title;
issueInfo.state = issue.state;
issueInfo.age = this.getIssueAge(issue.created_at);
queryResult.items?.push(issueInfo);
}
/**
* Calculate the age of the issue
* i.e. take today's date and find the number of days difference from
* the issue creation date
* @param created_at
* @returns
*/
getIssueAge(created_at: string): number {
let todayDate: Date = new Date();
let createDate: Date = new Date(created_at);
let differenceInTime = todayDate.getTime() - createDate.getTime();
//get the difference in day
return Math.floor(differenceInTime / (1000 * 3600 * 24));
}
}
// /**
// * QueryResult
// */
// class QueryResult {
// total_count: number;
// items: ResultIssueInfo[];
// }
// class ResultIssueInfo {
// title: string;
// html_url: string;
// state: string;
// age: number;
// }