🚀 refactor github contribution

This commit is contained in:
platane
2020-10-20 19:43:05 +02:00
parent 0fc64a0dab
commit d75d3d76e7
3 changed files with 107 additions and 28 deletions

View File

@@ -1,4 +1,75 @@
import { JSDOM } from "jsdom";
import fetch from "node-fetch";
import * as parser from "fast-xml-parser";
// const traverse = (
// o: any,
// callback: (elements: { name: string; "#text": string; attrs: any }[]) => void,
// path: { name: string; "#text": string; attrs: any }[] = []
// ) => {
// if (o && typeof o === "object")
// Object.entries(o)
// .filter(([o]) => o !== "attr" && o !== "#text")
// .forEach(([name, v]) => {
// const el = { name, attrs: v.attrs, "#text": v["#text"] };
// const p = [el, ...path];
// callback(p);
// traverse(v, callback, p);
// });
// };
const findNode = (o: any, condition: (x: any) => boolean): any => {
if (o && typeof o === "object") {
if (condition(o)) return o;
for (const c of Object.values(o)) {
const res = findNode(c, condition);
if (res) return res;
}
}
};
const parseUserPage = (content: string) => {
const o = parser.parse(content, {
attrNodeName: "attr",
attributeNamePrefix: "",
ignoreAttributes: false,
});
//
// parse colorScheme
const legend = findNode(
o,
(x) => x.attr && x.attr.class && x.attr.class.trim() === "legend"
);
const colorScheme = legend.li.map(
(x: any) => x.attr.style.match(/background\-color: +(#\w+)/)![1]!
);
//
// parse cells
const svg = findNode(
o,
(x) =>
x.attr && x.attr.class && x.attr.class.trim() === "js-calendar-graph-svg"
);
const cells = svg.g.g
.map((g: any, x: number) =>
g.rect.map(({ attr }: any, y: number) => {
const color = attr.fill;
const count = +attr["data-count"];
const date = attr["data-date"];
const k = colorScheme.indexOf(color);
return { x, y, color, count, date, k };
})
)
.flat();
return { cells, colorScheme };
};
/**
* get the contribution grid from a github user page
@@ -6,31 +77,10 @@ import { JSDOM } from "jsdom";
* @param userName
*/
export const getGithubUserContribution = async (userName: string) => {
const dom = await JSDOM.fromURL(`https://github.com/${userName}`);
const res = await fetch(`https://github.com/${userName}`);
const resText = await res.text();
const colorScheme = Array.from(
dom.window.document.querySelectorAll(".legend > li")
).map(
(element) =>
element.getAttribute("style")!.match(/background\-color: +(#\w+)/)![1]!
);
const cells = Array.from(
dom.window.document.querySelectorAll(".js-calendar-graph-svg > g > g")
)
.map((column, x) =>
Array.from(column.querySelectorAll("rect")).map((element, y) => {
const count = +element.getAttribute("data-count")!;
const date = element.getAttribute("data-date")!;
const color = element.getAttribute("fill")!;
const k = colorScheme.indexOf(color);
return { x, y, count, date, color, k };
})
)
.flat();
return { colorScheme, cells };
return parseUserPage(resText);
};
type ThenArg<T> = T extends PromiseLike<infer U> ? U : T;

View File

@@ -2,9 +2,11 @@
"name": "@snk/github-user-contribution",
"version": "1.0.0",
"dependencies": {
"jsdom": "16.4.0"
"node-fetch": "2.6.1",
"fast-xml-parser": "3.17.4"
},
"devDependencies": {
"@types/node-fetch": "2.5.7",
"@types/jsdom": "16.2.4"
}
}

View File

@@ -629,6 +629,14 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node-fetch@2.5.7":
version "2.5.7"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c"
integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*":
version "14.0.23"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.23.tgz#676fa0883450ed9da0bb24156213636290892806"
@@ -1737,7 +1745,7 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
combined-stream@^1.0.6, combined-stream@~1.0.6:
combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -2678,6 +2686,11 @@ fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fast-xml-parser@3.17.4:
version "3.17.4"
resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.17.4.tgz#d668495fb3e4bbcf7970f3c24ac0019d82e76477"
integrity sha512-qudnQuyYBgnvzf5Lj/yxMcf4L9NcVWihXJg7CiU1L+oUCq8MUnFEfH2/nXR/W5uq+yvUN1h7z6s7vs2v1WkL1A==
faye-websocket@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@@ -2796,6 +2809,15 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
integrity sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
@@ -4118,7 +4140,7 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsdom@16.4.0, jsdom@^16.4.0:
jsdom@^16.4.0:
version "16.4.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.4.0.tgz#36005bde2d136f73eee1a830c6d45e55408edddb"
integrity sha512-lYMm3wYdgPhrl7pDcRmvzPhhrGVBeVhPIqeHjzeiHN3DFmD1RBpbExbi8vU7BJdH8VAZYovR8DMt0PNNDM7k8w==
@@ -4652,6 +4674,11 @@ no-case@^3.0.3:
lower-case "^2.0.1"
tslib "^1.10.0"
node-fetch@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-forge@^0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"