Skip to content

wardseward/morningBriefingGenerator

Repository files navigation

Morning Briefing

A local-first daily briefing generator that builds a single HTML report (output/today.html) covering:

  • Weather — forecast, radar, lightning, satellite imagery (NWS, US locations)
  • News — RSS feeds with optional AI-powered summaries and headline rewrites (Ollama)
  • HF Propagation — solar indices, band conditions, and signal quality (ham radio)
  • Gmail — recent messages grouped by label, with optional AI insights
  • Calendar — today's and tomorrow's events (Google Calendar)
  • Apple Reminders — incomplete items grouped by list, due-soon callouts (macOS only)
  • TV Watchlist — upcoming episodes and poster thumbnails (TMDB)
  • Email delivery — optional daily HTML email via Gmail

Every data section can be toggled on/off, and each output mode (local HTML report, email) can be independently enabled or disabled in the config.


Platform Support

Feature macOS Windows Linux
Core briefing (weather, news, solar, TV) Yes Yes Yes
Gmail + Calendar Yes Yes Yes
AI news (Ollama) Yes Yes Yes
Email delivery Yes Yes Yes
Apple Reminders Yes No No
Scheduled generation (launchd) Yes Via Task Scheduler Via cron

Apple Reminders requires macOS EventKit. On Windows/Linux, disable the reminders section in your config and the dependency is skipped automatically.


Quick Setup

macOS

git clone https://github.com/YOUR_USERNAME/morning-briefing.git
cd morning-briefing
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

cp config_personal.example.py config_personal.py
# Edit config_personal.py with your location, sections, labels, etc.

# Google OAuth (requires credentials/google_credentials.json — see step 3.3)
python setup/auth.py

# Generate + open
python main.py
open output/today.html

Windows (PowerShell)

git clone https://github.com/YOUR_USERNAME/morning-briefing.git
cd morning-briefing
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt

copy config_personal.example.py config_personal.py
# Edit config_personal.py with your location, sections, labels, etc.
# Set reminders to disabled: "reminders": {"enabled": False, ...}

# Google OAuth (requires credentials\google_credentials.json — see step 3.3)
python setup\auth.py

# Generate + open
python main.py
start output\today.html

1) Personal Configuration

All personal settings live in config_personal.py, which is gitignored and never committed. The file config.py contains generic shareable defaults.

  1. Copy the example: cp config_personal.example.py config_personal.py
  2. Edit config_personal.py with your values

Only include variables you want to override. Everything else falls back to config.py defaults.

Key settings to customize:

Setting Purpose
CITY, LAT, LON Your location for weather
NWS_OFFICE, NWS_GRID_X, NWS_GRID_Y NWS forecast grid (run python setup/find_grid.py)
CALLSIGN, GRID_SQUARE Ham radio (or disable the solar section)
SECTIONS Toggle/reorder data sections — dict order = tab order
HTML_REPORT_ENABLED Write local HTML file to output/ (default: True)
EMAIL_ENABLED, EMAIL_TO Send daily email via Gmail (default: False)
GMAIL_LABELS Map display names to your Gmail label names
REMINDER_LISTS Which Apple Reminders lists to show (macOS only)
RADAR_STATION, GOES_SECTOR Weather map sources

2) Prerequisites

  • Python 3.10+ (3.11+ recommended)
  • Google account (Gmail/Calendar API access)
  • TMDB account + API credentials (for TV watchlist/posters)
  • Optional: Ollama for free local AI news summaries

macOS:

brew install python

Windows:

Download from python.org. During install, check "Add Python to PATH".


3) First-Time Setup (Step-by-Step)

Step 3.1 — Python environment

macOS / Linux:

cd morning-briefing
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Verify: which python3 should point to .venv/bin/python3.

Windows (PowerShell):

cd morning-briefing
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt

Verify: where python should point to .venv\Scripts\python.exe.

Step 3.2 — Weather location (NWS grid)

Run the grid finder to get your NWS forecast office and grid coordinates:

python setup/find_grid.py

