Skip to content

Commit

Permalink
replace workshops.yaml with spring2024.yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Feb 23, 2024
1 parent adbeb80 commit ba28554
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 91 deletions.
2 changes: 1 addition & 1 deletion deno.jsonc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"tasks": {
"lock": "deno cache --lock=deno.lock --lock-write deps.ts",
"udd": "deno run -Ar https://deno.land/x/udd/main.tsx deps.ts && deno task lock",
"udd": "deno run -Ar https://deno.land/x/udd/main.ts deps.ts && deno task lock",
"build": "deno run -A main.tsx",
"dev": "deno run -A --watch main.tsx",
"serve": "deno run -A https://deno.land/std/http/file_server.ts build"
Expand Down
1 change: 0 additions & 1 deletion deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { test } from "https://deno.land/[email protected]/front_matter/mod.ts";
export { copy, expandGlob } from "https://deno.land/[email protected]/fs/mod.ts";
export { join } from "https://deno.land/[email protected]/path/join.ts";
export { parseArgs } from "https://deno.land/[email protected]/cli/parse_args.ts";
export { extract } from "https://deno.land/[email protected]/front_matter/any.ts";
export { parse as parseYAML } from "https://deno.land/[email protected]/yaml/mod.ts";
Expand Down
1 change: 1 addition & 0 deletions lib/workshops/mod.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./workshops.ts";
export * from "./ssr.tsx";
export * from "./walk.ts";
38 changes: 15 additions & 23 deletions lib/workshops/ssr.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { Helmet } from "#/deps.ts";
import { withLayout } from "#/lib/shared/layout/mod.ts";
import { PageHeading } from "#/lib/shared/page_heading/mod.ts";
import {
DEFAULT_GROUP_ID,
type Workshop,
type WorkshopGroups,
} from "./workshops.ts";
import type { Workshop, WorkshopGroup } from "./workshops.ts";

function WorkshopPreviewComponent(props: { workshop: Workshop }) {
if (!props.workshop.url) {
Expand All @@ -16,32 +12,29 @@ function WorkshopPreviewComponent(props: { workshop: Workshop }) {
}

function WorkshopGroupsTableComponent(
props: { workshopGroups: WorkshopGroups },
props: { workshopGroups: WorkshopGroup[] },
) {
return (
<table>
<tr>
<th>Series</th>
<th>Workshops</th>
</tr>
{Object.keys(props.workshopGroups)
.filter((groupID) => groupID !== DEFAULT_GROUP_ID)
.map((groupID) => (
{props.workshopGroups
.map((group) => (
<tr>
<td>
<a href={`workshops/${groupID}.html`}>{groupID}</a>
</td>
<td>
{props.workshopGroups[groupID].length}
<a href={`series/${group.groupID}.html`}>{group.groupID}</a>
</td>
<td>{group.workshops.length}</td>
</tr>
))}
</table>
);
}

function WorkshopGroupsPageComponent(
props: { workshopGroups: WorkshopGroups },
props: { workshopGroups: WorkshopGroup[] },
) {
return (
<main>
Expand All @@ -63,7 +56,7 @@ function WorkshopGroupsPageComponent(
}

export function renderWorkshopGroupsPageHTML(
workshopGroups: WorkshopGroups,
workshopGroups: WorkshopGroup[],
) {
return withLayout(
<WorkshopGroupsPageComponent workshopGroups={workshopGroups} />,
Expand Down Expand Up @@ -98,32 +91,31 @@ function WorkshopGroupTableComponent(
}

function WorkshopGroupPageComponent(
props: { groupID: string; workshops: Workshop[] },
props: { group: WorkshopGroup },
) {
return (
<main>
<Helmet>
<html lang="en" amp />
<title>
{props.groupID} - Open Source Software workshops
{props.group.groupID} - Open Source Software workshops
</title>
<meta
name="description"
content={`Workshops in the ${props.groupID} series`}
content={`Workshops in the ${props.group.groupID} series`}
/>
</Helmet>

<h1>{props.groupID}</h1>
<WorkshopGroupTableComponent workshops={props.workshops} />
<h1>{props.group.groupID}</h1>
<WorkshopGroupTableComponent workshops={props.group.workshops} />
</main>
);
}

export function renderWorkshopGroupPageHTML(
groupID: string,
workshops: Workshop[],
group: WorkshopGroup,
) {
return withLayout(
<WorkshopGroupPageComponent groupID={groupID} workshops={workshops} />,
<WorkshopGroupPageComponent group={group} />,
);
}
17 changes: 17 additions & 0 deletions lib/workshops/walk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { expandGlob } from "#/deps.ts";
import type { WorkshopGroup } from "./workshops.ts";
import { parseWorkshopsYAML } from "./workshops.ts";

function trimExtension(path: string): string {
return path.replace(/\.[^.]*$/, "");
}

export async function* walkWorkshopsYAML(glob: string | URL) {
for await (const stat of expandGlob(glob)) {
const content = await Deno.readTextFile(stat.path);
const groupID = trimExtension(stat.name);
const workshops = parseWorkshopsYAML(content);
const group: WorkshopGroup = { groupID, workshops };
yield group;
}
}
51 changes: 11 additions & 40 deletions lib/workshops/workshops.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { parseYAML } from "#/deps.ts";

export interface WorkshopGroup {
groupID: string;
workshops: Workshop[];
}

export interface Workshop {
title: string;
description?: string;
timestamp: string;
group_id?: string;
url?: string;
}

Expand All @@ -13,58 +17,25 @@ export function isWorkshop(obj: unknown): obj is Workshop {
typeof obj === "object" &&
obj !== null &&
typeof (obj as Workshop).title === "string" &&
(obj as Workshop).description === undefined ||
typeof (obj as Workshop).description === "string" &&
typeof (obj as Workshop).timestamp === "string" &&
(obj as Workshop).group_id === undefined ||
typeof (obj as Workshop).group_id === "string" &&
(obj as Workshop).url === undefined ||
typeof (obj as Workshop).url === "string"
);
}

export function isWorkshops(obj: unknown): obj is Workshop[] {
return Array.isArray(obj) && obj.every(isWorkshop);
}

export function parseWorkshops(content: string): Workshop[] {
const workshops = JSON.parse(content);
if (!isWorkshops(workshops)) {
throw new Error("Invalid workshops");
}

return workshops;
return Array.isArray(obj) && obj.every((workshop) => isWorkshop(workshop));
}

export function parseWorkshopsYAML(content: string): Workshop[] {
export function parseWorkshopsYAML(
content: string,
): Workshop[] {
const workshops = parseYAML(content);
if (!isWorkshops(workshops)) {
throw new Error("Invalid workshops");
}

return workshops;
}

export const DEFAULT_GROUP_ID = "-";

export function groupWorkshops(
workshops: Workshop[],
defaultGroupID = DEFAULT_GROUP_ID,
) {
const groups: Record<string, Workshop[]> = {};
for (const workshop of workshops) {
const groupID = workshop.group_id ?? defaultGroupID;
if (!(groupID in groups)) {
groups[groupID] = [];
}

groups[groupID].push(workshop);
}

// Sort the workshops by timestamp.
for (const groupID in groups) {
groups[groupID].sort((a, b) => a.timestamp.localeCompare(b.timestamp));
}

return groups;
}

export type WorkshopGroups = ReturnType<typeof groupWorkshops>;
54 changes: 31 additions & 23 deletions main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import {
walkProjects,
} from "#/lib/projects/mod.ts";
import {
groupWorkshops,
parseWorkshopsYAML,
renderWorkshopGroupPageHTML,
renderWorkshopGroupsPageHTML,
walkWorkshopsYAML,
type WorkshopGroup,
} from "#/lib/workshops/mod.ts";
import { withLayout } from "./lib/shared/layout/mod.ts";
import { withLayout } from "#/lib/shared/layout/mod.ts";
import { PageHeading } from "#/lib/shared/page_heading/mod.ts";
import { join } from "#/deps.ts";

// Build script for generating static site from markdown files
// in the projects directory.
Expand All @@ -25,50 +26,57 @@ async function main(args: string[]) {
staticdir: ["s"],
},
default: {
indir: "projects",
indir: "./",
outdir: "build",
staticdir: "static",
},
});

// Create outdir if it does not exist.
await Deno.mkdir(flags.outdir, { recursive: true });
// Create projects directory if it does not exist.
await Deno.mkdir(join(flags.outdir, "projects"), { recursive: true });

// Render projects assets.
const projects: Project[] = [];
for await (const project of walkProjects(`${flags.indir}/*.md`)) {
for await (
const project of walkProjects(join(flags.indir, "projects", "*.md"))
) {
projects.push(project);
const html = renderProjectPageHTML(project, flags["base-url"]);
await Deno.writeTextFile(`${flags.outdir}/${project.id}.html`, html);
await Deno.writeTextFile(
join(flags.outdir, "projects", `${project.id}.html`),
html,
);
const json = JSON.stringify(project, null, 2);
await Deno.writeTextFile(`${flags.outdir}/${project.id}.json`, json);
await Deno.writeTextFile(
join(flags.outdir, "projects", `${project.id}.json`),
json,
);
}

const projectsIndexHTML = await renderProjectsPageHTML(projects);
await Deno.writeTextFile(
`${flags.outdir}/projects.html`,
join(flags.outdir, "projects.html"),
projectsIndexHTML,
);

// Create workshops directory if it does not exist.
await Deno.mkdir(`${flags.outdir}/workshops`, { recursive: true });
await Deno.mkdir(join(flags.outdir, "series"), { recursive: true });

// Render workshops assets.
const workshopsYAML = await Deno.readTextFile("workshops.yaml");
const workshopGroups = groupWorkshops(parseWorkshopsYAML(workshopsYAML));
for (const groupID in workshopGroups) {
const workshopIndexHTML = renderWorkshopGroupPageHTML(
groupID,
workshopGroups[groupID],
);

const workshopGroups: WorkshopGroup[] = [];
for await (
const group of walkWorkshopsYAML(join(flags.indir, "workshops", "*.yaml"))
) {
workshopGroups.push(group);
const html = renderWorkshopGroupPageHTML(group);
await Deno.writeTextFile(
`${flags.outdir}/workshops/${groupID}.html`,
workshopIndexHTML,
join(flags.outdir, "series", `${group.groupID}.html`),
html,
);
const json = JSON.stringify(group, null, 2);
await Deno.writeTextFile(
`${flags.outdir}/workshops/${groupID}.json`,
JSON.stringify(workshopGroups[groupID], null, 2),
join(flags.outdir, "series", `${group.groupID}.json`),
json,
);
}

Expand Down
3 changes: 0 additions & 3 deletions workshops.yaml → workshops/spring2024.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
- title: "Spring 2024 Open Source Software Kickoff"
description: "Launch into the vast expanse of collaborative development, exploring new frontiers and innovating together!"
timestamp: "2024-02-08"
group_id: "spring2024"
url: "https://acmcsuf.com/spring24-oss-kickoff"

- title: "Making First Contributions"
description: "Make your first open source contribution and learn the basics of Git and GitHub."
timestamp: "2024-02-15"
group_id: "spring2024"
url: "https://acmcsuf.com/1st-slides"

- title: "How to win FullyHacks"
description: "How to win a hackathon, and how to win FullyHacks in particular."
timestamp: "2024-02-22"
group_id: "spring2024"
url: "https://acmcsuf.com/winning-fh"

0 comments on commit ba28554

Please sign in to comment.