Skip to content

Commit

Permalink
menu function
Browse files Browse the repository at this point in the history
  • Loading branch information
33tm committed Sep 28, 2024
1 parent 0c9818a commit c06f020
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
1 change: 1 addition & 0 deletions functions/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export {api} from './api';
export {menu} from './menu';
export {sgyauth} from './sgyauth';
export * as sgyfetch from './sgyfetch';
export * as weather from './weather';
87 changes: 87 additions & 0 deletions functions/src/menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as functions from 'firebase-functions';
import admin from './util/adminInit';

import { DateTime } from 'luxon';
import { getAlternates } from './util/apiUtil';
import { getSchedule } from '@watt/shared/util/schedule';
import { SCHOOL_START, SCHOOL_END } from '@watt/shared/data/schedule';


const firestore = admin.firestore();

export const menu = functions.https.onCall(async () => {
const now = DateTime.now().setZone('America/Los_Angeles');

if (now < SCHOOL_START || now > SCHOOL_END) {
await firestore.collection('gunn').doc('menu').set({
timestamp: new Date().toISOString(),
menu: {}
});
return;
}

const current = (await firestore.collection('gunn').doc('menu').get()).data()!;
if (DateTime.fromISO(current.timestamp).plus({ week: 1 }) > now)
return;

const { daysInMonth, month, year } = now.plus({ week: 1 });
const { alternates } = await getAlternates();
const nutrislice = 'https://pausd.api.nutrislice.com/menu/api';
const nutrition = new Map();

async function getNutrition(day: number) {
return await Promise.all(['breakfast', 'lunch'].map(async meal => {
const { days } = await fetch(`${nutrislice}/weeks/school/henry-m-gunn-hs/menu-type/${meal}/${year}/${month}/${day}`)
.then(res => res.json())
.catch(() => []);
if (!days) return;
const items = days
.flatMap((day: any) => day.menu_items)
.map((items: any) => items.food)
.filter(Boolean);
for (const item of items) {
nutrition.set(item.name, {
serving: Object
.values(item.serving_size_info)
.every(x => !x) ? null : item.serving_size_info,
nutrition: Object
.values(item.rounded_nutrition_info)
.every(x => !x) ? null : item.rounded_nutrition_info,
ingredients: item.ingredients || null
});
}
}));
}

async function getMenu(date: DateTime) {
const { year, month, day } = date
const [brunch, lunch] = await Promise.all(['breakfast', 'lunch'].map(async meal => {
const { menu_items } = await fetch(`${nutrislice}/digest/school/henry-m-gunn-hs/menu-type/${meal}/date/${year}/${month}/${day}`)
.then(res => res.json())
.catch(() => []);
if (!menu_items) return;
return Object.fromEntries(menu_items.map((item: string) => [item, nutrition.get(item) ?? null]));
}))
return [date.toFormat('MM-dd'), { brunch, lunch }];
}

const days = Array
.from({ length: daysInMonth }, (_, i) => DateTime
.fromObject({ year, month, day: i + 1 })
.setZone('America/Los_Angeles'))
.filter(day => {
const { periods } = getSchedule(day, alternates);
return periods && periods.filter(({ n }) => n === 'B' || n === 'L').length;
});

await Promise.all(Array
.from({ length: Math.ceil((days[days.length - 1].day - days[0].day) / 7 + 1) }, (_, i) => 7 * i + days[0].day)
.map(getNutrition));

const menu = Object.fromEntries(await Promise.all(days.map(getMenu)));

await firestore.collection('gunn').doc('menu').set({
timestamp: new Date().toISOString(),
menu: { ...current.menu, ...menu }
});
})

0 comments on commit c06f020

Please sign in to comment.