Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions functions/devpost.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fetch from "isomorphic-unfetch";
import { JSDOM } from "jsdom";
import { DevpostHackathon, DevpostProject } from "../interfaces";
import { DevpostProjectResponse } from "../interfaces/DevpostProjectResponse";
import { DevpostHackathonResponse } from "../interfaces/DevpostHackathonResponse";

/**
* Parses out the Devpost username from a given devpost profile url
Expand All @@ -23,8 +25,19 @@ export const getUsernameFromUrl = (devpostUrl: string) => {
* Returns a list of hackathon projects a user has created
* @param devpostUsername Devpost user's username
*/
export const getUsersProjects = async (devpostUsername: string) => {
export const getUsersProjects = async (
devpostUsername: string
): Promise<DevpostProjectResponse> => {
const res = await fetch(`https://devpost.com/${devpostUsername}`);
const projectsRes: DevpostProjectResponse = { projects: [] };

if (!res.ok) {
projectsRes.error = res.status;
projectsRes.ok = false;
return projectsRes;
}

projectsRes.ok = true;
const projectPage = await res.text();

const { document } = new JSDOM(projectPage).window;
Expand All @@ -46,18 +59,20 @@ export const getUsersProjects = async (devpostUsername: string) => {
numLikes,
});
});

return projects;
projectsRes.projects = projects;
return projectsRes;
};

/**
* Returns the hackathon a given user has signed up for
* @param devpostUsername Devpost user's username
* @param maxHackathons Limit the amount of hackathons that get returned
*/
export const getUsersHackathons = async (devpostUsername: string) => {
export const getUsersHackathons = async (
devpostUsername: string
): Promise<DevpostHackathonResponse> => {
let numPages = 1;
const hackathons: DevpostHackathon[] = [];
const hackathonsRes: DevpostHackathonResponse = { hackathons: [] };

/**
* Function to parse out DevpostHackathons and put it in the hackathons array (abusing closures!)
Expand Down Expand Up @@ -140,7 +155,7 @@ export const getUsersHackathons = async (devpostUsername: string) => {
userWonPrize ||
hackathonsSubmitted.includes(parseInt(devpostId || "0", 10));

hackathons.push({
hackathonsRes.hackathons.push({
id: hackathonUrl.hostname, // hostname should be unique for each devpost hackathon
title: hackathonTitle,
link: hackathonLink,
Expand All @@ -153,6 +168,12 @@ export const getUsersHackathons = async (devpostUsername: string) => {

// get the first page of hackathons
const res = await fetch(`https://devpost.com/${devpostUsername}/challenges`);
if (!res.ok) {
hackathonsRes.error = res.status;
hackathonsRes.ok = false;
return hackathonsRes;
}
hackathonsRes.ok = true;
const hackathonPage = await res.text();

const { document } = new JSDOM(hackathonPage).window;
Expand Down Expand Up @@ -187,5 +208,5 @@ export const getUsersHackathons = async (devpostUsername: string) => {
// wait for all pages to be parsed
await Promise.all(promises);

return hackathons;
return hackathonsRes;
};
16 changes: 16 additions & 0 deletions interfaces/DevpostHackathonResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DevpostHackathon } from "./DevpostHackathon";

export interface DevpostHackathonResponse {
/**
* List of DevpostProjects
*/
hackathons: DevpostHackathon[];
/**
* Optional: Response status code
*/
error?: number;
/**
* Optional: Response ok-ness
*/
ok?: boolean;
}
16 changes: 16 additions & 0 deletions interfaces/DevpostProjectResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DevpostProject } from "./DevpostProject";

export interface DevpostProjectResponse {
/**
* List of DevpostProjects
*/
projects: DevpostProject[];
/**
* Optional: Response status code
*/
error?: number;
/**
* Optional: Response ok-ness
*/
ok?: boolean;
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "NODE_OPTIONS='--inspect' next dev",
"build": "next build",
"start": "next start",
"lint": "eslint . --fix",
Expand Down
21 changes: 18 additions & 3 deletions pages/api/user/[devpostUsername]/hackathons.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { NextApiRequest, NextApiResponse } from "next";
import { getUsersHackathons } from "../../../../functions/devpost";

export default async (req: NextApiRequest, res: NextApiResponse) => {
Expand All @@ -9,5 +9,20 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
if (!devpostUsername || Array.isArray(devpostUsername))
return res.status(400).send("");

return res.json(await getUsersHackathons(devpostUsername));
}
const userHackathons = await getUsersHackathons(devpostUsername);

if (!userHackathons.ok) {
let errorMessage: string;
switch (userHackathons.error) {
case 404:
errorMessage = `devpost user ${devpostUsername} not found.`;
break;
default:
errorMessage = `ERROR ${userHackathons.error}! something went wrong getting projects for ${devpostUsername}`;
break;
}
return res.status(userHackathons.error).send(errorMessage);
}

return res.json(userHackathons.hackathons);
};
21 changes: 18 additions & 3 deletions pages/api/user/[devpostUsername]/projects.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { NextApiRequest, NextApiResponse } from "next";
import { getUsersProjects } from "../../../../functions/devpost";

export default async (req: NextApiRequest, res: NextApiResponse) => {
Expand All @@ -9,5 +9,20 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
if (!devpostUsername || Array.isArray(devpostUsername))
return res.status(400).send("");

return res.json(await getUsersProjects(devpostUsername));
}
const userProjects = await getUsersProjects(devpostUsername);

if (!userProjects.ok) {
let errorMessage: string;
switch (userProjects.error) {
case 404:
errorMessage = `devpost user ${devpostUsername} not found.`;
break;
default:
errorMessage = `ERROR ${userProjects.error}! something went wrong getting projects for ${devpostUsername}`;
break;
}
return res.status(userProjects.error).send(errorMessage);
}

return res.json(userProjects.projects);
};
20 changes: 17 additions & 3 deletions pages/api/wall/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,24 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
const images = badgesFiles(DEVPOST_BADGES);
const customImages = badgesFiles(ALT_BADGES);

const devpostEvents = parseDevpostEvents(
const userHackathons =
!username || Array.isArray(username)
? []
: await getUsersHackathons(username),
? { hackathons: [] }
: await getUsersHackathons(username);
if (!userHackathons.ok) {
let errorMessage: string;
switch (userHackathons.error) {
case 404:
errorMessage = `devpost user ${username} not found.`;
break;
default:
errorMessage = `ERROR ${userHackathons.error}! something went wrong getting projects for ${username}`;
break;
}
return res.status(userHackathons.error).send(errorMessage);
}
const devpostEvents = parseDevpostEvents(
userHackathons.hackathons,
projectLevel,
badge_limit
);
Expand Down