Then set NWS_OFFICE, NWS_GRID_X, NWS_GRID_Y in your config_personal.py.

Step 3.3 — Google OAuth (Gmail + Calendar + Send)

3.3.a — Create Google Cloud project

  1. Go to Google Cloud Console.
  2. Create or select a project.
  3. Enable these APIs:
    • Gmail API
    • Google Calendar API

3.3.b — Create OAuth desktop credentials

  1. APIs & Services -> Credentials -> Create Credentials -> OAuth client ID
  2. Application type: Desktop app
  3. Download the JSON file
  4. Save it as credentials/google_credentials.json

3.3.c — Authorize

python setup/auth.py

This opens a browser for Google sign-in and saves credentials/google_token.json with these scopes:

  • gmail.readonly — read emails by label
  • gmail.send — send the daily briefing email
  • calendar.readonly — read calendar events

Step 3.4 — TMDB setup (TV watchlist + posters)

Set environment variables (or add to your config_personal.py):

macOS / Linux:

export TMDB_API_KEY="your_tmdb_api_v3_key"
export TMDB_READ_ACCESS_TOKEN="your_tmdb_v4_read_token"
export TMDB_ACCOUNT_ID="your_tmdb_account_id"
export TMDB_USE_WATCHLIST="true"

Windows (PowerShell):

$env:TMDB_API_KEY = "your_tmdb_api_v3_key"
$env:TMDB_READ_ACCESS_TOKEN = "your_tmdb_v4_read_token"
$env:TMDB_ACCOUNT_ID = "your_tmdb_account_id"
$env:TMDB_USE_WATCHLIST = "true"

Get your API keys at themoviedb.org/settings/api.

Step 3.5 — AI News (Ollama, optional)

Ollama runs locally and is free. It powers headline rewrites and email AI insights.

macOS:

brew install ollama
brew services start ollama
ollama pull phi3:mini
ollama pull llama3.1:8b

Windows:

Download the installer from ollama.com/download. Then in a terminal:

ollama pull phi3:mini
ollama pull llama3.1:8b

Ollama runs as a background service automatically on Windows after install.

Environment variables (or set via config_personal.py):

NEWS_AI_ENABLED=true
NEWS_AI_PROVIDER=ollama
NEWS_AI_PROFILE=fast              # fast | quality
NEWS_OLLAMA_MODEL_FAST=phi3:mini
NEWS_OLLAMA_MODEL_QUALITY=llama3.1:8b
NEWS_OLLAMA_URL=http://127.0.0.1:11434

Step 3.6 — Output modes

By default, the briefing writes a local HTML report to output/today.html. You can also enable email delivery, or use email-only mode and skip the local file entirely.

In your config_personal.py:

HTML_REPORT_ENABLED = True          # write output/today.html (default: True)
EMAIL_ENABLED       = True          # send email via Gmail    (default: False)
EMAIL_TO            = "you@example.com"

Examples:

  • Both enabled — get a local file and a daily email.
  • Email only — set HTML_REPORT_ENABLED = False and EMAIL_ENABLED = True. No file is written to output/.
  • Local only — keep defaults (HTML_REPORT_ENABLED = True, EMAIL_ENABLED = False).

You can also override these per-run with CLI flags (see section 4).

Step 3.7 — First run

macOS / Linux:

source .venv/bin/activate
python main.py
open output/today.html

Windows:

.venv\Scripts\Activate.ps1
python main.py
start output\today.html

4) Daily Commands

Generate a new briefing:

python main.py

Common flags:

Flag Effect
Output modes
--html Force local HTML report (overrides config)
--no-html Skip local HTML report
--send-email Force email delivery (overrides config)
--no-email Skip email delivery
Data sections
--no-gmail Skip Gmail fetch
--no-cal Skip Calendar fetch
--no-news Skip RSS news
--no-weather Skip weather
--no-solar Skip HF propagation
--no-tv Skip TV watchlist
--no-reminders Skip Apple Reminders

Switch AI news profile and regenerate:

