Skip to content

Commit

Permalink
Fetching termcard from google calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
rachleona committed Sep 5, 2024
1 parent 3366410 commit 37737d8
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 52 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
"bulma-switch": "^2.0.4",
"ics": "^3.5.0",
"luxon": "^3.4.3",
"node-fetch": "^3.3.2",
"node-ical": "^0.19.0",
"svelte-fa": "^3.0.4",
"svelte-markdown": "^0.4.0",
"title-case": "^4.1.2"
Expand Down
48 changes: 48 additions & 0 deletions src/lib/calendar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import ical from "node-ical";
import type { VEvent } from "node-ical";
import type { Events } from "$components/events/event";
import { titleCase } from "title-case";

type EventDateTimes = {
date: [number, number, number],
time: [number, number],
duration: [number, number]
};

function getEventDateTimes (start: Date, end: Date):EventDateTimes {
const date = start.getDate();
const month = start.getMonth() + 1;
const year = start.getFullYear();
const hour = start.getHours();
const minute = start.getMinutes();
const durationInMins = Math.round((end.getTime() - start.getTime()) / 60000);

return {
date: [year, month, date],
time: [hour, minute],
duration: [Math.floor(durationInMins / 60), durationInMins % 60]
}
}

export async function getEvents<T>(calendarURL: string, start: Date, end: Date, identifyType: (type: string) => T): Promise<Events<T>> {
let events:Events<T> = [];
const rawCalendar = await ical.async.fromURL(calendarURL);
events = Object.values(rawCalendar)
.filter(e => e.type == "VEVENT" && e.start > start && e.start < end)
.map((e:VEvent) => {
const eventDetails = /(?<type>jcr|soc): ?(?<title>[A-Za-z0-9-\/ ]+)/gmi.exec(e.summary).groups;
const { date, time, duration } = getEventDateTimes(e.start, e.end);

return {
description: titleCase(eventDetails.title),
date,
time,
duration,
location: e.location,
type: identifyType(eventDetails.type)
};
});

console.log(events);
return events;
}
31 changes: 26 additions & 5 deletions src/routes/get-involved/termcard/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
import Content from "$components/elements/Content.svelte";
import Calendar from "$components/events/Calendar.svelte";
import PageHeader from "$components/PageHeader.svelte";
import { termcard, term } from "./termcard";
import { getEvents } from "$lib/calendar"
import {
term,
startDate,
endDate,
termcardURL,
identifyTermcardEventType
} from "./termcard";
import type { TermcardEventTypes } from "./termcard";
const termcardPromise = getEvents<TermcardEventTypes>(termcardURL, startDate, endDate, identifyTermcardEventType);
</script>

<PageHeader
Expand All @@ -26,9 +35,21 @@
</a>
</div>
</div>
<Calendar
events={termcard}
colors={{ society: "#A28000", jcr: "#146A46" }}
type="listYear" />
{#await termcardPromise}
<p>Loading termcard...</p>
{:then termcard}
{#if termcard && termcard.length > 0}
<Calendar
events={termcard}
colors={{ society: "#A28000", jcr: "#146A46" }}
type="listYear" />
{:else}
<p>No termcard events at the moment. Check again later!</p>
{/if}
{:catch error}
<p>Oops! Something went wrong! Report this to the webmaster at
<a href="mailto:webmaster@thejcr.co.uk">webmaster@thejcr.co.uk</a>
</p>
{/await}
</Content>
</PageHeader>
58 changes: 12 additions & 46 deletions src/routes/get-involved/termcard/termcard.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,14 @@
import type { Events } from "$components/events/event";
export enum TermcardEventTypes {
jcr = "jcr",
soc = "society"
}

const year: number = 2024;
export const term = "Summer";
export const termcardURL = "https://calendar.google.com/calendar/ical/webmaster%40thejcr.co.uk/public/basic.ics";
export const startDate = new Date(Date.UTC(2024, 7, 18));
export const endDate = new Date(Date.UTC(2024, 7, 25));

export const term: string = "Easter";

export const termcard: Events<"jcr" | "society"> = [
{
description: "Spring Has Sprung Bop",
date: [year, 4, 26],
time: [21, 30],
duration: [3, 0],
location: "Buttery",
type: "jcr",
},
{
description: "Christ's Maths Society talks",
date: [year, 5, 2],
time: [19, 0],
duration: [1, 0],
location: "Yusuf Hamied Theatre",
type: "society",
},
{
description: "Pool Party",
date: [year, 6, 14],
time: [19, 0],
duration: [2, 0],
location: "Malcolm Bowie Bathing Pool",
type: "jcr",
},
{
description: "(Bad at) Sports Day",
date: [year, 6, 17],
time: [0, 0],
duration: [24, 0],
location: "TBC",
type: "jcr",
},
{
description: "Christ's May Ball",
date: [year, 6, 18],
time: [19, 0],
duration: [5, 0],
location: "Christ's College",
type: "jcr",
},
];
export function identifyTermcardEventType (type: string) {
if (type.toLowerCase() == "jcr") return TermcardEventTypes.jcr;
else return TermcardEventTypes.soc;
}
Loading

0 comments on commit 37737d8

Please sign in to comment.