diff --git a/_reve.sh b/_reve.sh index d7df8e2..06afd8d 100644 --- a/_reve.sh +++ b/_reve.sh @@ -7,16 +7,13 @@ reve_installation="$HOME/.local/bin/reve" reve_config="$HOME/.config/reve" -util_readf() { - local filename=$1 - - if [[ -f "$filename" ]]; then - cat "$filename" - else - error E "util_readf" "File not found: $filename" - return 1 - fi -} +_current_dir=$(realpath "$(dirname "$0")") +# shellcheck source=_reve_states.sh +source "$_current_dir/_reve_states" >&/dev/null +(($? == 1)) && source "$_current_dir/_reve_states.sh" +# shellcheck source=_reve_utils.sh +source "$_current_dir/_reve_utils" >&/dev/null +(($? == 1)) && source "$_current_dir/_reve_utils.sh" util_where_config() { local config_key=$1 @@ -83,11 +80,3 @@ util_toggle_dm() { util_write_config base.desktop_mode dark fi } - -error() { - local level=$1 location=$2 cause=$3 - message="[reve] [$level] [$location] $cause" - echo "$message" - now=$(date -Iminutes) - echo "${now::-6} $message" >>"$reve_installation/reve.log" -} diff --git a/_reve_states.sh b/_reve_states.sh new file mode 100644 index 0000000..309825a --- /dev/null +++ b/_reve_states.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# reve desktop environment framework +# Yigid BALABAN 2024 + +# reve internal: _reve_states +# defines state management API + +_current_dir=$(realpath "$(dirname "$0")") +# shellcheck source=_reve_utils.sh +source "$_current_dir/_reve_utils" >&/dev/null +(($? == 1)) && source "$_current_dir/_reve_utils.sh" + +REVE_STATE_REPO="$HOME/.local/bin/reve/states" + +__util_pathto_state() { + # args: $1 -- state key + # args: $2 -- state type + local key=$1 type=$2 + + pre_removed_key=${key/#base./} + state_path="$(echo "$pre_removed_key" | sed 's/\./\//g')$type" + echo "$state_path" +} + +__util_find_state() { + # args: $1 -- state key + # returns: 1 if state key not in map + # 2 if map is corrupted + local key=$1 + + type=$(awk -F'=' -v key="$key" '$1 == key {print $2}' "$REVE_STATE_REPO/map") + case "$type" in + prs | persistent) type="" ;; + tmp | temporary) type=".tmp" ;; + "") + error E states "state referenced by key '$key' doesn't exist" + return 1 + ;; + *) + error E states "state map '$REVE_STATE_REPO/map' is corrupted" + return 2 + ;; + esac + + __util_pathto_state "$1" "$type" +} + +util_create_state() { + local type=$1 key=$2 value=$3 + + if [ "$type" != "tmp" ] && [ "$type" != "prs" ]; then + error E util_create_state "can't create state with type '$type'" + return + fi + + if ! __util_find_state "$key"; then + echo "$value" >"$(__util_pathto_state "$key" "$type")" + echo "$key=$value" >"$REVE_STATE_REPO/map" + fi +} + +util_write_state() { + local key=$1 value=$2 + + _path=$(__util_find_state "$key") + if $? -eq 0; then + echo "$value" >"$_path" + fi +} + +util_read_state() { + local key=$1 + + _path=$(__util_find_state "$key") + if $? -eq 0; then + cat "$_path" + fi +} + +util_delete_state() { + local key=$1 + + _path=$(__util_find_state "$key") + if $? -eq 0; then + rm "$_path" + awk -F '=' -v key="$key" '$1 != key' "$REVE_STATE_REPO/map" >"$REVE_STATE_REPO/map.tmp" + mv "$REVE_STATE_REPO/map.tmp" "$REVE_STATE_REPO/map" + + _dir=$(dirname "$_path") + [ -z "$(ls -A "$_dir")" ] && rm -r "$_dir" + fi +} + +util_deleteall_temp() { + awk -F'=' '$2 == "tmp" { print $1 }' data.txt | while read -r key; do + util_delete_state "$key" + done +} diff --git a/_reve_utils.sh b/_reve_utils.sh new file mode 100644 index 0000000..d02af1a --- /dev/null +++ b/_reve_utils.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# reve desktop environment framework +# Yigid BALABAN 2024 + +# reve internal: _reve_utils +# defines utility functions + +# VERY CRITICAL: change this if install.sh is updated +reve_installation="$HOME/.local/bin/reve" + +util_readf() { + local filename=$1 + + if [[ -f "$filename" ]]; then + cat "$filename" + else + error E "util_readf" "File not found: $filename" + return 1 + fi +} + +error() { + local level=$1 location=$2 cause=$3 + message="[reve] [$level] [$location] $cause" + echo "$message" + now=$(date -Iminutes) + echo "${now::-6} $message" >>"$reve_installation/reve.log" +} diff --git a/chores/misc/asus_kbd_light.sh b/chores/misc/asus_kbd_light.sh new file mode 100755 index 0000000..70e9cc2 --- /dev/null +++ b/chores/misc/asus_kbd_light.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# reve desktop environment framework +# Yigid BALABAN 2024 + +# chore script +# type misc +# name asus_kbd_light.sh +# desc ... +# vars ... +# reload ... + +reve_folder="$HOME/.config/reve" +reve_desktop_mode="$reve_folder/desktop_mode" + +source "$( reve -w )/_reve" + +current_mode=$( util_readf "$reve_desktop_mode" ) + +if [ "$current_mode" == "light" ]; then + exit 0 +fi + +hex_dominant_color=$( magick "$reve_folder/chore/bg_dark" -resize 1x1\! -format "%[hex:p{0,0}]" info: ) + +asusctl led-mode static -c "$hex_dominant_color" +asusctl --kbd-bright med diff --git a/chores/mode/display_brightness.sh b/chores/mode/display_brightness.sh new file mode 100755 index 0000000..12e5f01 --- /dev/null +++ b/chores/mode/display_brightness.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# reve desktop environment framework +# Yigid BALABAN 2024 + +# chore script +# type mode +# name display_brightness.sh +# desc sets display brightness depending on the desktop_mode +# vars day_level, night_level +# reload none + +# shellcheck source=../../_reve.sh +source "$(reve where)/_reve" + +if [ "$RV_CURRENT_MODE" == "dark" ]; then + brightnessctl set "$(util_read_config display.night_level)" +else + brightnessctl set "$(util_read_config display.day_level)" +fi diff --git a/chores/mode/swww_slideshow.sh b/chores/mode/swww_slideshow.sh new file mode 100755 index 0000000..04ea6cf --- /dev/null +++ b/chores/mode/swww_slideshow.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# reve desktop environment framework +# Yigid BALABAN 2024 + +# chore script +# type mode +# name swww-based wallpaper slideshow +# desc reruns utility/swww_slideshow when mode changes +# vars swwwss.dark, swwwss.light, swwwss.folder +# reload no + +# shellcheck source=../../_reve.sh +source "$(reve where)/_reve" + +desktop_mode=$(util_read_config base.desktop_mode) + +if [ "$desktop_mode" == "dark" ]; then + util_write_config swwwss.folder "$(util_read_config swwwss.dark)" +else + util_write_config swwwss.folder "$(util_read_config swwwss.light)" +fi diff --git a/chores/power/laptop_disp_rr.sh b/chores/power/laptop_disp_rr.sh new file mode 100755 index 0000000..e69de29 diff --git a/docs/about_states.md b/docs/about_states.md new file mode 100644 index 0000000..2d438fd --- /dev/null +++ b/docs/about_states.md @@ -0,0 +1,26 @@ +# reve docs + +"about states", revision 1 +yigid balaban \ + +## about states + +different from configuration files, some information is temporary, and "local" to current runtime. some utilities, for example, may need a way to store and access variables. for that reason reve exposes 4 functions to work with states that can be temporary or permanent. + +for this reason, states can be created/updated, deleted or read using reve. + +### reve's API for states + +Functions for working with states are defined in `_reve.sh`: + +1. `util_create_state {type} {key} [value]`: Creates the state file. `{type}` can be `tmp` for temporary or `prs` for persistent. +1. `util_read_state {key}`: Returns the value read from file addressed by key. Will return `1` if an error occurs. +2. `util_write_state {key} {value}`: Writes the value to file addressed by key. Will **overwrite** without warning. +3. `util_delete_state {key}`: Deletes the file addressed by key. Will delete the containing folder, if the folder is empty. + +### underlying implementation + +- the `key`s are dot-delimited folders, subfolders and files. The last element of the key is assumed to be the file name. +- trying to read, write or delete a file that is not created will return an error. +- as a result of the rule above, writing a new state is not possible, you have to create it with an explicit type first. +- temporary states will be cleaned when the appropriate call is made (`reve state clean`) diff --git a/install.sh b/install.sh index 2ad076b..5547b08 100644 --- a/install.sh +++ b/install.sh @@ -4,48 +4,52 @@ # Yigid BALABAN 2024 rt_script_dir=$(realpath "$(dirname "$0")") -cd "$rt_script_dir" || exit +cd "$rt_script_dir" || exit reve_installation_target="$HOME/.local/bin/reve" echo "[1/5] Creating reve installation folder" mkdir -p "$reve_installation_target" -echo "[2/5] Copying: reve.sh and _reve.sh" +echo "[2/5] Copying: reve.sh and other internal tools" cp reve.sh "$reve_installation_target/reve" cp _reve.sh "$reve_installation_target/_reve" +cp _reve_utils.sh "$reve_installation_target/_reve_utils" +cp _reve_states.sh "$reve_installation_target/_reve_states" chmod +x "$reve_installation_target/reve" chmod -x "$reve_installation_target/_reve" +chmod -x "$reve_installation_target/_reve_utils" +chmod -x "$reve_installation_target/_reve_states" echo "[3/5] Adding reve to path" if grep -q "/bin/bash" /etc/shells; then - echo "==> bash detected." - if ! grep -q "$reve_installation_target" ~/.bashrc; then - echo "export PATH=\"\$PATH:$reve_installation_target\"" >> ~/.bashrc - echo "Added $reve_installation_target to bash PATH." - else - echo "$reve_installation_target is already in bash PATH." - fi + echo "==> bash detected." + if ! grep -q "$reve_installation_target" ~/.bashrc; then + echo "export PATH=\"\$PATH:$reve_installation_target\"" >>~/.bashrc + echo "Added $reve_installation_target to bash PATH." + else + echo "$reve_installation_target is already in bash PATH." + fi fi if grep -q "/bin/zsh" /etc/shells; then - echo "==> zsh detected." - if ! grep -q "$reve_installation_target" ~/.zshrc; then - echo "export PATH=\"\$PATH:$reve_installation_target\"" >> ~/.zshrc - echo "Added $reve_installation_target to zsh PATH." - else - echo "$reve_installation_target is already in zsh PATH." - fi + echo "==> zsh detected." + if ! grep -q "$reve_installation_target" ~/.zshrc; then + echo "export PATH=\"\$PATH:$reve_installation_target\"" >>~/.zshrc + echo "Added $reve_installation_target to zsh PATH." + else + echo "$reve_installation_target is already in zsh PATH." + fi fi if grep -q "/bin/fish" /etc/shells; then - echo "==> fish detected." - if ! fish -c "echo $PATH | grep -q $reve_installation_target"; then - fish -c "fish_add_path $reve_installation_target" - echo "Added $reve_installation_target to fish PATH." - else - echo "$reve_installation_target is already in fish PATH." - fi + echo "==> fish detected." + if ! fish -c "echo $PATH | grep -q $reve_installation_target"; then + fish -c "fish_add_path $reve_installation_target" + echo "Added $reve_installation_target to fish PATH." + else + echo "$reve_installation_target is already in fish PATH." + fi fi echo "[4/5] Creating chores/mode folder" diff --git a/reve.sh b/reve.sh index 9f8c76a..862149e 100755 --- a/reve.sh +++ b/reve.sh @@ -284,6 +284,11 @@ shell-completion) f_shell_completion exit 0 ;; +state) + if [ "$2" == "clean" ]; then + util_deleteall_temp + fi + ;; mode) in_desktop_mode="$2" ;;