Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refac: separate event and project fetch function and add languages url #101

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 20 additions & 0 deletions scripts/actions/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export interface IEvent {
name: string;
date: string;
location: string;
img: string;
link: string;
}

export function fetchEvent(existingEvent: IEvent[]): IEvent[] {
const events = [...existingEvent];

for (const event of events) {
const index = events.findIndex((x) => x.name === event.name);
if (index === -1) {
events.push(event);
}
}

return events;
}
46 changes: 33 additions & 13 deletions scripts/actions/fetch-projects-by-topic.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import fs from 'fs'
import path from 'path'
import process from 'node:process'
import path from 'path'
import { fileURLToPath } from 'url'

const defaultTopicName = 'bangkok-open-source'

interface Language {
[key: string]: number;
}

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const filePath = path.resolve(__dirname, '../../src/content/ring.generated.json')

Expand Down Expand Up @@ -37,16 +41,30 @@ async function fetchPagedProjects(
page = 1,
perPage = 100
): Promise<SearchRepositoriesResponse> {
const url = new URL('https://api.github.com/search/repositories')
url.searchParams.set('q', query)
url.searchParams.set('page', `${page}`)
url.searchParams.set('per_page', `${perPage}`)
const url = new URL('https://api.github.com/search/repositories');
url.searchParams.set('q', query);
url.searchParams.set('page', `${page}`);
url.searchParams.set('per_page', `${perPage}`);

const resp = await fetch(url)
const resp = await fetch(url);
if (!resp.ok) {
throw new Error(`Failed to fetch paged projects: ${resp.status} ${await resp.text()}`)
throw new Error(`Failed to fetch paged projects: ${resp.status} ${await resp.text()}`);
}
return (await resp.json()) as SearchRepositoriesResponse
const result = (await resp.json()) as SearchRepositoriesResponse;

// Fetch languages for each repository
const repositoriesWithLanguages = await Promise.all(
result.items.map(async (repo) => {
const languagesResp = await fetch(repo.languages_url);
if (!languagesResp.ok) {
throw new Error(`Failed to fetch languages for ${repo.full_name}`);
}
const languages: Language = await languagesResp.json();
return { ...repo, languages: Object.keys(languages) };
})
);

return { ...result, items: repositoriesWithLanguages };
}

function saveProjectsToJSON(projects: Project[]) {
Expand All @@ -64,14 +82,15 @@ function saveProjectsToJSON(projects: Project[]) {
async function main() {
const topicName = process.argv[2] || defaultTopicName
const topicLimit = Number(process.argv[3] ?? 1000)
const repositories = await fetchProjects(topicName, topicLimit)
// TODO: should be nice to have repo's languages from Repository.languages_url not just Repository.language
const repositories = await fetchProjects(topicName, topicLimit);

const projects = repositories.map<Project>((repo) => ({
name: repo.name,
repo: repo.html_url,
description: repo.description,
languages: [repo.language]
}))
languages: [repo.language],
languages_url: repo.languages_url
}));
saveProjectsToJSON(projects)
}

Expand Down Expand Up @@ -175,5 +194,6 @@ interface Project {
name: string
repo: string
description: string
languages: string[]
languages?: string[]
languages_url?: string
}
27 changes: 27 additions & 0 deletions scripts/actions/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export interface IProject {
name: string;
repo: string;
description: string;
languages?: string[];
}

export function fetchProjects(existingProjects: IProject[], newProjects: IProject[]): IProject[] {
const projects = [...existingProjects];

for (const project of newProjects) {
const index = projects.findIndex((x) => x.name === project.name);
if (index === -1) {
projects.push(project);
}
}

return projects;
}

export function shuffleProject<T>(array: T[]): T[] {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[array[i], array[j]] = [array[j], array[i]]
}
return array
}
12 changes: 9 additions & 3 deletions src/components/CardLink.astro
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ const { title, url, description, languages = [] } = Astro.props

