Skip to content

Commit

Permalink
Enable empathy badge and merge discussions with old data
Browse files Browse the repository at this point in the history
  • Loading branch information
dgparmar14 committed Jul 19, 2024
1 parent f1bab51 commit b89aaeb
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 52 deletions.
28 changes: 27 additions & 1 deletion config/GraduateAttributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,28 @@ export let humanValues = [
key: "empathy",
label: "Empathy",
icon: "/images/Human-Values/Empathy.svg",
levels: [],
levels: [
{
label: "1x",
value: 1,
description: "Resolved 1 Question in the community",
},
{
label: "2x",
value: 10,
description: "Resolved 10 Question in the community",
},
{
label: "3x",
value: 100,
description: "Resolved 100 Question in the community",
},
{
label: "4x",
value: 1000,
description: "Resolved 1000 Question in the community",
},
],
},
{
key: "value_inculcation",
Expand Down Expand Up @@ -290,6 +311,11 @@ export let resolveGraduateAttributes = (
attribute,
contributor.activityData?.authored_issue_and_pr?.length,
);
case "empathy":
return resolveLevel(
attribute,
contributor.highlights.discussion_answered / 5,
);
default:
return { ...attribute };
}
Expand Down
16 changes: 8 additions & 8 deletions lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,6 @@ export async function getContributorBySlug(file: string, detail = false) {
activityData = JSON.parse(
await readFile(join(githubRoot, `${githubHandle}.json`), "utf8"),
) as ActivityData;
// in activitydata need to add github discussion data
const discussions = await getGithubDiscussions(githubHandle);

// Add discussions to activityData in activity array
activityData = {
...activityData,
activity: [...activityData.activity, ...discussions],
};
} catch (e) {
activityData = {
last_updated: undefined,
Expand All @@ -119,6 +111,14 @@ export async function getContributorBySlug(file: string, detail = false) {
} satisfies ActivityData;
}

// in activitydata need to add github discussion data
const discussions = await getGithubDiscussions(githubHandle);

// Add discussions to activityData in activity array
activityData = {
...activityData,
activity: [...activityData.activity, ...discussions],
};
const slackMessages = await getSlackMessages(data.slack);

activityData = {
Expand Down
51 changes: 50 additions & 1 deletion lib/discussion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,54 @@ import octokit from "./octokit";
import { featureIsEnabled } from "./utils";
import { Activity } from "./types";

interface Participant {
repository: {
discussion: {
comments: {
edges: {
node: {
author: {
login: string;
};
};
}[];
};
};
};
}

const root = join(process.cwd(), "data-repo/data/github/discussions");

export const categories: { name: string; emoji: string }[] = [];

export async function fetchParticipants(discussion: ParsedDiscussion) {
const org = env.NEXT_PUBLIC_GITHUB_ORG;
const number = discussion.link?.split("/").pop() ?? "";

const participants: Participant = await octokit.graphql(`query {
repository(owner: "${org}", name: "${discussion.repoName}") {
discussion (number: ${number}) {
comments(first: 100) {
edges {
node {
author {
login
}
}
}
}
}
}
}`);
return Array.from(
new Set(
participants.repository.discussion.comments.edges.map(
(c) => c.node.author.login,
),
),
);
}

export async function fetchGithubDiscussion(
noOfDiscussion?: number | null,
user?: string,
Expand Down Expand Up @@ -42,6 +86,12 @@ export async function fetchGithubDiscussion(
}
});

// get all particpants for github discussions
discussions.forEach(async (discussion) => {
// append participants to discussion
discussion.participants = await fetchParticipants(discussion);
});

if (user) {
return discussions.filter(
(discussion) =>
Expand All @@ -50,7 +100,6 @@ export async function fetchGithubDiscussion(
);
}

// return noOfDiscussion ? discussions.slice(0, noOfDiscussion) : discussions;
return noOfDiscussion ? discussions.slice(0, noOfDiscussion) : discussions;
}
interface Dicussion {
Expand Down
71 changes: 37 additions & 34 deletions scraper/src/github-scraper/discussion.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { parseISO, startOfDay, subDays } from "date-fns";
import { octokit } from "./config.js";
import { Discussion, ParsedDiscussion } from "./types.js";
import { saveDiscussionData } from "./utils.js";
Expand Down Expand Up @@ -27,15 +28,6 @@ query($org: String!, $cursor: String) {
name
emojiHTML
}
comments(first: 10) {
edges {
node {
author {
login
}
}
}
}
createdAt
}
}
Expand All @@ -52,43 +44,48 @@ async function fetchDiscussionsForOrg(org: string, cursor = null) {
const response = await octokit.graphql.paginate(query, variables);

type Edge = typeof response.organization.repositories.edges;
// const discussions = response.organization.repositories.edges.map(
// (edge: Edge) => edge.node.discussions.edges,
// );

// return discussions.flat();
const discussions = response.organization.repositories.edges.map(
(edge: Edge) => ({
repoName: edge.node.name,
discussions: edge.node.discussions.edges,
}),
);

return discussions;
}

