Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

count_forks option for Lang cards and hide_border option for Repo cards #480

Closed
wants to merge 11 commits into from
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
*.json
*.md
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "none",
"useTabs": false,
"endOfLine": "lf",
"proseWrap": "always"
}
8 changes: 5 additions & 3 deletions api/pin.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {
renderError,
parseBoolean,
clampValue,
CONSTANTS,
CONSTANTS
} = require("../src/common/utils");
const fetchRepo = require("../src/fetchers/repo-fetcher");
const renderRepoCard = require("../src/cards/repo-card");
Expand All @@ -13,13 +13,14 @@ module.exports = async (req, res) => {
const {
username,
repo,
hide_border,
title_color,
icon_color,
text_color,
bg_color,
theme,
show_owner,
cache_seconds,
cache_seconds
} = req.query;

let repoData;
Expand Down Expand Up @@ -56,12 +57,13 @@ module.exports = async (req, res) => {

return res.send(
renderRepoCard(repoData, {
hide_border,
title_color,
icon_color,
text_color,
bg_color,
theme,
show_owner: parseBoolean(show_owner),
show_owner: parseBoolean(show_owner)
})
);
} catch (err) {
Expand Down
14 changes: 10 additions & 4 deletions api/top-langs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const {
clampValue,
parseBoolean,
parseArray,
CONSTANTS,
CONSTANTS
} = require("../src/common/utils");
const fetchTopLanguages = require("../src/fetchers/top-languages-fetcher");
const renderTopLanguages = require("../src/cards/top-languages-card");
Expand All @@ -24,17 +24,23 @@ module.exports = async (req, res) => {
cache_seconds,
layout,
langs_count,
count_forks,
exclude_repo
} = req.query;
let topLangs;

res.setHeader("Content-Type", "image/svg+xml");

if (blacklist.includes(username)) {
return res.send(renderError("Something went wrong"));
}

try {
topLangs = await fetchTopLanguages(username, langs_count);
topLangs = await fetchTopLanguages(
username,
langs_count,
count_forks,
parseArray(exclude_repo)
);

const cacheSeconds = clampValue(
parseInt(cache_seconds || CONSTANTS.TWO_HOURS, 10),
Expand All @@ -54,7 +60,7 @@ module.exports = async (req, res) => {
text_color,
bg_color,
theme,
layout,
layout
})
);
} catch (err) {
Expand Down
32 changes: 25 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ You can customize the appearance of your `Stats Card` or `Repo Card` however you
- `text_color` - Body text color _(hex color)_
- `icon_color` - Icons color if available _(hex color)_
- `bg_color` - Card's background color _(hex color)_ **or** a gradient in the form of _angle,start,end_
- `hide_border` - Hides the card's border _(boolean)_
- `theme` - name of the theme, choose from [all available themes](./themes/README.md)
- `cache_seconds` - set the cache header manually _(min: 1800, max: 86400)_

Expand Down Expand Up @@ -166,16 +167,17 @@ You can provide multiple comma-separated values in bg_color option to render a g
- `hide_title` - _(boolean)_
- `layout` - Switch between two available layouts `default` & `compact`
- `card_width` - Set the card's width manually _(number)_
- `count_forks` - Whether to count languages of forks, default: false _(boolean)_
- `exclude_repo` - Exclude specified repositories _(Comma-separated values)_
- `langs_count` - Show more languages on the card, between 1-10, defaults to 5 _(number)_

> :warning: **Important:**
> Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
> :warning: **Important:**
> Language names should be uri-escaped, as specified in [Percent Encoding](https://en.wikipedia.org/wiki/Percent-encoding)
> (i.e: `c++` should become `c%2B%2B`, `jupyter notebook` should become `jupyter%20notebook`, etc.)

#### Wakatime Card Exclusive Options:

- `hide_title` - _(boolean)_
- `hide_border` - _(boolean)_
- `line_height` - Sets the line-height between text _(number)_
- `hide_progress` - Hides the progress bar and percentage _(boolean)_

Expand Down Expand Up @@ -221,6 +223,22 @@ Endpoint: `api/top-langs?username=anuraghazra`
[![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra)](https://github.com/anuraghazra/github-readme-stats)
```

### Count languages of forks

You can use `?count_forks=true` parameter to count languages of forks.

```md
[![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&count_forks=true)](https://github.com/anuraghazra/github-readme-stats)
```

### Exclude individual repositories

You can use `?exclude_repo=repo1,repo2` parameter to exclude individual repositories.

```md
[![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=anuraghazra&exclude_repo=reakit,gatsby)](https://github.com/anuraghazra/github-readme-stats)
```

### Hide individual languages

You can use `?hide=language1,language2` parameter to hide individual languages.
Expand Down Expand Up @@ -342,16 +360,16 @@ NOTE: Since [#58](https://github.com/anuraghazra/github-readme-stats/pull/58) we
<summary><b> Guide on setting up Vercel 🔨 </b></summary>

1. Go to [vercel.com](https://vercel.com/)
1. Click on `Log in`
1. Click on `Log in`
![](https://files.catbox.moe/tct1wg.png)
1. Sign in with GitHub by pressing `Continue with GitHub`
1. Sign in with GitHub by pressing `Continue with GitHub`
![](https://files.catbox.moe/btd78j.jpeg)
1. Sign into GitHub and allow access to all repositories, if prompted
1. Fork this repo
1. Go back to your [Vercel dashboard](https://vercel.com/dashboard)
1. Select `Import Project`
1. Select `Import Project`
![](https://files.catbox.moe/qckos0.png)
1. Select `Import Git Repository`
1. Select `Import Git Repository`
![](https://files.catbox.moe/pqub9q.png)
1. Select root and keep everything as is, just add your environment variable named PAT_1 (as shown), which will contain a personal access token (PAT), which you can easily create [here](https://github.com/settings/tokens/new) (leave everything as is, just name it something, it can be anything you want)
![](https://files.catbox.moe/0ez4g7.png)
Expand Down
19 changes: 10 additions & 9 deletions src/cards/repo-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {
encodeHTML,
getCardColors,
FlexLayout,
wrapTextMultiline,
wrapTextMultiline
} = require("../common/utils");
const icons = require("../common/icons");
const Card = require("../common/Card");
Expand All @@ -18,15 +18,16 @@ const renderRepoCard = (repo, options = {}) => {
stargazers,
isArchived,
isTemplate,
forkCount,
forkCount
} = repo;
const {
hide_border,
title_color,
icon_color,
text_color,
bg_color,
show_owner,
theme = "default_repocard",
theme = "default_repocard"
} = options;

const header = show_owner ? nameWithOwner : name;
Expand Down Expand Up @@ -55,7 +56,7 @@ const renderRepoCard = (repo, options = {}) => {
icon_color,
text_color,
bg_color,
theme,
theme
});

const totalStars = kFormatter(stargazers.totalCount);
Expand Down Expand Up @@ -101,7 +102,7 @@ const renderRepoCard = (repo, options = {}) => {

const starAndForkCount = FlexLayout({
items: [svgStars, svgForks],
gap: 65,
gap: 65
}).join("");

const card = new Card({
Expand All @@ -113,12 +114,12 @@ const renderRepoCard = (repo, options = {}) => {
titleColor,
textColor,
iconColor,
bgColor,
},
bgColor
}
});

card.disableAnimations();
card.setHideBorder(false);
card.setHideBorder(hide_border);
card.setHideTitle(false);
card.setCSS(`
.description { font: 400 13px 'Segoe UI', Ubuntu, Sans-Serif; fill: ${textColor} }
Expand Down Expand Up @@ -147,7 +148,7 @@ const renderRepoCard = (repo, options = {}) => {
${svgLanguage}

<g
data-testid="star-fork-group"
data-testid="star-fork-group"
transform="translate(${primaryLanguage ? 155 - shiftText : 25}, 0)"
>
${starAndForkCount}
Expand Down
9 changes: 5 additions & 4 deletions src/common/retryer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { logger, CustomError } = require("../common/utils");

const retryer = async (fetcher, variables, retries = 0) => {
const retryer = async (fetcher, variables, retries = 0, count_forks) => {
if (retries > 7) {
throw new CustomError("Maximum retries exceeded", CustomError.MAX_RETRY);
}
Expand All @@ -9,7 +9,8 @@ const retryer = async (fetcher, variables, retries = 0) => {
let response = await fetcher(
variables,
process.env[`PAT_${retries + 1}`],
retries
retries,
count_forks
);

// prettier-ignore
Expand All @@ -21,7 +22,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
logger.log(`PAT_${retries + 1} Failed`);
retries++;
// directly return from the function
return retryer(fetcher, variables, retries);
return retryer(fetcher, variables, retries, count_forks);
}

// finally return the response
Expand All @@ -35,7 +36,7 @@ const retryer = async (fetcher, variables, retries = 0) => {
logger.log(`PAT_${retries + 1} Failed`);
retries++;
// directly return from the function
return retryer(fetcher, variables, retries);
return retryer(fetcher, variables, retries, count_forks);
}
}
};
Expand Down
41 changes: 32 additions & 9 deletions src/fetchers/top-languages-fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ const { request, logger, clampValue } = require("../common/utils");
const retryer = require("../common/retryer");
require("dotenv").config();

const fetcher = (variables, token) => {
const fetcher = (variables, token, retries, count_forks) => {
const forks = count_forks == "true" ? `` : `isFork: false, `;
return request(
{
query: `
query userInfo($login: String!) {
user(login: $login) {
# fetch only owner repos & not forks
repositories(ownerAffiliations: OWNER, isFork: false, first: 100) {
# fetch only owner repos
repositories(ownerAffiliations: OWNER, ${forks}first: 100) {
nodes {
name
languages(first: 10, orderBy: {field: SIZE, direction: DESC}) {
edges {
size
Expand All @@ -25,27 +27,48 @@ const fetcher = (variables, token) => {
}
}
`,
variables,
variables
},
{
Authorization: `bearer ${token}`,
Authorization: `bearer ${token}`
}
);
};

async function fetchTopLanguages(username, langsCount = 5) {
async function fetchTopLanguages(
username,
langsCount = 5,
count_forks = false,
exclude_repo = []
) {
if (!username) throw Error("Invalid username");

langsCount = clampValue(parseInt(langsCount), 1, 10);

const res = await retryer(fetcher, { login: username });
const res = await retryer(fetcher, { login: username }, 0, count_forks);

if (res.data.errors) {
logger.error(res.data.errors);
throw Error(res.data.errors[0].message || "Could not fetch user");
}

let repoNodes = res.data.data.user.repositories.nodes;
let repoToHide = {};

// populate repoToHide map for quick lookup
// while filtering out
if (exclude_repo) {
exclude_repo.forEach((langName) => {
repoToHide[langName] = true;
});
}

// filter out repositories to be hidden
repoNodes = repoNodes
.sort((a, b) => b.size - a.size)
.filter((name) => {
return !repoToHide[name.name];
});

repoNodes = repoNodes
.filter((node) => {
Expand All @@ -69,8 +92,8 @@ async function fetchTopLanguages(username, langsCount = 5) {
[prev.node.name]: {
name: prev.node.name,
color: prev.node.color,
size: langSize,
},
size: langSize
}
};
}, {});

Expand Down