Compare commits

..
3 Commits
Author SHA1 Message Date
anuraghazra ce30d4eeb0 chore: docs update 2020-07-09 22:53:53 +05:30
anuraghazra 4f99f08b64 docs: alignment tip 2020-07-09 22:48:20 +05:30
anuraghazra d41462ddf1 docs: added Github Extra pins docs 2020-07-09 22:42:54 +05:30
4 changed files with 74 additions and 130 deletions
+12 -19
View File
@@ -1,10 +1,7 @@
const axios = require("axios");
const { renderError, kFormatter } = require("../utils");
require("dotenv").config();
async function fetchStats(username) {
if (!username) throw Error("Invalid username");
const res = await axios({
url: "https://api.github.com/graphql",
method: "post",
@@ -52,11 +49,7 @@ async function fetchStats(username) {
totalStars: 0,
contributedTo: 0,
};
if (res.data.errors) {
console.log(res.data.errors);
throw Error("Could not fetch user");
}
if (res.data.error) return stats;
const user = res.data.data.user;
@@ -74,11 +67,12 @@ async function fetchStats(username) {
}
const createTextNode = (icon, label, value, lheight) => {
const classname = icon === "★" && "star-icon";
return `
<tspan x="25" dy="${lheight}" class="stat bold">
<tspan class="icon ${classname}" fill="#4C71F2">${icon}</tspan> ${label}:</tspan>
<tspan x="155" dy="0" class="stat">${kFormatter(value)}</tspan>
<tspan class="icon ${
icon === "★" && "star-icon"
}" fill="#4C71F2">${icon}</tspan> ${label}:</tspan>
<tspan x="155" dy="0" class="stat">${value}</tspan>
`;
};
@@ -135,16 +129,15 @@ const renderSVG = (stats, options) => {
};
module.exports = async (req, res) => {
const { username, hide, hide_border, show_icons, line_height } = req.query;
let stats;
const username = req.query.username;
const hide = req.query.hide;
const hide_border = req.query.hide_border;
const show_icons = req.query.show_icons;
const line_height = req.query.line_height;
const stats = await fetchStats(username);
res.setHeader("Content-Type", "image/svg+xml");
try {
stats = await fetchStats(username);
} catch (err) {
return res.send(renderError(err.message));
}
res.send(
renderSVG(stats, {
hide: JSON.parse(hide || "[]"),
+48 -69
View File
@@ -1,5 +1,4 @@
const axios = require("axios");
const { renderError, kFormatter, encodeHTML } = require("../utils");
require("dotenv").config();
async function fetchRepo(username, reponame) {
@@ -11,28 +10,35 @@ async function fetchRepo(username, reponame) {
},
data: {
query: `
fragment RepoInfo on Repository {
name
stargazers {
totalCount
}
description
primaryLanguage {
color
id
name
}
forkCount
}
query getRepo($login: String!, $repo: String!) {
user(login: $login) {
repository(name: $repo) {
...RepoInfo
name
stargazers {
totalCount
}
description
primaryLanguage {
color
id
name
}
forkCount
}
}
organization(login: $login) {
repository(name: $repo) {
...RepoInfo
name
stargazers {
totalCount
}
description
primaryLanguage {
color
id
name
}
forkCount
}
}
}
@@ -44,39 +50,21 @@ async function fetchRepo(username, reponame) {
},
});
const data = res.data.data;
if (res.data.error && res.data.error.type !== "NOT_FOUND") return {};
if (!res.data.data.organization && res.data.data.user)
return res.data.data.user.repository;
if (!data.user && !data.organization) {
throw new Error("Not found");
}
const isOrg = res.data.data.organization && !res.data.data.user;
if (isOrg) return res.data.data.organization.repository;
if (data.organization === null && data.user) {
if (!data.user.repository) {
throw new Error("User Repository Not found");
}
return data.user.repository;
}
if (data.user === null && data.organization) {
if (!data.organization.repository) {
throw new Error("Organization Repository Not found");
}
return data.organization.repository;
}
return res.data.data.user.repository;
}
const renderRepoCard = (repo) => {
const { name, description, primaryLanguage, stargazers, forkCount } = repo;
const height = 120;
const shiftText = primaryLanguage.name.length > 15 ? 0 : 30;
let desc = description || "No description provided";
if (desc.length > 55) {
desc = `${description.slice(0, 55)}..`;
}
return `
<svg width="400" height="${height}" viewBox="0 0 400 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="400" height="${height}" viewBox="0 0 400 ${height}" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
.header { font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
.stat { font: 600 14px 'Segoe UI', Ubuntu, Sans-Serif; fill: #333 }
@@ -91,42 +79,33 @@ const renderRepoCard = (repo) => {
</svg>
<text x="50" y="38" class="header">${name}</text>
<text class="description" x="25" y="70">${encodeHTML(desc)}</text>
<text class="description" x="25" y="70">${description.slice(
0,
60
)}..</text>
<g transform="translate(30, 100)">
<circle cx="0" cy="-5" r="6" fill="${primaryLanguage.color}" />
<text class="gray" x="15">${primaryLanguage.name}</text>
</g>
<g transform="translate(${155 - shiftText}, 100)">
<svg y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
<path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path>
</svg>
<text class="gray" x="25">${kFormatter(stargazers.totalCount)}</text>
</g>
<circle cx="30" cy="95" r="6" fill="${primaryLanguage.color}" />
<svg x="120" y="88" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
<path fill-rule="evenodd" d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25zm0 2.445L6.615 5.5a.75.75 0 01-.564.41l-3.097.45 2.24 2.184a.75.75 0 01.216.664l-.528 3.084 2.769-1.456a.75.75 0 01.698 0l2.77 1.456-.53-3.084a.75.75 0 01.216-.664l2.24-2.183-3.096-.45a.75.75 0 01-.564-.41L8 2.694v.001z"></path>
</svg>
<g transform="translate(${220 - shiftText}, 100)">
<svg y="-12" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
<path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>
</svg>
<text class="gray" x="25">${kFormatter(forkCount)}</text>
</g>
<svg x="190" y="88" viewBox="0 0 16 16" version="1.1" width="16" height="16" fill="#586069">
<path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>
</svg>
<text class="gray" x="45" y="100">${primaryLanguage.name}</text>
<text class="gray" x="145" y="100">${stargazers.totalCount}</text>
<text class="gray" x="210" y="100">${forkCount}</text>
</svg>
`;
};
module.exports = async (req, res) => {
const { username, repo } = req.query;
const username = req.query.username;
const repo = req.query.repo;
const repoData = await fetchRepo(username, repo);
let repoData;
res.setHeader("Content-Type", "image/svg+xml");
try {
repoData = await fetchRepo(username, repo);
} catch (err) {
console.log(err);
return res.send(renderError(err.message));
}
res.send(renderRepoCard(repoData));
};
+14 -14
View File
@@ -1,6 +1,6 @@
## Github Readme stats
Get dynamically generated GitHub stats on your readmes!
Get dynamically generated github stats on your readmes!
# Features
@@ -9,17 +9,17 @@ Get dynamically generated GitHub stats on your readmes!
# Github Stats Card
Copy paste this into your markdown content, and that's it. Simple!
Copy paste this into your markdown content and thats it. simple!
change the `?username=` value to your GitHubs's username
```md
[![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats)
![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=anuraghazra)
```
### Hiding individual stats
### Hiding certain stats
To hide any specific stats, you can pass a query parameter `?hide=` with an array of items, you wanna hide.
To hide any specific stats you can pass a query parameter `?hide=` with an array of items you wanna hide.
> Options: `&hide=["stars","prs","issues","contribs"]`
@@ -29,7 +29,7 @@ To hide any specific stats, you can pass a query parameter `?hide=` with an arra
### Showing icons
To enable icons, you can pass `show_icons=true` in the query param like so
To enable icons you can pass `show_icons=true` in the query param like so
```md
![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show_icons=true)
@@ -56,34 +56,34 @@ Other options:
# Github Extra Pins
Github extra pins allow you to pin more than 6 repositories in your profile using a GitHub readme profile.
Github extra pins allows you to pin more than 6 repositories in your profile by using github readme profile.
Yey! you are no longer limited to 6 pinned repositories.
Yey! you are no longer limited to 6 pinned repos
### Usage
Copy-paste this code into your readme and change the links.
Copy paste this code into your readme and change the links.
Endpoint: `api/pin?username=anuraghazra&repo=github-readme-stats`
```md
[![ReadMe Card](https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats)
[![ReadMe Card](https://github-readme-stats.anuraghazra1.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats)
```
### Demo
[![ReadMe Card](https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats)
[![ReadMe Card](https://github-readme-stats.anuraghazra1.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats)](https://github.com/anuraghazra/github-readme-stats)
### Quick Tip (Align The Repo Cards)
You usually won't be able to layout the images side by side to do that you can use this approach
Normally you won't be able to layout the images side by side to do that you can use this approach
```md
<a href="https://github.com/anuraghazra/github-readme-stats">
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
<img align="left" src="https://github-readme-stats.anuraghazra1.vercel.app/api/pin/?username=anuraghazra&repo=github-readme-stats" />
</a>
<a href="https://github.com/anuraghazra/convoychat">
<img align="left" src="https://github-readme-stats.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
<img align="left" src="https://github-readme-stats.anuraghazra1.vercel.app/api/pin/?username=anuraghazra&repo=convoychat" />
</a>
```
-28
View File
@@ -1,28 +0,0 @@
const renderError = (message) => {
return `
<svg width="495" height="100" viewBox="0 0 495 100" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #252525 }
</style>
<rect x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
<text x="25" y="45" class="text">Something went wrong! file an issue at https://git.io/JJmN9</text>
<text x="25" y="65" class="text small">${message}</text>
</svg>
`;
};
// https://stackoverflow.com/a/48073476/10629172
function encodeHTML(str) {
return str.replace(/[\u00A0-\u9999<>&](?!#)/gim, function (i) {
return "&#" + i.charCodeAt(0) + ";";
});
}
function kFormatter(num) {
return Math.abs(num) > 999
? Math.sign(num) * (Math.abs(num) / 1000).toFixed(1) + "k"
: Math.sign(num) * Math.abs(num);
}
module.exports = { renderError, kFormatter, encodeHTML };