Skip to content

Repository files navigation

Noah Eisen's Personal Website

A modern personal website built with Astro featuring integrated social media data from Strava, Letterboxd, and Goodreads, plus a data-driven resume pipeline.

Features

  • Static Site Generation: Built with Astro for fast, optimized performance
  • Social Media Integration: Automatically fetches and displays data from:
    • Strava (fitness activities with interactive maps)
    • Letterboxd (movie reviews and ratings)
    • Goodreads (book reviews and reading statistics)
  • Interactive Maps: Leaflet maps showing Strava activity routes
  • Data-Driven Resume: Single source of truth JSON file generates both the website career timeline and a compiled PDF resume

Project Structure

├── src/
│   ├── pages/           # Astro pages (index.astro is the entire site)
│   └── games/           # Game projects
├── scripts/
│   ├── social-data/             # Orchestrator + processors/scrapers for social data pipeline
│   ├── strava-fetcher/          # Strava API fetcher
│   ├── goodreads-fetcher/       # Goodreads RSS fetcher
│   ├── letterboxd-fetcher/      # Letterboxd RSS fetcher
│   └── resume-generator/        # Scripts to generate resume.tex and compile PDF
├── resume/                      # Resume source of truth
│   ├── resume_data.json         # Edit this to update resume content
│   ├── resume.tex               # Auto-generated — do not edit manually
│   ├── deedy-resume.cls         # LaTeX class file
│   └── fonts/                   # Fonts required by the LaTeX template
├── public/              # Static assets (including resume.pdf)
└── dist/                # Built website (generated, not committed)

Development Setup

Prerequisites

  • Node.js (for Astro)
  • Python 3.12+ (for social data pipeline and resume generator)
  • MacTeX (for compiling the resume PDF locally — download from https://www.tug.org/mactex/)

Installation

  1. Install Node.js dependencies:
npm install
  1. Set up Python environment:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Environment Variables

Create a .env file in the repo root:

STRAVA_CLIENT_ID=your_strava_client_id
STRAVA_CLIENT_SECRET=your_strava_client_secret
STRAVA_REFRESH_TOKEN=your_strava_refresh_token

Umami Analytics

The site uses Umami Cloud for pageviews and lightweight click tracking. The shared tracking script lives in src/components/UmamiAnalytics.astro; its public data-website-id is committed directly because it is visible in the rendered HTML anyway.

Useful docs: Add a website, Collect data, Track events.

Development

Start Development Server

npm run dev

Build for Production

npm run build

Update Social Media Data

# Fetch fresh data from external sources
python scripts/strava-fetcher/fetch_activities.py
python scripts/goodreads-fetcher/fetch_books.py
python scripts/letterboxd-fetcher/fetch_films.py

# Run the orchestrator to combine everything
python scripts/social-data/orchestrate.py

Data is written to src/data/social_data.json and picked up automatically on the next build.

Resume Pipeline

Resume content lives in a single source of truth: resume/resume_data.json.

Each work experience entry supports:

  • description — used in the PDF; add web_description for a different blurb on the website
  • items — bullet points; add skip_pdf: true to show a bullet on the website only
  • skip_pdf: true at the experience level to omit the entire entry from the PDF
  • web_text on an item to render HTML (e.g. links) on the website while keeping plain text in the PDF

After editing resume_data.json, run:

npm run resume

This will:

  1. Regenerate resume/resume.tex from the JSON
  2. Compile the PDF with xelatex (requires MacTeX)
  3. Copy the compiled PDF to public/resume.pdf

Troubleshooting PDF Compilation

If local compilation isn't working, Overleaf is a good fallback. Upload the contents of the resume/ directory and compile there, then download the PDF and place it at public/resume.pdf.

Social Data Pipeline

A two-stage pipeline collects data from external sources and combines it for the site:

  1. Fetchers pull raw data into local JSON: Strava API, Goodreads RSS, Letterboxd RSS
  2. Orchestrator reads those JSON files, computes stats, and produces src/data/social_data.json

See scripts/social-data/README.md for the full pipeline diagram and details.

Data is stored in src/data/social_data.json. This file is auto-generated — do not edit it manually.

CI/CD

GitHub Actions handles two workflows:

  • social-data-fetch.yml: Runs daily at 3AM Pacific, fetches fresh social data, commits updated JSON with [skip ci]
  • deploy.yml: Triggers on push to master and after the social data fetch completes; builds and deploys to GitHub Pages

Architecture Diagram

Architecture Diagram

High-level overview of the website architecture showing data flow from social media APIs through Python scrapers to the Astro static site.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages