users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/next-meeting.sh
8d7aa6e03293de5432a33e6ed55f3f4b2a4f095c
· 3.4 KB · 101 lines
raw
| 1 | #!/bin/bash |
| 2 | # Get next meeting using icalBuddy (much faster than AppleScript, handles recurring events) |
| 3 | # Usage: next-meeting.sh [icalBuddyPath] [lookAheadHours] |
| 4 | |
| 5 | # Configuration |
| 6 | MAX_IN_PROGRESS_MINUTES=15 # Stop showing "now" after meeting is 15 min in progress |
| 7 | LOOKAHEAD="${2:-12}" # How many hours ahead to look for meetings (default: 12) |
| 8 | MAX_EVENTS=10 # Fetch multiple events to skip stale in-progress ones |
| 9 | |
| 10 | # Calculate end time (icalBuddy doesn't support now+Xh syntax) |
| 11 | END_TIME=$(date -v+${LOOKAHEAD}H "+%Y-%m-%d %H:%M") |
| 12 | |
| 13 | # Use custom path if provided, otherwise auto-detect |
| 14 | CUSTOM_PATH="$1" |
| 15 | if [ -n "$CUSTOM_PATH" ] && [ -x "$CUSTOM_PATH" ]; then |
| 16 | ICALBUDDY="$CUSTOM_PATH" |
| 17 | else |
| 18 | ICALBUDDY=$(which icalBuddy 2>/dev/null) |
| 19 | if [ -z "$ICALBUDDY" ]; then |
| 20 | if [ -x "/opt/homebrew/bin/icalBuddy" ]; then |
| 21 | ICALBUDDY="/opt/homebrew/bin/icalBuddy" |
| 22 | elif [ -x "/usr/local/bin/icalBuddy" ]; then |
| 23 | ICALBUDDY="/usr/local/bin/icalBuddy" |
| 24 | else |
| 25 | echo "" |
| 26 | exit 0 |
| 27 | fi |
| 28 | fi |
| 29 | fi |
| 30 | |
| 31 | now_epoch=$(date +%s) |
| 32 | |
| 33 | # Fetch multiple events - each event bullet starts with <<<E>>> |
| 34 | # Using a unique prefix that won't appear in notes content |
| 35 | output=$("$ICALBUDDY" -n -nc -nrd -ea -eed -li "$MAX_EVENTS" \ |
| 36 | -b "<<<E>>>" -ss "" \ |
| 37 | -df "%Y-%m-%d" -tf "%H:%M" \ |
| 38 | -iep "title,datetime,notes" \ |
| 39 | eventsFrom:"now" to:"$END_TIME" 2>/dev/null) |
| 40 | |
| 41 | if [ -z "$output" ]; then |
| 42 | echo "" |
| 43 | exit 0 |
| 44 | fi |
| 45 | |
| 46 | # Write events to temp file for processing |
| 47 | tmpfile=$(mktemp) |
| 48 | echo "$output" > "$tmpfile" |
| 49 | |
| 50 | # Extract individual events by splitting on <<<E>>> prefix |
| 51 | event_num=0 |
| 52 | while IFS= read -r line; do |
| 53 | if [[ "$line" == "<<<E>>>"* ]]; then |
| 54 | # Process previous event if we have one |
| 55 | if [ "$event_num" -gt 0 ] && [ -n "$cur_title" ] && [ -n "$cur_start_time" ] && [ -n "$cur_iso_date" ]; then |
| 56 | meeting_epoch=$(date -j -f "%Y-%m-%d %H:%M" "$cur_iso_date $cur_start_time" +%s 2>/dev/null) |
| 57 | if [ -n "$meeting_epoch" ]; then |
| 58 | minutes_until=$(( (meeting_epoch - now_epoch) / 60 )) |
| 59 | if [ "$minutes_until" -ge "-$MAX_IN_PROGRESS_MINUTES" ]; then |
| 60 | echo "${cur_title}|${cur_iso_date}T${cur_start_time}||${cur_notes}|${minutes_until}" |
| 61 | rm -f "$tmpfile" |
| 62 | exit 0 |
| 63 | fi |
| 64 | fi |
| 65 | fi |
| 66 | |
| 67 | # Start new event |
| 68 | event_num=$((event_num + 1)) |
| 69 | cur_title="${line#<<<E>>>}" |
| 70 | cur_title=$(echo "$cur_title" | sed 's/ (Calendar)$//') |
| 71 | cur_iso_date="" |
| 72 | cur_start_time="" |
| 73 | cur_notes="" |
| 74 | in_notes=0 |
| 75 | elif [[ "$line" =~ ^[[:space:]]+[0-9]{4}-[0-9]{2}-[0-9]{2}" at "[0-9]{2}:[0-9]{2} ]]; then |
| 76 | cur_iso_date=$(echo "$line" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}') |
| 77 | cur_start_time=$(echo "$line" | grep -oE 'at [0-9]{2}:[0-9]{2}' | head -1 | sed 's/at //') |
| 78 | in_notes=0 |
| 79 | elif [[ "$line" == *"notes:"* ]]; then |
| 80 | in_notes=1 |
| 81 | cur_notes="$line" |
| 82 | elif [ "$in_notes" -eq 1 ]; then |
| 83 | cur_notes="${cur_notes} $(echo "$line" | sed 's/|/¦/g')" |
| 84 | fi |
| 85 | done < "$tmpfile" |
| 86 | |
| 87 | # Process the last event |
| 88 | if [ "$event_num" -gt 0 ] && [ -n "$cur_title" ] && [ -n "$cur_start_time" ] && [ -n "$cur_iso_date" ]; then |
| 89 | meeting_epoch=$(date -j -f "%Y-%m-%d %H:%M" "$cur_iso_date $cur_start_time" +%s 2>/dev/null) |
| 90 | if [ -n "$meeting_epoch" ]; then |
| 91 | minutes_until=$(( (meeting_epoch - now_epoch) / 60 )) |
| 92 | if [ "$minutes_until" -ge "-$MAX_IN_PROGRESS_MINUTES" ]; then |
| 93 | echo "${cur_title}|${cur_iso_date}T${cur_start_time}||${cur_notes}|${minutes_until}" |
| 94 | rm -f "$tmpfile" |
| 95 | exit 0 |
| 96 | fi |
| 97 | fi |
| 98 | fi |
| 99 | |
| 100 | rm -f "$tmpfile" |
| 101 | echo "" |