Skip to content

Commit c391039

Browse files
committed
add neww stats
1 parent 51af3de commit c391039

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
{
22
"USERNAME": "FabioDevCode",
33
"TITLE": "Langages Utilisés",
4+
"STATS_TITLE": "FabioDevCode's GitHub Stats",
45
"BG_COLOR": "#202830",
56
"BORDER_COLOR": "#202830",
67
"TITLE_COLOR": "#D1D7E0",
78
"TEXT_COLOR": "#D1D7E0",
89
"PERCENT_COLOR": "#9298A1",
10+
"ICON_COLOR": "#6e7681",
11+
"VALUE_COLOR": "#58a6ff",
912
"VARIANTS": [2, 4, 6],
1013
"IGNORE_LANGUAGES": ["HTML", "CSS", "Handlebars", "SCSS"]
1114
}

generate-stats.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ const CONFIG = JSON.parse(fs.readFileSync('config.json', 'utf8'));;
66
// Couleurs officielles GitHub (NE PAS MODIFIER)
77
const LANGUAGE_COLORS = JSON.parse(fs.readFileSync('github_colors.json', 'utf8'));
88

9+
// Icônes SVG pour les stats
10+
const ICONS = {
11+
star: `<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 .25z"/>`,
12+
commit: `<path fill-rule="evenodd" d="M11.93 8.5a4.002 4.002 0 01-7.86 0H.75a.75.75 0 010-1.5h3.32a4.002 4.002 0 017.86 0h3.32a.75.75 0 010 1.5h-3.32zm-1.43-.75a2.5 2.5 0 10-5 0 2.5 2.5 0 005 0z"/>`,
13+
pullRequest: `<path fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"/>`,
14+
issue: `<path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"/><path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"/>`,
15+
contrib: `<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"/>`,
16+
github: `<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>`
17+
};
18+
919
async function fetchGitHubStats(username, token) {
1020
console.log(`📊 Récupération des stats pour ${username}...`);
1121

@@ -53,6 +63,143 @@ function getLanguageColor(language) {
5363
return LANGUAGE_COLORS[language] || '#858585';
5464
}
5565

66+
async function fetchGitHubUserStats(username, token) {
67+
console.log(`📊 Récupération des stats utilisateur pour ${username}...`);
68+
69+
const query = `
70+
query($username: String!) {
71+
user(login: $username) {
72+
repositories(first: 100, ownerAffiliations: OWNER, isFork: false) {
73+
totalCount
74+
nodes {
75+
stargazerCount
76+
}
77+
}
78+
pullRequests(first: 1) {
79+
totalCount
80+
}
81+
issues(first: 1) {
82+
totalCount
83+
}
84+
repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
85+
totalCount
86+
}
87+
contributionsCollection {
88+
totalCommitContributions
89+
restrictedContributionsCount
90+
}
91+
}
92+
}`;
93+
94+
try {
95+
const response = await fetch('https://api.github.com/graphql', {
96+
method: 'POST',
97+
headers: {
98+
'Authorization': `bearer ${token}`,
99+
'Content-Type': 'application/json',
100+
},
101+
body: JSON.stringify({ query, variables: { username } })
102+
});
103+
104+
if (!response.ok) {
105+
throw new Error(`GitHub GraphQL API error: ${response.status}`);
106+
}
107+
108+
const data = await response.json();
109+
110+
if (data.errors) {
111+
throw new Error(data.errors[0].message);
112+
}
113+
114+
const user = data.data.user;
115+
const totalStars = user.repositories.nodes.reduce((sum, repo) => sum + repo.stargazerCount, 0);
116+
const totalCommits = user.contributionsCollection.totalCommitContributions + user.contributionsCollection.restrictedContributionsCount;
117+
118+
const stats = {
119+
stars: totalStars,
120+
commits: totalCommits,
121+
pullRequests: user.pullRequests.totalCount,
122+
issues: user.issues.totalCount,
123+
contributedTo: user.repositoriesContributedTo.totalCount
124+
};
125+
126+
console.log(`✅ Stats utilisateur récupérées:`, stats);
127+
return stats;
128+
} catch (error) {
129+
console.error('❌ Erreur lors de la récupération des stats utilisateur:', error.message);
130+
throw error;
131+
}
132+
}
133+
134+
function formatNumber(num) {
135+
if (num >= 1000000) {
136+
return (num / 1000000).toFixed(1) + 'M';
137+
} else if (num >= 1000) {
138+
return (num / 1000).toFixed(1) + 'k';
139+
}
140+
return num.toString();
141+
}
142+
143+
function generateUserStatsSVG(stats, username) {
144+
const statItems = [
145+
{ label: 'Total Stars', value: stats.stars, icon: ICONS.star },
146+
{ label: 'Total Commits', value: stats.commits, icon: ICONS.commit },
147+
{ label: 'Total PRs', value: stats.pullRequests, icon: ICONS.pullRequest },
148+
{ label: 'Total Issues', value: stats.issues, icon: ICONS.issue },
149+
{ label: 'Contributed to', value: stats.contributedTo, icon: ICONS.contrib }
150+
];
151+
152+
const statsTitle = CONFIG.STATS_TITLE || `${username}'s GitHub Stats`;
153+
const iconColor = CONFIG.ICON_COLOR || '#6e7681';
154+
const valueColor = CONFIG.VALUE_COLOR || CONFIG.TEXT_COLOR;
155+
156+
let itemsY = 55;
157+
const statsItems = statItems.map(item => {
158+
const formattedValue = formatNumber(item.value);
159+
const itemSVG = `
160+
<g transform="translate(25, ${itemsY})">
161+
<svg width="16" height="16" viewBox="0 0 16 16" fill="${iconColor}">
162+
${item.icon}
163+
</svg>
164+
<text x="28" y="12" font-size="14" fill="${CONFIG.TEXT_COLOR}">${item.label}:</text>
165+
<text x="145" y="12" font-size="14" font-weight="600" fill="${valueColor}">${formattedValue}</text>
166+
</g>`;
167+
itemsY += 30;
168+
return itemSVG;
169+
}).join('');
170+
171+
const height = 230;
172+
const width = 420;
173+
174+
return `<?xml version="1.0" encoding="UTF-8"?>
175+
<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
176+
<defs>
177+
<style>
178+
@import url('https://fonts.googleapis.com/css2?family=Segoe+UI:wght@400;500;600&amp;display=swap');
179+
* { font-family: 'Segoe UI', Ubuntu, sans-serif; }
180+
</style>
181+
</defs>
182+
183+
<!-- Background -->
184+
<rect width="${width}" height="${height}" fill="${CONFIG.BG_COLOR}" rx="10" stroke="${CONFIG.BORDER_COLOR}" stroke-width="1"/>
185+
186+
<!-- Title -->
187+
<text x="25" y="35" font-size="18" fill="${CONFIG.TITLE_COLOR}" font-weight="600">
188+
${statsTitle}
189+
</text>
190+
191+
<!-- Stats Items -->
192+
${statsItems}
193+
194+
<!-- GitHub Logo -->
195+
<g transform="translate(${width - 100}, ${height / 2 - 40})">
196+
<svg width="80" height="80" viewBox="0 0 16 16" fill="${iconColor}" opacity="0.3">
197+
${ICONS.github}
198+
</svg>
199+
</g>
200+
</svg>`;
201+
}
202+
56203
function generateSVG(languageStats, topN = 5) {
57204
// Trier et limiter
58205
const sortedLangs = Object.entries(languageStats)
@@ -165,6 +312,12 @@ async function main() {
165312
console.log(` ✅ ${filename}`);
166313
});
167314

315+
// Générer les stats utilisateur
316+
const userStats = await fetchGitHubUserStats(CONFIG.USERNAME, token);
317+
const userStatsSVG = generateUserStatsSVG(userStats, CONFIG.USERNAME);
318+
fs.writeFileSync('github-stats.svg', userStatsSVG);
319+
console.log(` ✅ github-stats.svg`);
320+
168321
console.log('\n🎉 Toutes les images ont été générées avec succès !');
169322
} catch (error) {
170323
console.error('❌ Erreur lors de la génération:', error);

0 commit comments

Comments
 (0)