X-Git-Url: https://iankelling.org/git/?a=blobdiff_plain;f=myi3status;h=bd0c634d1c1228b97ad1605fc62610fb6c97712f;hb=HEAD;hp=65285329a36f51fc717f484e248e7a6a40c2d599;hpb=fa5deaee2e0182ddfc7b39eea7ee2acedb259ddf;p=distro-setup diff --git a/myi3status b/myi3status old mode 100644 new mode 100755 index 6528532..bd0c634 --- a/myi3status +++ b/myi3status @@ -1,105 +1,333 @@ #!/bin/bash -# Copyright (C) 2019 Ian Kelling -# SPDX-License-Identifier: AGPL-3.0-or-later +# I, Ian Kelling, follow the GNU license recommendations at +# https://www.gnu.org/licenses/license-recommendations.en.html. They +# recommend that small programs, < 300 lines, be licensed under the +# Apache License 2.0. This file contains or is part of one or more small +# programs. If a small program grows beyond 300 lines, I plan to switch +# its license to GPL. +# Copyright 2024 Ian Kelling + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# usage: +# +# * left click seconds to reset & enable main timer which shows 30 +# minutes in blue and half hours in orange. +# +# * right click seconds to disable minutes & half hours of main timer +# +# * left click minutes to reset & enable 2nd timer. +# +# * right click minutes to disable 2nd timer + +# docs: +# +# Sections from right to left. +# +# section #1, labeled day_percent +# +# 1. Thousandths of a 16 hour day left. 1 = 57.6 seconds. +# 2. Bar of one thousand of a day which gets shorter by ninths. One ninth is 6.4 seconds. +# 3. Start of the day (only the non-zero numbers). Set this with the ds command. +# 4. The time right now. +# 5. Ten thousands of the year left. 1 = 52:34 minutes (leap year = 52:42) +# 6. Bar of 1/10,000 of a year shrinking by ninths. 1 ninth = 5:50 minutes (leap year = 5:51 mins). +# +# section #2, labeled seconds +# +# block characters, ▉, are added every 3 seconds, a total of 20 for 1 +# minute. The groups of 5 blocks = 15 seconds each. +# +# section #3, labeled mins +# +# Only enabled by clicking on seconds, see usage. +# +# Block characters are added every minute until 30, then reset. There +# are 6 groups of 5 minutes. +# +# Section #4 +# +# Half hours in orange, grouped into groups of 2. This will grow until +# it fills the screen. +# +# Section #5 & 6 +# +# Only enabled by clicking on mins section, see usage. +# +# These repeat sections 3 and 4 in violet and some other color. +# +# if [ -z "$BASH_VERSION" ]; then echo "error: shell is not bash" >&2; exit 1; fi -source /a/bin/errhandle/err +source /a/bin/bash-bear-trap/bash-bear shopt -s nullglob shopt -s dotglob -shopt -s nullglob -for p in ~/.gem/ruby/*/bin; do - PATH="$PATH:$p" -done - -todaycache=/tmp/timetraptoday -newer() { - if [[ ! -e $todaycache ]]; then - return 1 +tmp_focus1=$(mktemp) +tmp_focus2=$(mktemp) + +mins=0 +half_hours=0 +start=$EPOCHSECONDS +domins=false + +if date -d 'february 29' &>/dev/null; then + days_in_this_year=366 +else + days_in_this_year=365 +fi + + +get_daystart() { + if [[ /b/data/daystart -ot /b/data/daystart-generated && $day_start_24h ]]; then + return 0 + fi + day_start_24h=$(cat /b/data/daystart) + day_start_sig_digits=${day_start_24h%?} + day_start_sig_digits=${day_start_sig_digits%0} + day_start_hour=${day_start_24h%??} + day_start_min=${day_start_24h: -2} + echo $day_start_hour > /b/data/daystart-generated + echo $day_start_min >> /b/data/daystart-generated + day_start=$(date -d $day_start_hour:$day_start_min +%s) + # for after midnight but before the day start. + if (( day_start > EPOCHSECONDS )); then + day_start=$(date -d "$day_start_hour:$day_start_min yesterday" +%s) fi - ! find $todaycache -mmin $1 -type f -exec false {} + &>/dev/null } -td() { /a/opt/timetrap/bin/t d -ftotal all -m '^w|x$' "$@"; } + main() { + get_daystart + + ## debug + # if [[ $line ]]; then + # echo "line=$line" >>/tmp/t + # fi + case $line in + ""|"[") : ;; + *) + json="${line#,}" + case $(echo "$json" | jq -r .name) in + seconds) + case $(echo "$json" | jq -r .button) in + # left click + 1) + start=$EPOCHSECONDS + domins=true + ;; + # right click + 3) + domins=false + ;; + esac + ;; + mins) + case $(echo "$json" | jq -r .button) in + 1) + start2=$EPOCHSECONDS + ;; + 3) + start2= + ;; + esac + + ;; + esac + esac + + time=$((EPOCHSECONDS - start)) + total_mins=$(( time / 60 )) + mins=$(( total_mins % 30 )) + half_hours=$(( total_mins / 30 )) + + + + printf '[' - ps_char= - if [[ -e /dev/shm/iank-status ]]; then - eval $(< /dev/shm/iank-status) + if [[ -e /dev/shm/iank-status && ! -e /tmp/quiet-status ]]; then + ps_char= + eval "$(< /dev/shm/iank-status)" fi - # clocked in or out? - cursheet=$(sqlite3 /p/.timetrap.db "select sheet from entries where end is NULL;") + touch --date="10 minutes ago" $tmp_focus1 + touch --date="30 minutes ago" $tmp_focus2 + f=/tmp/focus-last-input - if [[ $cursheet ]]; then - if i3-msg -t get_bar_config bar-0 | grep '"mode":"dock"' &>/dev/null; then - i3-msg -q 'bar mode hide' - fi - else - if i3-msg -t get_bar_config bar-0 | grep '"mode":"hide"' &>/dev/null; then - i3-msg -q 'bar mode dock' - fi - cursheet=out + # We output a reminder to do input to the focus app if we haven't done + # it less 10 minutes ago (but dont bother if its been more than 30 + # minutes, maybe we aren't running it anymore.) + if [[ -e $f && $tmp_focus2 -ot $f && $tmp_focus1 -nt $f ]]; then + ps_char="=======FOCUS====== $ps_char" fi - # maybe sometime show work and x separate - if newer 3; then - today=$(< /tmp/timetraptoday) - elif newer 10; then - today=$(< /tmp/timetraptoday) - td -s today >/tmp/timetraptoday & - else - today=$(td -s today) - echo "$today" >/tmp/timetraptoday + if [[ -e /tmp/iank-i3-no-auto ]]; then + ps_char="$ps_char I" + fi + if [[ -e /tmp/no-obs-auto-scene-switch ]]; then + ps_char="$ps_char O" fi - # hours remaining in the day: - - # work+study in the last week, not counting today. - # no arg to printf for the intentional behavior of no arg - # shellcheck disable=SC2183 - cache=/tmp/timetrap$(printf '%(%F)T') - if [[ -e $cache ]]; then - eval $(<$cache) - else - week=$(td -s '8 days ago' -e 'yesterday') - printf 'week="%s"\n' "$week" >$cache - week4=$(td -s '29 days ago' -e 'yesterday') - printf 'week4="%s"\n' "$week4" >>$cache + + printf '{ "name":"status", "color":"#ED297D", "full_text": "%s' "$ps_char" + printf '"},' + + + if [[ $start2 ]]; then + time2=$((EPOCHSECONDS - start2)) + total_mins2=$(( time2 / 60 )) + mins2=$(( total_mins2 % 30 )) + half_hours2=$(( total_mins2 / 30 )) + # this is duplicate of mins and half hours except for different + # colors and looking at vars above. + + # begin half hours + printf '{ "color": "#EFC93E", "full_text": "' + for ((i=half_hours2-1; i >= 0 ; i--)); do + printf ▉ + if (( i > 0 && i % 2 == 0 )); then + printf " " + fi + done + printf '"},' + + + # begin minutes + printf '{ "name":"mins2", "color":"#ED297D", "full_text": "' + for ((i=29; i >= 0 ; i--)); do + if (( i < mins2 )); then + printf ▉ + else + printf " " + fi + if (( i > 0 && i % 5 == 0 )); then + printf " " + fi + done + printf '"},' + fi - # weekly work+study in the last 4 weeks, not counting today. - # todo later: - # 4 weeks - # ($x4week + $w4week + .05) /4 - #weekly work+study in the last 16 weeks, not counting today. - #weekly work+study in the last 52 weeks, not counting today. - - unixtime=$EPOCHSECONDS - midnight=$(date +%s -d 'tomorrow 00:00') - tmp=($(echo "scale=1; today_left=($midnight-$unixtime) / 60 / 60; -today_left; -done_today=($today + .05) /1; -/* hours I could do today by working 80% of the remainder time */ -today_left * .8 + done_today; -done_today; -($week + .05) /1; -($week4 + .05) /4"|bc)) - printf "[ { \"full_text\": \"" - if [[ $ps_char ]]; then - printf "%s| " "$ps_char" + + if $domins; then + # begin half hours + printf '{ "color": "#FFB542", "full_text": "' + for ((i=half_hours-1; i >= 0 ; i--)); do + printf ▉ + if (( i > 0 && i % 2 == 0 )); then + printf " " + fi + done + printf '"},' + + + # begin minutes + printf '{ "name":"mins", "color":"#0D6BDD", "full_text": "' + for ((i=29; i >= 0 ; i--)); do + if (( i < mins )); then + printf ▉ + else + printf " " + fi + if (( i > 0 && i % 5 == 0 )); then + printf " " + fi + done + printf '"},' + fi + + # begin seconds + printf '{ "name": "seconds", "full_text": "' + + for ((i=0; i < 20; i++)); do + # This first condition is to make the transition from full to empty + # be less jarring. We are filling a bucket of space with ticks of + # time, we would have to choose to show full or empty, but never + # both. Or we could have a half/tick to show full then empty real + # quick. I decided to try having it work like a snake, empty out the + # 1st quarter as we fill up the last quarter. + + if (( i > 0 && i % 5 == 0 )); then + printf " " + fi + i_end=$(( time % 60 / 3 + 1 )) + if (( i_end - i > 15 )); then + printf " " + elif (( i_end == 1 && i == 0 )); then + printf B + elif (( i < i_end )); then + printf ▉ + else + printf " " + fi + done + printf '"},' + + ## begin day percent, in thousandths, plus a spark block for ten_thousandth. + printf '{ "name": "day_percent", "full_text": "' + + + # after 24 hours, reset the day start + if (( day_start + 24 * 60 * 60 < EPOCHSECONDS )); then + day_start=$(date -d $day_start_hour:$day_start_min +%s) fi - printf "%s | left today %s %s | today %s | week %s | 4weeks %s | %s\" } ],\n" "$cursheet" "${tmp[@]}" "$(date "+%A, %B %d, %r")" + + # there are 9 spark levels, 1/9 = .111.... In order to keep it in bash math, we upscale + # the number and divide by 111, 3 digits is good enough accuracy. + spark_index="$(( (1000000 -(EPOCHSECONDS - day_start)*1000000 / (16*60*60) ) % 1000 / 111 ))" + spark=" ▁▂▃▄▅▆▇█" + # note: 960 minutes, so 10 minutes is about 1% + day_thousandth=$(( 1000 - (EPOCHSECONDS - day_start)*1000 / (16*60*60) )) + printf %s "$day_thousandth${spark:spark_index:1}$day_start_sig_digits $(date "+%l:%M")" + + # .1% of a waking year is ~5.75 hours, or 365 thousandths of a day. + # 1% of a waking year is 3.7 days + # A spark line of a thousandth of a waking year is 39 minutes. + year_start=$(date +%s -d 'january 1 6am') + year_days=$(( (EPOCHSECONDS - year_start) / (24*60*60) )) + year_start=$(( year_start + year_days * 8*60*60 )) + year_spark_index=$(( ( 1000000 - (EPOCHSECONDS - year_start)*1000000 / (days_in_this_year*16*60*60) ) % 1000 / 111 )) + year_tenthousandth=$(( 10000 - (EPOCHSECONDS - year_start)*10000 / (days_in_this_year*16*60*60) )) + printf %s " $year_tenthousandth${spark:year_spark_index:1}" + + + echo '"} +], +' } -# pass any arg and we just run once + +# pass any arg and we just run once. mainly for debugging if (( $# )); then main + + # debug + #echo date -d $day_start_hour:$day_start_min +%s + #echo day_start=$day_start now=$EPOCHSECONDS + else - printf '{ "version": 1 }\n[' + printf '{ "version": 1, "click_events": true }\n[' while true; do - main - sleep 5 + if [[ -e /tmp/noi3bar ]]; then + sleep 10 + else + main + line= + read -r -t 3 line ||: + fi done fi + +rm -f $tmp_focus1 $tmp_focus2