-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOpenRankDetails.ts
115 lines (104 loc) · 3.28 KB
/
OpenRankDetails.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
import * as XLSX from "xlsx";
import {
getXSOSIReposInEachMonth,
Month,
RepoName,
RawOpenRankDetail,
getOpenRankDetail,
} from "./api";
import { DIRNAME_SHEETS, FILENAME_SHEET_OPENRANK_DETAILS } from "./const";
interface Record {
month: Month;
repo: string; // only repo name, no owner name
user: string;
from: string; // a "from" can be an issue, pr, or user
value: number; // the value that the "from" contributes to the user openrank
}
export default class OpenRankDetails {
private reposInEachMonth: Map<Month, RepoName[]>;
private rawDetails: Map<Month, Map<RepoName, RawOpenRankDetail>>;
private records: Record[];
constructor() {
this.reposInEachMonth = new Map();
this.rawDetails = new Map();
this.records = [];
}
async init() {
await this.loadReposInEachMonth();
await this.loadRawDetails();
this.generateRecords();
}
private async loadReposInEachMonth() {
this.reposInEachMonth = await getXSOSIReposInEachMonth();
}
private async loadRawDetails() {
for (const [month, repos] of this.reposInEachMonth) {
for (const repo of repos) {
if (!this.rawDetails.has(month)) {
this.rawDetails.set(
month,
new Map([[repo, await getOpenRankDetail(repo, month)]])
);
} else {
this.rawDetails
.get(month)
.set(repo, await getOpenRankDetail(repo, month));
}
}
}
}
private formatFromName(fromNode: any) {
if (fromNode.c === "i" || fromNode.c === "p") {
return `#${fromNode.n}`;
}
return fromNode.n;
}
private generateRecords() {
for (const [month, details] of this.rawDetails) {
for (const [repo, detail] of details) {
const nodes = detail.nodes;
const links = detail.links;
nodes
.filter((node) => node.c === "u")
.forEach((userNode) => {
// the "Self" record
this.records.push({
month,
repo: repo.split("/")[1], // drop owner name
user: userNode.n,
from: "Self",
value: userNode.i * userNode.r,
});
// other rocords
links
.filter((link) => link.t === userNode.id)
.forEach((link) => {
const fromNode = nodes.find((node) => node.id === link.s);
if (fromNode) {
this.records.push({
month,
repo: repo.split("/")[1], // drop owner name
user: userNode.n,
from: this.formatFromName(fromNode),
value: (1 - userNode.r) * link.w * fromNode.v,
});
} else { // for more info: https://github.com/X-lab2017/scripts-for-xlab-ospo-dashboard/issues/1
console.log(
`Cannot find node with id ${link.s} in repo ${repo}, ${month}`
);
}
});
});
}
}
}
printRecords() {
console.table(this.records);
}
dump2xlsx() {
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.json_to_sheet(this.records);
XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
XLSX.writeFile(wb, `${DIRNAME_SHEETS}/${FILENAME_SHEET_OPENRANK_DETAILS}`);
}
}