async function parseDiscussionData(
allDiscussions: { repoName: string; discussions: Discussion[] }[],
date: string,
numDays: number,
) {
const parsedDiscussions: ParsedDiscussion[] = allDiscussions.flatMap((repo) =>
repo.discussions.map((d) => {
const participants = Array.from(
new Set(d.node.comments.edges.map((c) => c.node.author.login)),
);
return {
source: "github",
title: d.node.title,
text: d.node.body,
author: d.node.author.login,
link: d.node.url,
time: d.node.createdAt,
category: {
name: d.node.category.name,
emoji: d.node.category.emojiHTML.replace(/<\/?div>/g, ""),
},
participants,
repoName: repo.repoName,
};
}),
const endDate: Date = startOfDay(parseISO(date));
const startDate: Date = startOfDay(subDays(endDate, numDays));

const parsedDiscussions: ParsedDiscussion[] = allDiscussions.flatMap(
(repo) => {
const filteredDiscussions = repo.discussions.filter((d) => {
const discussionTime: Date = new Date(d.node.createdAt);
return discussionTime > startDate && discussionTime <= endDate;
});

return filteredDiscussions.map((d) => {
return {
source: "github",
title: d.node.title,
text: d.node.body,
author: d.node.author.login,
link: d.node.url,
time: d.node.createdAt,
category: {
name: d.node.category.name,
emoji: d.node.category.emojiHTML.replace(/<\/?div>/g, ""),
},
repoName: repo.repoName,
};
});
},
);

return parsedDiscussions;
Expand All @@ -97,10 +94,16 @@ async function parseDiscussionData(
export async function fetchAllDiscussionEventsByOrg(
organizationName: string,
dataDir: string,
date: string,
numDays: number = 1,
) {
try {
const allDiscussions = await fetchDiscussionsForOrg(organizationName);
const parsedDiscussions = await parseDiscussionData(allDiscussions);
const parsedDiscussions = await parseDiscussionData(
allDiscussions,
date,
numDays,
);
await saveDiscussionData(parsedDiscussions, dataDir);
} catch (error: any) {
throw new Error(`Error fetching discussions: ${error.message}`);
Expand Down
2 changes: 1 addition & 1 deletion scraper/src/github-scraper/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const main = async () => {
}
await scrapeGitHub(orgName, date, Number(numDays), orgName);
await mergedData(dataDir, processedData);
await fetchAllDiscussionEventsByOrg(orgName, dataDir);
await fetchAllDiscussionEventsByOrg(orgName, dataDir, date, Number(numDays));

console.log("Done");
};
Expand Down
18 changes: 11 additions & 7 deletions scraper/src/github-scraper/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,16 +176,20 @@ export async function saveDiscussionData(
discussions: ParsedDiscussion[],
dataDir: string,
) {
const discussionDir = path.join(dataDir, "discussions");
await mkdir(discussionDir, { recursive: true });
const file = path.join(discussionDir, "discussions.json");
console.log(`Saving discussion data to ${file}`);
// check data dir present or not and file is present or not if not then create it
await mkdir(dataDir + "/discussions", { recursive: true });

const file = path.join(dataDir + "/discussions", "discussions.json");
try {
// Try reading the file
const response = await readFile(file);
const oldData = JSON.parse(response.toString());
const newData = oldData.concat(discussions);
const jsonData = JSON.stringify(newData, null, 2);
await writeFile(file, jsonData);
} catch (err) {
// File doesn't exist, create it with initial data
const jsonData = JSON.stringify(discussions, null, 2);
await writeFile(file, jsonData);
} catch (error: any) {
console.error(`Failed to save discussion data: ${error.message}`);
throw error;
}
}

0 comments on commit b89aaeb

Please sign in to comment.