Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# ----- PostgreSQL (Docker) -----
POSTGRES_USER=forum
POSTGRES_PASSWORD=forum_password
POSTGRES_PASSWORD=YOUR_DB_PASSWORD_HERE
POSTGRES_DB=the_forum
POSTGRES_PORT=5434

Expand All @@ -16,17 +16,17 @@ DATABASE_URL=postgresql://forum:forum_password@localhost:5434/the_forum
AUTH_SECRET=your-auth-secret-here
AUTH_AZURE_AD_CLIENT_ID=your-client-id
AUTH_AZURE_AD_CLIENT_SECRET=your-client-secret
AUTH_AZURE_AD_TENANT_ID=2ff60116-7431-425d-b5af-077d7791bda4
AUTH_AZURE_AD_TENANT_ID=YOUR_TENANT_ID_HERE

# ----- AWS S3 (image uploads) -----
# AWS_S3_BUCKET=the-forum-uploads
# AWS_REGION=us-east-1

# ----- Next.js public vars (prefix with NEXT_PUBLIC_) -----
# NEXT_PUBLIC_API_URL=http://localhost:8000
NEXT_PUBLIC_MAPBOX_TOKEN=pk.your-mapbox-public-token
NEXT_PUBLIC_CAMPUS_MAP_TOKEN=pk.campus-map-public-token
NEXT_PUBLIC_CAMPUS_MAP_STYLE=mapbox://styles/account/style-id
NEXT_PUBLIC_MAPBOX_TOKEN=YOUR_CAMPUS_MAPBOX_TOKEN_HERE
NEXT_PUBLIC_CAMPUS_MAP_TOKEN=YOUR_CAMPUS_MAP_TOKEN_HERE
NEXT_PUBLIC_CAMPUS_MAP_STYLE=YOUR_CAMPUS_MAP_STYLE_HERE

# ----- FastAPI -----
# FASTAPI_SECRET_KEY=changeme
Expand All @@ -44,4 +44,4 @@ NEXT_PUBLIC_CAMPUS_MAP_STYLE=mapbox://styles/account/style-id

# ----- Listserv Scraper -----
LISTSERV_EMAIL=tigerapp@princeton.edu
LISTSERV_PASSWORD=your-listserv-password
LISTSERV_PASSWORD=YOUR_LISTSERV_PASSWORD_HERE
41 changes: 41 additions & 0 deletions .github/workflows/scrape_listserv.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Scrape WhitmanWire

on:
schedule:
# Runs at 8:00 AM UTC (4:00 AM Eastern Time) every day
- cron: '0 8 * * *'
workflow_dispatch: # Allows you to click a "Run workflow" button in GitHub's UI

jobs:
scrape-and-commit:
runs-on: ubuntu-latest
# This permission is required so the bot can push the JSON file back to your repo
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11' # The script uses standard libraries, so this is fine

- name: Run Scraper
env:
# Pulls securely from GitHub Secrets
LISTSERV_EMAIL: ${{ secrets.LISTSERV_EMAIL }}
LISTSERV_PASSWORD: ${{ secrets.LISTSERV_PASSWORD }}
run: |
python3 apps/listserv-scraper/src/scrape_listserv.py --list WHITMANWIRE --limit 100 --fetch-bodies

- name: Commit and push changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Stage the specific data folder where the script saves its output
git add apps/listserv-scraper/data/
# Commit the changes; if there are no new emails, it fails gracefully instead of crashing
git commit -m "chore: update WhitmanWire scraped data" || echo "No changes to commit"
git push
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ build/
!.env.example
!**/.env.example
!**/env.local.example
.forum_venv/

# ---- Database ----
drizzle/
Expand Down
4 changes: 2 additions & 2 deletions apps/database/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"scripts": {
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:push": "drizzle-kit push",
"db:push": "drizzle-kit push --force",
"db:studio": "drizzle-kit studio",
"db:seed": "tsx src/seed.ts",
"db:seed": "bun src/seed.ts",
"lint": "biome check .",
"check-types": "tsc --noEmit"
},
Expand Down
56 changes: 34 additions & 22 deletions apps/database/src/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,35 @@ import {
timestamp,
uuid,
varchar,
vector,
} from "drizzle-orm/pg-core";

// ── Enums ─────────────────────────────────────────────────

// YUBI has modified event tags
export const eventTagEnum = pgEnum("event_tag", [
"free-food",
"workshop",
"performance",
"speaker",
"social",
"free food",
"career",
"sports",
"music",
"art",
"academic",
"cultural",
"community-service",
"religious",
"political",
"research",
"academics",
"tech",
"entrepreneurship",
"politics",
"visual arts",
"performing arts",
"literature",
"culture",
"music",
"gaming",
"outdoor",
"athletics",
"religion",
"sustainability",
"outdoors",
"wellness",
"community service",
"speaker event",
"social event",
"stem",
]);

export const campusRegionEnum = pgEnum("campus_region", [
Expand All @@ -59,14 +65,14 @@ export const notificationTypeEnum = pgEnum("notification_type", [
export const orgCategoryEnum = pgEnum("org_category", [
"career",
"affinity",
"performance",
"academic",
"athletic",
"social",
"cultural",
"religious",
"political",
"service",
"performing arts",
"academics",
"athletics",
"social event",
"culture",
"religion",
"politics",
"community service",
]);

export const orgRoleEnum = pgEnum("org_role", ["owner", "officer", "member"]);
Expand Down Expand Up @@ -219,6 +225,11 @@ export const eventTags = pgTable(
(t) => [primaryKey({ columns: [t.eventId, t.tag] })],
);

export const eventTagEmbeddings = pgTable("event_tag_embeddings", {
tagName: eventTagEnum("tag_name").primaryKey(),
embedding: vector("embedding", { dimensions: 1536 }).notNull(),
});

export const rsvps = pgTable(
"rsvps",
{
Expand Down Expand Up @@ -278,6 +289,7 @@ export const pipelineLogStatusEnum = pgEnum("pipeline_log_status", [
"skipped_not_event",
"duplicate",
"error",
"needs_review",
]);

export const listservConfigs = pgTable("listserv_configs", {
Expand Down
Loading
Loading