users/ryan/modules/simple-bar/simple-bar-source/lib/scripts/next-meeting.sh

63e15655ee66d63088bc907072616b988fee4351 · 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 ""