Netgrimoire/Gremlin/Morning_Briefing.md
2026-04-19 04:27:24 +00:00

14 KiB

title description published date tags editor dateCreated
Consolidated Morning Briefing true 2026-04-19T04:27:14.348Z markdown 2026-04-19T04:27:14.348Z

Gremlin's Morning Briefing System

Complete automated daily briefing integrating calendars, work taskings, and personal email


Overview

The Gremlin Morning Briefing is an automated system that generates a unified HTML dashboard displaying:

  • SIL Calendar (Google Calendar synced to Nextcloud)
  • Work Email Taskings (exported from Outlook as Markdown)
  • Personal Email Tasks (parsed from MailCow IMAP via Ollama LLM)
  • Federal Holidays
  • Future: NetGrimoire stack status, Vikunja tasks

The briefing organizes everything into three priority zones:

  • 🔥 TODAY - Overdue tasks, today's events, high-priority items
  • 📆 THIS WEEK - Next 7 days planning horizon
  • 📬 LATER - Days 8-14, backlog items

Architecture

Data Sources

  1. Google Calendar (SIL) → Service Account API
  2. Nextcloud → Work briefing MD file via WebDAV
  3. MailCow IMAP → Personal email scanning
  4. Ollama (llama3.2:3b) → Email parsing for tasks/due dates
  5. Federal Holidays API → date.nager.at

Processing Pipeline

Google Calendar ──┐
Work Email MD ────┼──> Python Script ──> HTML Briefing ──> Apache ──> Glance iframe
MailCow IMAP ─────┤         ↓
Federal Holidays ─┘    Nextcloud CalDAV
                       (SIL + Taskings calendars)

Key Optimizations

  • Email Pre-screening: Regex filters reduce Ollama calls from 285 → ~30
  • Caching: Processed email IDs prevent re-processing
  • Zone-based bucketing: Smart categorization by urgency and date

Installation

Prerequisites

System Requirements:

  • Python 3.9+
  • Docker Swarm (for Glance)
  • Apache web server
  • Nextcloud instance
  • MailCow mail server
  • Ollama with llama3.2:3b model

Python Dependencies:

pip3 install --break-system-packages \
  google-auth google-auth-oauthlib google-auth-httplib2 \
  google-api-python-client \
  caldav icalendar pytz requests

1. Google Calendar Setup

Create Service Account:

  1. Go to Google Cloud Console
  2. Create project: NetGrimoire
  3. Enable Google Calendar API
  4. Create Service Account: n8n-calendar-reader@netgrimoire.iam.gserviceaccount.com
  5. Generate JSON key → save to /home/gremlin/.config/gcloud/netgrimoire-calendar-sa.json
  6. Set permissions: chmod 600 /home/gremlin/.config/gcloud/netgrimoire-calendar-sa.json

Share Calendar:

  1. Open SIL calendar in Google Calendar
  2. Settings → Share with specific people
  3. Add service account email (read-only)

2. Nextcloud Setup

Create App Password:

  1. Login to Nextcloud: https://cloud.netgrimoire.com
  2. Settings → Security → Devices & sessions
  3. Create new app password: Gremlin Briefing Script
  4. Save password for script configuration

Create Folders:

/Briefings/
  └── work-briefing.md

Upload Work Briefing:

  • Export daily work tasking email as Markdown
  • Upload to /Briefings/work-briefing.md (overwrite daily)

3. Script Installation

Deploy Script:

# Create directory structure
mkdir -p /home/gremlin/scripts
mkdir -p /home/gremlin/.config/gcloud
mkdir -p /home/gremlin/logs

# Copy script
cp gremlin-briefing-final.py /home/gremlin/scripts/
chmod 600 /home/gremlin/scripts/gremlin-briefing-final.py
chmod +x /home/gremlin/scripts/gremlin-briefing-final.py

# Edit configuration
nano /home/gremlin/scripts/gremlin-briefing-final.py

Configuration (lines 24-48):

# Nextcloud
NEXTCLOUD_PASSWORD = 'YOUR_APP_PASSWORD_HERE'

# MailCow IMAP
MAILCOW_PASSWORD = 'YOUR_MAILCOW_PASSWORD_HERE'

# Email Keywords (flagged for attention)
EMAIL_FLAG_KEYWORDS = ['mxroute', 'travel', 'dts', 'cititravel', '.mil', 'cindy']

# VIP Senders (always surface in TODAY)
EMAIL_VIP_SENDERS = ['cindy']

Test Run:

/home/gremlin/scripts/gremlin-briefing-final.py

Expected output:

============================================================
Gremlin Briefing Generator - Optimized
============================================================
Fetching Google Calendar events...
  Found 15 SIL events
Fetching work briefing from Nextcloud...
  Found work briefing (12453 chars)
  Parsed 18 work events, 24 action items
Connecting to MailCow IMAP...
  Found 285 emails in last 14 days
  Fetched 8 new emails
Pre-screening 8 emails...
  ✓ 3 emails need processing (filtered 5 junk)
