]> git.r.bdr.sh - rbdr/r.bdr.sh/blob - swiftbar/focus.utils.sh
Update scripts to use focus checks
[rbdr/r.bdr.sh] / swiftbar / focus.utils.sh
1 ASSERT_PATH="$HOME/Library/DoNotDisturb/DB/Assertions.json"
2 MODECONFIG_PATH="$HOME/Library/DoNotDisturb/DB/ModeConfigurations.json"
3
4 ###############################################################################
5 #
6 # USAGE:
7 #
8 # You can ask a script to only continue if it matches a focus mode, or to halt
9 # if it encounters it. You can do this by passing pipe separated values to
10 # VAR_RUN_ON_FOCUS or VAR_HALT_ON_FOCUS and then calling focus_check.
11 # For example, this will only run the script if "Personal" or "Do Not Disturb"
12 # are active:
13 #
14 # VAR_RUN_ON_FOCUS="Personal|Do Not Disturb"
15 # focus_check
16 #
17 # And this will halt the script only if the focus is Work
18 #
19 # VAR_HALT_ON_FOCUS="Work"
20 # focus_check
21 #
22 # If neither variable is set, then all checks will be disabled.
23 #
24 # SETUP:
25 #
26 # Copy focus.utils.sh to your SwiftBar directory and include it if it exists.
27 #
28 # if [[ -f "${BASH_SOURCE%/*}/focus.utils.sh" ]]; then
29 # source "${BASH_SOURCE%/*}/focus.utils.sh"
30 # focus_check
31 # fi
32 #
33 # PERMISSIONS:
34 #
35 # Accessing these databases requires that SwiftBar has full disk access
36 # permissions. If the checks are enabled but the database files can't be read
37 # it will instead return an error with instructions on what to do.
38 #
39 # ADDITIONAL FUNCTIONS:
40 #
41 # If you need custom behavior you can use the get_focus and is_focus_active
42 #
43 # get_focus will return the name of the currently active focus, or an empty
44 # string if there's no focus enabled.
45 #
46 # is_focus_active receives a pipe delimited string and will return 0 if the
47 # current focus is in the list, or 1 if the current focus is not present.
48 #
49 ###############################################################################
50 # Internal Utilities
51 ###############################################################################
52
53 _assert_permissions() {
54
55 if [[ ! -r "$ASSERT_PATH" ]] || [[ ! -r "$MODECONFIG_PATH" ]]; then
56 echo ":light.beacon.max:"
57 echo "---"
58 echo "Focus database not readable.\nAllow SwiftBar in System Settings > Privacy & Security > Full Disk Access."
59 exit 0
60 fi
61 }
62
63 _run_on_focus() {
64 [[ -z "${VAR_RUN_ON_FOCUS}" ]] && return 0
65 _assert_permissions
66 is_focus_active $VAR_RUN_ON_FOCUS || exit 0
67 return 0
68 }
69
70 _halt_on_focus() {
71 [[ -z "${VAR_HALT_ON_FOCUS}" ]] && return 0
72 _assert_permissions
73 is_focus_active $VAR_HALT_ON_FOCUS || return 0
74 exit 0
75 }
76
77 ###############################################################################
78 # Public Functions
79 ###############################################################################
80
81 get_focus() {
82 local focus=""
83
84 # Check for active assertions
85 if [[ -f "$ASSERT_PATH" ]]; then
86 local modeid=$(jq -r '.data[0].storeAssertionRecords[0].assertionDetails.assertionDetailsModeIdentifier // empty' "$ASSERT_PATH")
87
88 if [[ -n "$modeid" ]]; then
89 focus=$(jq -r --arg mid "$modeid" '.data[0].modeConfigurations[$mid].mode.name' "$MODECONFIG_PATH")
90 echo "$focus"
91 return
92 fi
93 fi
94
95 # Calculate current time in minutes
96 local hour=$(date +%H)
97 local minute=$(date +%M)
98 local now=$((hour * 60 + minute))
99
100 # Process scheduled triggers
101 jq -r '.data[0].modeConfigurations | to_entries[] | select(.value.triggers.triggers[0] != null) |
102 select(.value.triggers.triggers[0].enabledSetting == 2) |
103 {
104 id: .key,
105 name: .value.mode.name,
106 start: (.value.triggers.triggers[0].timePeriodStartTimeHour * 60 + .value.triggers.triggers[0].timePeriodStartTimeMinute),
107 end: (.value.triggers.triggers[0].timePeriodEndTimeHour * 60 + .value.triggers.triggers[0].timePeriodEndTimeMinute)
108 } | @json' "$MODECONFIG_PATH" 2>/dev/null | while read -r line; do
109 local start=$(echo "$line" | jq -r '.start')
110 local end=$(echo "$line" | jq -r '.end')
111 local name=$(echo "$line" | jq -r '.name')
112
113 if [[ $start -lt $end ]]; then
114 if [[ $now -ge $start && $now -lt $end ]]; then
115 focus="$name"
116 break
117 fi
118 elif [[ $start -gt $end ]]; then
119 if [[ $now -ge $start || $now -lt $end ]]; then
120 focus="$name"
121 break
122 fi
123 fi
124 done
125
126 echo -n "$focus" | xargs
127 }
128
129 is_focus_active() {
130 local current_focus=$(get_focus)
131 [[ "$current_focus" =~ ^($1)$ ]] && return 0
132 return 1
133 }
134
135 focus_check() {
136 _run_on_focus
137 _halt_on_focus
138 }