python setup/set_news_profile.py fast --apply-now --open
python setup/set_news_profile.py quality --apply-now --open

Shell aliases (macOS/Linux, add to ~/.zshrc or ~/.bashrc):

alias morning="open ~/morning-briefing/output/today.html"
alias briefing-fast="cd ~/morning-briefing && source .venv/bin/activate && python setup/set_news_profile.py fast --apply-now --open"
alias briefing-quality="cd ~/morning-briefing && source .venv/bin/activate && python setup/set_news_profile.py quality --apply-now --open"

5) Scheduled Generation

macOS (launchd)

A launchd plist template is included. It runs the briefing every morning at a configured time.

# Copy and customize the example plist with your paths, API keys, and email
cp setup/com.ward.morning-briefing.plist.example setup/com.ward.morning-briefing.plist
# Edit setup/com.ward.morning-briefing.plist — update ProgramArguments paths,
# EnvironmentVariables (TMDB keys, NEWS_AI settings, EMAIL_TO), etc.

# Install the LaunchAgent
cp setup/com.ward.morning-briefing.plist ~/Library/LaunchAgents/
launchctl load ~/Library/LaunchAgents/com.ward.morning-briefing.plist

# Verify
launchctl list | grep morning-briefing

To update after editing the plist:

launchctl unload ~/Library/LaunchAgents/com.ward.morning-briefing.plist
launchctl load ~/Library/LaunchAgents/com.ward.morning-briefing.plist

Optional — wake the machine before the scheduled run:

sudo pmset repeat wakeorpoweron MTWRF 06:50:00

Windows (Task Scheduler)

  1. Open Task Scheduler (taskschd.msc)
  2. Click Create Basic Task
  3. Set trigger: Daily, at your desired time (e.g. 6:55 AM)
  4. Set action: Start a program
    • Program: C:\path\to\morning-briefing\.venv\Scripts\python.exe
    • Arguments: main.py
    • Start in: C:\path\to\morning-briefing
  5. In the task properties, go to the General tab and check "Run whether user is logged on or not"
  6. Under Settings, check "Wake the computer to run this task" if desired

Set environment variables system-wide via System Properties > Environment Variables, or create a wrapper batch file:

@echo off
cd /d C:\path\to\morning-briefing
set NEWS_AI_ENABLED=true
set NEWS_AI_PROVIDER=ollama
set NEWS_AI_PROFILE=fast
set TMDB_API_KEY=your_key
set TMDB_READ_ACCESS_TOKEN=your_token
set TMDB_ACCOUNT_ID=your_id
set TMDB_USE_WATCHLIST=true
.venv\Scripts\python.exe main.py

Point the Task Scheduler action at this .bat file instead.

Linux (cron)

crontab -e

Add a line like:

55 6 * * * cd /path/to/morning-briefing && .venv/bin/python main.py >> logs/cron.log 2>&1

Set environment variables in the crontab or in a wrapper script.


6) News AI Modes

Mode Model Speed Quality Headlines Rewritten
fast phi3:mini Fast Good Up to 3 per category
quality llama3.1:8b Slower Better Up to 8 per category

Switch the default profile:

python setup/set_news_profile.py fast
python setup/set_news_profile.py quality

Switch and immediately regenerate:

python setup/set_news_profile.py fast --apply-now --open
python setup/set_news_profile.py quality --apply-now --open

7) Maintenance

Update dependencies

pip install -r requirements.txt

Re-authorize Google

python setup/auth.py

Verify Ollama

macOS:

brew services list | grep ollama
ollama list

Windows / Linux:

ollama list

Health check (macOS)

python setup/doctor.py
python setup/doctor.py --verbose

The doctor script checks: venv, Google token scopes, LaunchAgent plist, Ollama service, and model availability. It is macOS-specific due to launchd and brew checks.

Smoke test individual sources

python sources/weather.py
python sources/solar.py
python sources/news.py
python sources/tv.py
python sources/gmail_source.py
python sources/calendar_source.py

8) Troubleshooting

ModuleNotFoundError

