meal-order-manager/src/scraper/scrape_menu.py
Adam Moussa 265d12b890
feat(menu): publish the weekly menu from the job worker
Monday publish parses the catalog embedded in the Redefine menu page and runs on the Fargate worker, so the GitHub Actions scrape cron can go away.
2026-09-25 17:43:34 -04:00

60 lines
1.8 KiB
Python

"""Fetch the Redefine Meals menu and write menu JSON for local form generation."""
import json
import sys
from datetime import datetime
from pathlib import Path
try:
from scraper.parse_menu import MenuParseError, fetch_menu
except ImportError:
from parse_menu import MenuParseError, fetch_menu
CONFIG_PATH = Path(__file__).resolve().parents[2] / "config.json"
def load_config():
with open(CONFIG_PATH) as f:
return json.load(f)
def scrape_menu(url: str, **_kwargs) -> dict:
return fetch_menu(url)
def main():
config = load_config()
url = config.get("menu_url", "https://www.redefinemeals.com/menu")
output_dir = Path(__file__).resolve().parents[2] / config.get(
"output_dir", "output"
)
output_dir.mkdir(exist_ok=True)
print(f"Fetching menu from {url} ...")
try:
result = scrape_menu(url)
except MenuParseError as exc:
print(f"Error: {exc}", file=sys.stderr)
sys.exit(1)
week_str = datetime.now().strftime("%Y-W%U")
output_file = output_dir / f"menu-{week_str}.json"
with open(output_file, "w") as f:
json.dump(result, f, indent=2)
print(f"\nFetched {result['meal_count']} meals")
print(f"Output saved to {output_file}")
print(f"\n{'Name':<40} {'Price':>7} {'Cal':>5} {'Prot':>5} {'Tags'}")
print("-" * 90)
for meal in result["meals"]:
tags = ", ".join(meal["dietary_tags"]) if meal["dietary_tags"] else ""
new = " *NEW*" if meal["is_new"] else ""
price = f"${meal['price']:.2f}" if meal["price"] is not None else "?"
cal = str(meal["calories"]) if meal["calories"] else "?"
prot = meal["protein"] or "?"
print(f"{(meal['name'] + new):<40} {price:>7} {cal:>5} {prot:>5} {tags}")
if __name__ == "__main__":
main()