mirror of
https://github.com/PretendoNetwork/website.git
synced 2026-03-21 17:24:28 -05:00
186 lines
4.4 KiB
JavaScript
186 lines
4.4 KiB
JavaScript
const { GraphQLClient, gql } = require('graphql-request');
|
|
const Stripe = require('stripe');
|
|
const config = require('../config.json');
|
|
|
|
const graphql = new GraphQLClient('https://api.github.com/graphql', {
|
|
headers: {
|
|
Authorization: `bearer ${config.github.graphql_token}`,
|
|
}
|
|
});
|
|
const stripe = new Stripe(config.stripe.secret_key);
|
|
|
|
const getProjectCards = gql`
|
|
fragment ItemContent on Node {
|
|
__typename
|
|
... on DraftIssue {
|
|
title
|
|
}
|
|
... on Issue {
|
|
title
|
|
}
|
|
}
|
|
|
|
fragment Itemfields on Node {
|
|
__typename
|
|
... on ProjectV2ItemFieldSingleSelectValue {
|
|
name,
|
|
field {
|
|
... on ProjectV2SingleSelectField {
|
|
name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
query getProjectCards($orgName: String!) {
|
|
organization(login: $orgName) {
|
|
projectsV2(first: 100) {
|
|
nodes {
|
|
repositories(first: 1) {
|
|
nodes {
|
|
url
|
|
}
|
|
}
|
|
title
|
|
items(first: 100) {
|
|
nodes {
|
|
id
|
|
content {
|
|
...ItemContent
|
|
}
|
|
fieldValues(first: 20) {
|
|
nodes {
|
|
...Itemfields
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
let githubProjectsCache;
|
|
let stripeDonationCache;
|
|
|
|
async function getGithubProjectsCache() {
|
|
if (!githubProjectsCache) {
|
|
githubProjectsCache = await updateGithubProjectsCache();
|
|
}
|
|
|
|
if (githubProjectsCache.update_time < Date.now() - (1000 * 60 * 60)) {
|
|
githubProjectsCache = await updateGithubProjectsCache();
|
|
}
|
|
|
|
return githubProjectsCache;
|
|
}
|
|
|
|
function getProgressField(fields) {
|
|
const found = fields.nodes.find(v => v.field?.name === 'Status');
|
|
return found?.name ?? undefined;
|
|
}
|
|
|
|
async function updateGithubProjectsCache() {
|
|
const projectsCacheData = {
|
|
update_time: Date.now(),
|
|
sections: []
|
|
};
|
|
|
|
const data = await graphql.request(getProjectCards, {
|
|
orgName: 'PretendoNetwork',
|
|
});
|
|
|
|
const projects = data.organization.projectsV2.nodes;
|
|
|
|
for (const project of projects) {
|
|
if (!project.repositories.nodes[0]) {
|
|
continue;
|
|
}
|
|
|
|
const extractedData = {
|
|
title: project.title,
|
|
url: project.repositories.nodes[0]?.url,
|
|
cards: {
|
|
done: [],
|
|
in_progress: [],
|
|
todo: []
|
|
}
|
|
};
|
|
|
|
for (const { content, fieldValues } of project.items.nodes) {
|
|
const progress = getProgressField(fieldValues);
|
|
|
|
if (!['DraftIssue'].includes(content.__typename)) {
|
|
continue; // not a supported card, skip
|
|
}
|
|
|
|
if (!progress) {
|
|
continue; // entry does not have a status, skip
|
|
}
|
|
|
|
extractedData.cards[progress.toLowerCase().replace(' ', '_')]?.push(content.title);
|
|
}
|
|
|
|
projectsCacheData.sections.push(extractedData);
|
|
}
|
|
|
|
return projectsCacheData;
|
|
}
|
|
|
|
async function getStripeDonationCache() {
|
|
if (!stripeDonationCache) {
|
|
stripeDonationCache = await updateStripeDonationCache();
|
|
}
|
|
|
|
if (stripeDonationCache.update_time < Date.now() - (1000 * 60 * 60)) {
|
|
stripeDonationCache = await updateStripeDonationCache();
|
|
}
|
|
|
|
return stripeDonationCache;
|
|
}
|
|
|
|
async function updateStripeDonationCache() {
|
|
const donationCache = {
|
|
update_time: Date.now(),
|
|
goal: config.stripe.goal_cents,
|
|
total: 0,
|
|
donators: 0,
|
|
completed_real: 0,
|
|
completed_capped: 0
|
|
};
|
|
|
|
let hasMore = true;
|
|
let lastId;
|
|
|
|
while (hasMore) {
|
|
const { data: activeSubscriptions, has_more } = await stripe.subscriptions.list({
|
|
limit: 100,
|
|
status: 'active',
|
|
starting_after: lastId
|
|
});
|
|
|
|
donationCache.donators += activeSubscriptions.length;
|
|
|
|
for (const subscription of activeSubscriptions) {
|
|
donationCache.total += subscription.plan.amount;
|
|
lastId = subscription.id;
|
|
}
|
|
|
|
hasMore = has_more;
|
|
}
|
|
|
|
donationCache.goal_dollars = donationCache.goal / 100;
|
|
donationCache.total_dollars = donationCache.total / 100;
|
|
|
|
donationCache.completed_real = Math.floor((donationCache.total / donationCache.goal) * 100); // real completion amount
|
|
donationCache.completed_capped = Math.max(0, Math.min(donationCache.completed_real, 100)); // capped at 100
|
|
|
|
return donationCache;
|
|
}
|
|
|
|
module.exports = {
|
|
getGithubProjectsCache,
|
|
getStripeDonationCache
|
|
};
|