<div class="project-card group relative focus-within:scale-[1.01]">
<div class="grid gap-2">
<a href={url} class="after:absolute after:inset-0 after:content-[''] after:focus:border after:focus:transition-all focus:after:border-bosf/50">
<a
href={url}
class="after:absolute after:inset-0 after:content-[''] after:focus:border focus:after:border-bosf/50 after:focus:transition-all"
>
<h3 class="text-2xl font-medium transition-all">
{title}
</h3>
</a>
<p class="text-base">
{description}
</p>
<!-- TODO: Languages display as tags -->
{languages.length > 0 && <p>{languages.join(', ')}</p>}
{
languages.length > 0 && (
<p class="text-base my-1 font-medium text-bosf">{languages.join(', ')}</p>
)
}
</div>
</div>
3 changes: 2 additions & 1 deletion src/content/ring.generated.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"description": "A client-side secure P2P file sharing using WebRTC.",
"languages": [
"Svelte"
]
],
"languages_url": "https://api.github.com/repos/ntsd/zero-share/languages"
}
]
}
2 changes: 2 additions & 0 deletions src/content/ring.json
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@
"languages": [
"JavaScript",
"Discord.js"
]
},
{
"name": "Arcade Game",
Expand All @@ -397,6 +398,7 @@
"Socket-io",
"Mqtt.js",
"Mongoose"
]
},
{
"name": "Bad Boyz",
Expand Down
46 changes: 15 additions & 31 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,11 @@ import events from '../content/events.json'
import sponsors from '../content/sponsors.json'
import CardLink from '../components/CardLink.astro'
import EventCard from '../components/EventCard.astro'
import { fetchProjects, shuffleProject } from '../../scripts/actions/project'
import { fetchEvent } from '../../scripts/actions/event'

// TODO: refactor dedupe logic to separate file?
// TODO: limit projects in index page
const projects = [...ring.projects]
for (const project of generatedRing.projects as typeof ring.projects) {
const index = projects.findIndex((x) => x.name === project.name)
if (index === -1) {
projects.push(project)
}
}

function shuffle<T>(array: T[]): T[] {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1))
;[array[i], array[j]] = [array[j], array[i]]
}
return array
}

const event = [...events.events]
.filter((x, i, a) => a.findIndex((y) => y.name === x.name) === i)
.sort((a, b) => {
const aDate = new Date(a.date)
const bDate = new Date(b.date)
return aDate.getTime() - bDate.getTime()
})
.slice(0, 6) // Add this line to limit to 6 events
const projects = fetchProjects([...ring.projects], [...generatedRing.projects])
const event = fetchEvent([...events.events])
---

<BaseLayout>
Expand All @@ -48,10 +26,16 @@ const event = [...events.events]
<h1 class="text-center text-3xl font-medium">1. Write code 💻</h1>
<div class="main-grid">
{
shuffle(projects)
shuffleProject(projects)
.slice(0, 6)
.map((x) => {
return <CardLink title={x.name} url={x.repo} description={x.description} />
.map((project) => {
return (
<CardLink
title={project.name}
url={project.repo}
description={project.description}
/>
)
})
}
</div>
Expand All @@ -63,8 +47,8 @@ const event = [...events.events]
<h1 class="text-center text-3xl font-medium">2. Join events 🙌</h1>
<div class="main-grid">
{
event.map((x) => {
return <EventCard events={x} />
event.map((event) => {
return <EventCard events={event} />
})
}
</div>
Expand Down
10 changes: 2 additions & 8 deletions src/pages/ring.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@ import BaseLayout from '../layouts/BaseLayout.astro'
import ring from '../content/ring.json'
import generatedRing from '../content/ring.generated.json'
import CardLink from '../components/CardLink.astro'
import { fetchProjects } from '../../scripts/actions/project'

// TODO: refactor dedupe logic to separate file?
const projects = [...ring.projects]
for (const project of generatedRing.projects as typeof ring.projects) {
const index = projects.findIndex((x) => x.name === project.name)
if (index === -1) {
projects.push(project)
}
}
const projects = fetchProjects([...ring.projects], [...generatedRing.projects])
---

<BaseLayout>
Expand Down