host info updates
[distro-setup] / myi3status
1 #!/bin/bash
2 # I, Ian Kelling, follow the GNU license recommendations at
3 # https://www.gnu.org/licenses/license-recommendations.en.html. They
4 # recommend that small programs, < 300 lines, be licensed under the
5 # Apache License 2.0. This file contains or is part of one or more small
6 # programs. If a small program grows beyond 300 lines, I plan to switch
7 # its license to GPL.
8
9 # Copyright 2024 Ian Kelling
10
11 # Licensed under the Apache License, Version 2.0 (the "License");
12 # you may not use this file except in compliance with the License.
13 # You may obtain a copy of the License at
14
15 # http://www.apache.org/licenses/LICENSE-2.0
16
17 # Unless required by applicable law or agreed to in writing, software
18 # distributed under the License is distributed on an "AS IS" BASIS,
19 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 # See the License for the specific language governing permissions and
21 # limitations under the License.
22
23
24 # usage:
25 #
26 # * left click seconds to reset & enable main timer which shows 30
27 # minutes in blue and half hours in orange.
28 #
29 # * right click seconds to disable minutes & half hours of main timer
30 #
31 # * left click minutes to reset & enable 2nd timer.
32 #
33 # * right click minutes to disable 2nd timer
34
35 # docs:
36 #
37 # Sections from right to left.
38 #
39 # section #1, labeled day_percent
40 #
41 # 1. Thousandths of a 16 hour day left. 1 = 57.6 seconds.
42 # 2. Bar of one thousand of a day which gets shorter by ninths. One ninth is 6.4 seconds.
43 # 3. Start of the day (only the non-zero numbers). Set this with the ds command.
44 # 4. The time right now.
45 # 5. Ten thousands of the year left. 1 = 52:34 minutes (leap year = 52:42)
46 # 6. Bar of 1/10,000 of a year shrinking by ninths. 1 ninth = 5:50 minutes (leap year = 5:51 mins).
47 #
48 # section #2, labeled seconds
49 #
50 # block characters, ▉, are added every 3 seconds, a total of 20 for 1
51 # minute. The groups of 5 blocks = 15 seconds each.
52 #
53 # section #3, labeled mins
54 #
55 # Only enabled by clicking on seconds, see usage.
56 #
57 # Block characters are added every minute until 30, then reset. There
58 # are 6 groups of 5 minutes.
59 #
60 # Section #4
61 #
62 # Half hours in orange, grouped into groups of 2. This will grow until
63 # it fills the screen.
64 #
65 # Section #5 & 6
66 #
67 # Only enabled by clicking on mins section, see usage.
68 #
69 # These repeat sections 3 and 4 in violet and some other color.
70 #
71 #
72 if [ -z "$BASH_VERSION" ]; then echo "error: shell is not bash" >&2; exit 1; fi
73
74 source /a/bin/bash-bear-trap/bash-bear
75
76 shopt -s nullglob
77 shopt -s dotglob
78
79 tmp_focus1=$(mktemp)
80 tmp_focus2=$(mktemp)
81
82 mins=0
83 half_hours=0
84 start=$EPOCHSECONDS
85 domins=false
86
87 if date -d 'february 29' &>/dev/null; then
88 days_in_this_year=366
89 else
90 days_in_this_year=365
91 fi
92
93
94 get_daystart() {
95 if [[ /b/data/daystart -ot /b/data/daystart-generated && $day_start_24h ]]; then
96 return 0
97 fi
98 day_start_24h=$(cat /b/data/daystart)
99 day_start_sig_digits=${day_start_24h%?}
100 day_start_sig_digits=${day_start_sig_digits%0}
101 day_start_hour=${day_start_24h%??}
102 day_start_min=${day_start_24h: -2}
103 echo $day_start_hour > /b/data/daystart-generated
104 echo $day_start_min >> /b/data/daystart-generated
105 day_start=$(date -d $day_start_hour:$day_start_min +%s)
106 # for after midnight but before the day start.
107 if (( day_start > EPOCHSECONDS )); then
108 day_start=$(date -d "$day_start_hour:$day_start_min yesterday" +%s)
109 fi
110 }
111
112
113 main() {
114 get_daystart
115
116 ## debug
117 # if [[ $line ]]; then
118 # echo "line=$line" >>/tmp/t
119 # fi
120 case $line in
121 ""|"[") : ;;
122 *)
123 json="${line#,}"
124 case $(echo "$json" | jq -r .name) in
125 seconds)
126 case $(echo "$json" | jq -r .button) in
127 # left click
128 1)
129 start=$EPOCHSECONDS
130 domins=true
131 ;;
132 # right click
133 3)
134 domins=false
135 ;;
136 esac
137 ;;
138 mins)
139 case $(echo "$json" | jq -r .button) in
140 1)
141 start2=$EPOCHSECONDS
142 ;;
143 3)
144 start2=
145 ;;
146 esac
147
148 ;;
149 esac
150 esac
151
152 time=$((EPOCHSECONDS - start))
153 total_mins=$(( time / 60 ))
154 mins=$(( total_mins % 30 ))
155 half_hours=$(( total_mins / 30 ))
156
157
158
159 printf '['
160
161 if [[ -e /dev/shm/iank-status && ! -e /tmp/quiet-status ]]; then
162 ps_char=
163 eval "$(< /dev/shm/iank-status)"
164 fi
165
166 touch --date="10 minutes ago" $tmp_focus1
167 touch --date="30 minutes ago" $tmp_focus2
168 f=/tmp/focus-last-input
169
170 # We output a reminder to do input to the focus app if we haven't done
171 # it less 10 minutes ago (but dont bother if its been more than 30
172 # minutes, maybe we aren't running it anymore.)
173 if [[ -e $f && $tmp_focus2 -ot $f && $tmp_focus1 -nt $f ]]; then
174 ps_char="=======FOCUS====== $ps_char"
175 fi
176
177 if [[ -e /tmp/iank-i3-no-auto ]]; then
178 ps_char="$ps_char I"
179 fi
180 if [[ -e /tmp/no-obs-auto-scene-switch ]]; then
181 ps_char="$ps_char O"
182 fi
183
184
185 printf '{ "name":"status", "color":"#ED297D", "full_text": "%s' "$ps_char"
186 printf '"},'
187
188
189 if [[ $start2 ]]; then
190 time2=$((EPOCHSECONDS - start2))
191 total_mins2=$(( time2 / 60 ))
192 mins2=$(( total_mins2 % 30 ))
193 half_hours2=$(( total_mins2 / 30 ))
194 # this is duplicate of mins and half hours except for different
195 # colors and looking at vars above.
196
197 # begin half hours
198 printf '{ "color": "#EFC93E", "full_text": "'
199 for ((i=half_hours2-1; i >= 0 ; i--)); do
200 printf
201 if (( i > 0 && i % 2 == 0 )); then
202 printf " "
203 fi
204 done
205 printf '"},'
206
207
208 # begin minutes
209 printf '{ "name":"mins2", "color":"#ED297D", "full_text": "'
210 for ((i=29; i >= 0 ; i--)); do
211 if (( i < mins2 )); then
212 printf
213 else
214 printf " "
215 fi
216 if (( i > 0 && i % 5 == 0 )); then
217 printf " "
218 fi
219 done
220 printf '"},'
221
222 fi
223
224 if $domins; then
225 # begin half hours
226 printf '{ "color": "#FFB542", "full_text": "'
227 for ((i=half_hours-1; i >= 0 ; i--)); do
228 printf
229 if (( i > 0 && i % 2 == 0 )); then
230 printf " "
231 fi
232 done
233 printf '"},'
234
235
236 # begin minutes
237 printf '{ "name":"mins", "color":"#0D6BDD", "full_text": "'
238 for ((i=29; i >= 0 ; i--)); do
239 if (( i < mins )); then
240 printf
241 else
242 printf " "
243 fi
244 if (( i > 0 && i % 5 == 0 )); then
245 printf " "
246 fi
247 done
248 printf '"},'
249 fi
250
251 # begin seconds
252 printf '{ "name": "seconds", "full_text": "'
253
254 for ((i=0; i < 20; i++)); do
255 # This first condition is to make the transition from full to empty
256 # be less jarring. We are filling a bucket of space with ticks of
257 # time, we would have to choose to show full or empty, but never
258 # both. Or we could have a half/tick to show full then empty real
259 # quick. I decided to try having it work like a snake, empty out the
260 # 1st quarter as we fill up the last quarter.
261
262 if (( i > 0 && i % 5 == 0 )); then
263 printf " "
264 fi
265 i_end=$(( time % 60 / 3 + 1 ))
266 if (( i_end - i > 15 )); then
267 printf " "
268 elif (( i_end == 1 && i == 0 )); then
269 printf B
270 elif (( i < i_end )); then
271 printf
272 else
273 printf " "
274 fi
275 done
276 printf '"},'
277
278 ## begin day percent, in thousandths, plus a spark block for ten_thousandth.
279 printf '{ "name": "day_percent", "full_text": "'
280
281
282 # after 24 hours, reset the day start
283 if (( day_start + 24 * 60 * 60 < EPOCHSECONDS )); then
284 day_start=$(date -d $day_start_hour:$day_start_min +%s)
285 fi
286
287 # there are 9 spark levels, 1/9 = .111.... In order to keep it in bash math, we upscale
288 # the number and divide by 111, 3 digits is good enough accuracy.
289 spark_index="$(( (1000000 -(EPOCHSECONDS - day_start)*1000000 / (16*60*60) ) % 1000 / 111 ))"
290 spark=" ▁▂▃▄▅▆▇█"
291 # note: 960 minutes, so 10 minutes is about 1%
292 day_thousandth=$(( 1000 - (EPOCHSECONDS - day_start)*1000 / (16*60*60) ))
293 printf %s "$day_thousandth${spark:spark_index:1}$day_start_sig_digits $(date "+%l:%M")"
294
295 # .1% of a waking year is ~5.75 hours, or 365 thousandths of a day.
296 # 1% of a waking year is 3.7 days
297 # A spark line of a thousandth of a waking year is 39 minutes.
298 year_start=$(date +%s -d 'january 1 6am')
299 year_days=$(( (EPOCHSECONDS - year_start) / (24*60*60) ))
300 year_start=$(( year_start + year_days * 8*60*60 ))
301 year_spark_index=$(( ( 1000000 - (EPOCHSECONDS - year_start)*1000000 / (days_in_this_year*16*60*60) ) % 1000 / 111 ))
302 year_tenthousandth=$(( 10000 - (EPOCHSECONDS - year_start)*10000 / (days_in_this_year*16*60*60) ))
303 printf %s " $year_tenthousandth${spark:year_spark_index:1}"
304
305
306 echo '"}
307 ],
308 '
309 }
310
311
312 # pass any arg and we just run once. mainly for debugging
313 if (( $# )); then
314 main
315
316 # debug
317 #echo date -d $day_start_hour:$day_start_min +%s
318 #echo day_start=$day_start now=$EPOCHSECONDS
319
320 else
321 printf '{ "version": 1, "click_events": true }\n['
322 while true; do
323 if [[ -e /tmp/noi3bar ]]; then
324 sleep 10
325 else
326 main
327 line=
328 read -r -t 3 line ||:
329 fi
330 done
331 fi
332
333 rm -f $tmp_focus1 $tmp_focus2