Processing 3 emails with Ollama...
  Parsing: Need to get Harvey a bath on april 19th...
  ✓ Successfully parsed 3 emails
Syncing SIL calendar to Nextcloud...
  ✓ SIL sync complete
Syncing email tasks to Nextcloud...
  ✓ Added 2 email tasks to calendar
Fetching federal holidays...
  Found 11 federal holidays
Organizing items into zones...
Generating HTML briefing...
Writing to /data/nfs/znas/Docker/web/pages/netgrimoire/public_html/briefing.html...
============================================================
✓ SUCCESS!
  TODAY: 3 events, 2 tasks, 1 flagged, 0 VIP
  THIS WEEK: 5 days, 1 tasks
  LATER: 2 days, 0 backlog
============================================================

4. Cron Job Setup

Daily Execution (6:00 AM):

crontab -e

Add:

0 6 * * * /usr/bin/python3 /home/gremlin/scripts/gremlin-briefing-final.py >> /home/gremlin/logs/briefing.log 2>&1

Manual Trigger:

# Run now
/home/gremlin/scripts/gremlin-briefing-final.py

# Clear email cache (force re-process all emails)
rm /home/gremlin/.gremlin-email-cache.json

5. Glance Integration

Update Glance Configuration:

nano /data/nfs/znas/Docker/glance/glance.yml

Add iframe widget:

- type: iframe
  title: "☠️ Gremlin's Morning Briefing"
  source: "https://www.netgrimoire.com/briefing.html"
  height: 1200

Restart Glance:

docker service update --force glance_glance

Access:

  • Direct: https://www.netgrimoire.com/briefing.html
  • Via Glance: https://home.netgrimoire.com

Configuration Guide

Adding Email Keywords

Email keywords flag specific topics for your attention. Emails matching these keywords appear in the 🚨 Flagged Emails section of TODAY.

Edit Script:

nano /home/gremlin/scripts/gremlin-briefing-final.py

Modify Line 45:

EMAIL_FLAG_KEYWORDS = ['mxroute', 'travel', 'dts', 'cititravel', '.mil', 'cindy']

Add keywords (lowercase, no spaces):

EMAIL_FLAG_KEYWORDS = [
    'mxroute',      # Hosting provider mentions
    'travel',       # Travel-related emails
    'dts',          # Defense Travel System
    'cititravel',   # Travel booking system
    '.mil',         # Military emails
    'cindy',        # From/mentions Cindy
    'vikunja',      # Task management mentions
    'backup',       # Backup-related alerts
    'downtime',     # Service outage mentions
]

Keywords are case-insensitive and match anywhere in subject or first 500 chars of body.


Adding VIP Senders

VIP senders always appear in TODAY's 💕 VIP section, regardless of content.

Edit Line 46:

EMAIL_VIP_SENDERS = ['cindy']

Add multiple VIPs:

EMAIL_VIP_SENDERS = [
    'cindy',           # Wife
    'boss@company',    # Boss's email
    'urgent@',         # Any address containing "urgent"
]

Matching is case-insensitive substring match on the From: field.


Adjusting Email Search Window

Default: 14 days (last 2 weeks)

Edit Line 44:

EMAIL_SEARCH_DAYS = 14

Change to 7 days:

EMAIL_SEARCH_DAYS = 7

Warning: Larger windows = more emails to process. Pre-screening mitigates this, but 30+ days may be slow.


Customizing Ollama Model

Default: llama3.2:3b (fast, good quality for email parsing)

Edit Line 49:

OLLAMA_MODEL = 'llama3.2:3b'

Alternative models:

OLLAMA_MODEL = 'qwen2.5-coder:7b'  # Better date extraction, slower
OLLAMA_MODEL = 'llama3.1:8b'       # More accurate, much slower

Test model availability:

curl http://docker4:11434/api/tags

Email Cache Management

The script tracks processed emails in /home/gremlin/.gremlin-email-cache.json to avoid re-processing.

View cache:

cat /home/gremlin/.gremlin-email-cache.json

Clear cache (force re-process all emails):

rm /home/gremlin/.gremlin-email-cache.json

Cache grows indefinitely. Periodically clear to prevent bloat:

# Monthly cache reset (add to crontab)
0 0 1 * * rm /home/gremlin/.gremlin-email-cache.json

Work Email Export Process

Daily Workflow:

  1. Export from Outlook:

    • Select "Daily Executive Briefing" email
    • Save as .md file
  2. Upload to Nextcloud:

    • Navigate to /Briefings/
    • Upload/replace work-briefing.md
  3. Script automatically fetches on next run

Expected MD Format:

## Daily Executive Briefing: April 18 - April 24, 2026

### Next Week's Schedule

| Date | Time | Subject | Location |
|:---|:---|:---|:---|
| Mon, Apr 20 | 08:30 - 09:30 | Meeting Name | Conference Room |

### Prioritized Action Items