Make sure you're using the virtual environment:

macOS / Linux:

source .venv/bin/activate
python main.py

Windows:

.venv\Scripts\Activate.ps1
python main.py

insufficientPermissions or scope errors

Re-run the auth script to refresh the token with all required scopes:

python setup/auth.py

No AI news generated

  1. Confirm NEWS_AI_ENABLED=true
  2. Confirm NEWS_AI_PROVIDER=ollama
  3. Verify Ollama is running: ollama list
  4. Verify models are pulled: ollama pull phi3:mini
  5. Confirm NEWS_OLLAMA_URL is reachable (http://127.0.0.1:11434)

No TV thumbnails

  1. Confirm TMDB_API_KEY and TMDB_READ_ACCESS_TOKEN are set
  2. Confirm TMDB_USE_WATCHLIST=true
  3. Confirm your TMDB watchlist is not empty

Reminders not showing (macOS)

  1. Confirm REMINDER_LISTS in config_personal.py matches your actual list names
  2. Grant Terminal / IDE access to Reminders in System Settings > Privacy & Security > Reminders

Reminders not available (Windows / Linux)

Apple Reminders is macOS-only. Set "reminders": {"enabled": False, ...} in your SECTIONS config.

Scheduled run didn't happen (macOS)

cat logs/run.log
cat logs/error.log
launchctl list | grep morning-briefing

Reload if needed:

launchctl unload ~/Library/LaunchAgents/com.ward.morning-briefing.plist
launchctl load ~/Library/LaunchAgents/com.ward.morning-briefing.plist

9) File Reference

morning-briefing/
├── main.py                        # Entry point — orchestrates fetch + render
├── config.py                      # Shared defaults (generic, committed)
├── config_personal.py             # YOUR overrides (gitignored)
├── config_personal.example.py     # Template for config_personal.py
├── renderer.py                    # Jinja2 rendering for browser + email HTML
├── requirements.txt
│
├── templates/
│   ├── briefing.html              # Browser report (tabbed UI)
│   └── briefing_email.html        # Email-friendly flat layout
│
├── sources/
│   ├── weather.py                 # NWS forecast + maps
│   ├── solar.py                   # HF propagation / solar indices
│   ├── news.py                    # RSS feeds + Ollama AI rewrites
│   ├── gmail_source.py            # Gmail by label
│   ├── gmail_ai.py                # AI insights for Gmail categories
│   ├── calendar_source.py         # Google Calendar events
│   ├── reminders.py               # Apple Reminders (macOS only)
│   ├── tv.py                      # TMDB watchlist + posters
│   └── email_sender.py            # Gmail API email delivery
│
├── setup/
│   ├── auth.py                    # Google OAuth flow
│   ├── doctor.py                  # Health check (macOS)
│   ├── find_grid.py               # NWS grid coordinate finder
│   ├── set_news_profile.py        # Switch AI profile + regenerate
│   ├── import_tmdb_watchlist.py   # Import shows to TMDB watchlist
│   └── com.ward.morning-briefing.plist.example  # launchd template
│
├── credentials/                   # OAuth tokens (gitignored)
├── output/                        # Generated HTML reports
└── logs/                          # Run + error logs

10) Security Notes

  • credentials/ — OAuth tokens, never committed.
  • config_personal.py — your personal settings, gitignored.
  • setup/com.ward.morning-briefing.plist — contains API keys, gitignored.
  • Google scopes: gmail.readonly, gmail.send, calendar.readonly.
  • API keys (TMDB, Ollama) should be set via environment variables or config_personal.py, never in config.py.
  • To revoke access: remove app permissions in Google Account Security.

11) Monthly Checklist

  1. Run a full generation and confirm all sections populate.
  2. Verify the scheduler is loaded (macOS: launchctl list | grep morning-briefing).
  3. Verify Ollama is running and models are present (ollama list).
  4. Check Google token still works (python setup/auth.py if needed).
  5. Refresh TMDB watchlist if TV data looks stale.

About

Morning Brief generator app

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors