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();