]>
Commit | Line | Data |
---|---|---|
1bf7c9b9 RBR |
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 | } |