| Priority | From | Subject | Action / Deadline |
|:---|:---|:---|:---|
| **High** | Boss Name | Task Subject | Action required: Details here |
| Normal | Colleague | Task Subject | Action required: Details here |

Script parses:

  • Schedule table → merges into calendar view
  • Action items table → displays in 📧 Work Taskings
  • Filters out "Canceled:" meetings

Troubleshooting

Script Fails: Google Calendar Auth Error

Error:

Error fetching Google Calendar: invalid_grant

Fix:

  1. Verify service account JSON file exists:
    ls -l /home/gremlin/.config/gcloud/netgrimoire-calendar-sa.json
    
  2. Check calendar sharing in Google Calendar settings
  3. Regenerate service account key if needed

Script Fails: Nextcloud Connection Error

Error:

Error fetching work briefing: HTTP 401

Fix:

  1. Verify Nextcloud app password
  2. Test WebDAV manually:
    curl -u graymutt:YOUR_PASSWORD \
      https://cloud.netgrimoire.com/remote.php/dav/files/graymutt/Briefings/work-briefing.md
    
  3. Regenerate app password if needed

Script Fails: MailCow IMAP Error

Error:

Error fetching emails: Login failed

Fix:

  1. Verify MailCow credentials
  2. Test IMAP manually:
    telnet 192.168.5.16 143
    # Type: a001 LOGIN phil@pncharris.com YOUR_PASSWORD
    
  3. Check MailCow IMAP is enabled for user

Ollama Parsing Returns Null

Symptom: Emails found, but Successfully parsed 0 emails

Causes:

  1. Ollama not running:
    curl http://docker4:11434/api/tags
    
  2. Model not pulled:
    docker exec -it ollama ollama pull llama3.2:3b
    
  3. Timeout issues (increase Line 368):
    timeout=30  # Increase to 60 for slower models
    

Email Pre-screening Too Aggressive

Symptom: Important emails not appearing in briefing

Fix: Check pre-screening patterns in should_process_email() (Lines 297-334)

Add more date patterns:

date_patterns = [
    r'\b\d{1,2}[/-]\d{1,2}[/-]\d{2,4}\b',
    r'\b\d{4}-\d{2}-\d{2}\b',
    # Add custom patterns
    r'next week',
    r'by end of',
]

Add more action keywords:

action_keywords = [
    'due', 'deadline', 'task', 'todo',
    # Add custom keywords
    'please review',
    'need your input',
    'waiting on',
]

HTML Not Rendering in Glance

Symptom: Blank iframe or "403 Forbidden"

Fix:

  1. Verify Apache serving file:
    curl https://www.netgrimoire.com/briefing.html
    
  2. Check file permissions:
    ls -l /data/nfs/znas/Docker/web/pages/netgrimoire/public_html/briefing.html
    # Should be: -rw-r--r-- 1 1964 1964
    
  3. Verify Apache VirtualHost config:
    cat /data/nfs/znas/Docker/web/apache/netgrimoire.conf
    

Future Enhancements

Planned Integrations

NetGrimoire Stack Status:

def fetch_netgrimoire_status():
    """Fetch Uptime Kuma API for service health"""
    # Query Uptime Kuma heartbeat API
    # Return: {services_up: N, services_down: N, warnings: [...]}

Vikunja Tasks:

def fetch_vikunja_tasks():
    """Fetch tasks from Vikunja API"""
    # Query Vikunja API for open tasks
    # Merge into TODAY/THIS WEEK/LATER zones

Additional Google Calendars:

  • PNC Fish and More
  • Personal calendar
  • Shared family calendar

Gremlin Mood States:

  • Time-based commentary variation
  • Workload-based sass level
  • Stack health integration

File Locations

Script Files

/home/gremlin/
├── scripts/
│   └── gremlin-briefing-final.py
├── logs/
│   └── briefing.log
└── .config/
    └── gcloud/
        └── netgrimoire-calendar-sa.json

Data Files

/home/gremlin/
└── .gremlin-email-cache.json

/data/nfs/znas/Docker/web/pages/netgrimoire/public_html/
└── briefing.html

Nextcloud Files

/Briefings/
└── work-briefing.md


Maintenance

Weekly Tasks

  • Review flagged keywords effectiveness
  • Check email cache size
  • Verify Nextcloud work briefing uploads

Monthly Tasks

  • Clear email cache
  • Review Ollama parsing accuracy
  • Update work email export process if needed

Quarterly Tasks

  • Review Google Calendar sharing permissions
  • Rotate Nextcloud app password
  • Update federal holidays API if needed

Support

Logs:

# Script execution log
tail -f /home/gremlin/logs/briefing.log

# Glance container logs
docker service logs glance_glance --tail 50

Manual debugging:

# Run script with verbose output
python3 -u /home/gremlin/scripts/gremlin-briefing-final.py

# Test individual components
python3 -c "from google.oauth2 import service_account; print('Google auth OK')"

Last updated: April 18, 2026 Maintained by: Phil Harris (graymutt)