scripts/contributor.js (121 lines of code) (raw):
// Get contributor information of github repository
var fs = require('fs');
var path = require('path');
var TeamJson = require('../static/data/team.json');
var outputFile = path.resolve(__dirname, '../static/data/team.json');
var teamAvatarDir = path.resolve(__dirname, '../static/img/team');
// ignore PMC and committers members
var ignoreList = [];
TeamJson.forEach(function(u) {
if (u.type === 'pmc' || u.type === 'committer') {
u.users.forEach(function(user) {
ignoreList.push(user.name);
});
}
});
console.log('ignoreList', ignoreList);
// all repo urls
var repositoryUrls = [
'https://api.github.com/repos/apache/answer/contributors?page=%d&per_page=100',
'https://api.github.com/repos/apache/answer-plugins/contributors?page=%d&per_page=100',
'https://api.github.com/repos/apache/answer-website/contributors?page=%d&per_page=100',
];
var allContributors = [];
function fetchContributors() {
var promises = repositoryUrls.map(function(url, index) {
return fetchPagedContributors(url, index, 1, []);
});
return Promise.all(promises).then(function(results) {
// filter duplicate contributors
var uniqueContributors = [];
allContributors.forEach(function(contributor) {
var existingContributor = uniqueContributors.find(function(c) {
return c.name === contributor.name;
});
if (!existingContributor) {
uniqueContributors.push(contributor);
}
});
// Sort by name field
uniqueContributors.sort(function(a, b) {
return a.name.localeCompare(b.name);
});
// read existing data from team.json
var existingData = fs.readFileSync(outputFile, 'utf8');
var jsonData = JSON.parse(existingData);
jsonData[2].count = uniqueContributors.length;
jsonData[2].users = uniqueContributors;
// save data to team.json
fs.writeFile(outputFile, JSON.stringify(jsonData, null, 2), function(err) {
if (err) {
console.error('write file err:', err);
}
});
});
}
function fetchPagedContributors(url, index, page, currentResults) {
return fetch(url.replace('%d', page))
.then(function(res) {
return res.json();
})
.then(function(data) {
// Add the newly fetched data to currentResults
var newResults = currentResults.concat(
data.map(function(contributor) {
return {
name: contributor.login,
github: contributor.html_url,
avatar: contributor.avatar_url,
};
}).filter(function(contributor) {
return !ignoreList.includes(contributor.name);
})
);
// If the returned data length is equal to 100, continue to request the next page
if (data.length === 100) {
return fetchPagedContributors(url, index, page + 1, newResults);
} else {
// Add the final newResults to the allContributors array.
allContributors = allContributors.concat(newResults);
return newResults;
}
});
}
saveAvatars('pmc');
saveAvatars('committer');
// 根据 MIME 类型获取文件扩展名
function getExtensionFromMimeType(mimeType) {
var mimeToExtension = {
'image/jpeg': 'jpg',
'image/png': 'png',
'image/gif': 'gif',
'image/webp': 'webp',
'image/svg+xml': 'svg',
};
return mimeToExtension[mimeType] || 'jpg';
}
// save avatars
async function saveAvatars(type) {
const dataType = TeamJson.find((item) => item.type === type);
const users = dataType.users;
for (const user of users) {
try {
const avatarUrl = user.avatar;
const response = await fetch(avatarUrl);
if (!response.ok) {
throw new Error(`Failed to fetch ${avatarUrl}: ${response.statusText}`);
}
const contentType = response.headers.get('content-type');
// According to Content-Type to get extension
const extension = getExtensionFromMimeType(contentType);
const avatarName = `${user.name}.${extension}`;
const savePath = path.join(teamAvatarDir, avatarName);
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
fs.writeFileSync(savePath, buffer);
// 更新 avatar2 字段为相对路径
user.avatar_local = `/img/team/${avatarName}`;
console.log(`Saved avatar for ${user.name} to ${savePath}`);
} catch (error) {
console.error(`Failed to save avatar for ${user.name}:`, error.message);
}
}
TeamJson = TeamJson.map((item) => {
if (item.type === type) {
return {
...item,
users,
};
}
return item;
});
fs.writeFileSync(outputFile, JSON.stringify(TeamJson, null, 2));
}
saveAvatars('pmc');
saveAvatars('committer');
// fetchContributors();