]> danix's work - my-dotfiles.git/commitdiff
updated bin directory
authordanix <redacted>
Wed, 6 Nov 2024 11:43:55 +0000 (12:43 +0100)
committerdanix <redacted>
Wed, 6 Nov 2024 11:43:55 +0000 (12:43 +0100)
38 files changed:
bin/betterlockscreen [new file with mode: 0644]
bin/blackpearl-emoji.sh [new file with mode: 0644]
bin/blackpearl-notes.sh [new file with mode: 0644]
bin/blackpearl-powermenu.sh
bin/blackpearl-symbols.sh [new file with mode: 0644]
bin/blackpearl-utilsmenu.sh
bin/blackpearl-window.sh
bin/change_wallpaper.sh
bin/dunst-snooze.sh [new file with mode: 0644]
bin/dunst_vol_brig.sh [new file with mode: 0644]
bin/executors/battery-level [deleted file]
bin/feh-blur [new file with mode: 0644]
bin/gify.sh [new file with mode: 0644]
bin/hideIt.sh [new file with mode: 0644]
bin/hidebars.sh [new file with mode: 0644]
bin/i3lock-fancy
bin/i3suspend
bin/info-airqualityindex.sh [new file with mode: 0644]
bin/lightsOn.sh [new file with mode: 0644]
bin/maiumin [new file with mode: 0644]
bin/mkpass [new file with mode: 0644]
bin/mvb [new file with mode: 0644]
bin/my_netstat [new file with mode: 0644]
bin/nopy.sh [new file with mode: 0644]
bin/nospaces [new file with mode: 0644]
bin/notes [new file with mode: 0644]
bin/polybar-kdeconnect.sh [new file with mode: 0644]
bin/qwalwal.sh [new file with mode: 0644]
bin/run-polybar.sh
bin/send-to-device.sh [changed mode: 0755->0644]
bin/slack-updates
bin/speedtest [new file with mode: 0644]
bin/superenalotto.sh [new file with mode: 0644]
bin/symbols.sh [new file with mode: 0644]
bin/wal.sh [new file with mode: 0644]
bin/wallpaper.sh [new file with mode: 0644]
bin/walogram [new file with mode: 0644]
bin/walwal.sh [new file with mode: 0644]

diff --git a/bin/betterlockscreen b/bin/betterlockscreen
new file mode 100644 (file)
index 0000000..0b92ad9
--- /dev/null
@@ -0,0 +1,942 @@
+#!/usr/bin/env bash
+
+# Author : Copyright (c) 2017-2023 Pavan Jadhaw, and others (https://github.com/betterlockscreen/betterlockscreen/graphs/contributors)
+# Project Repository : https://github.com/betterlockscreen/betterlockscreen
+
+cmd_exists () {
+    command -v "$1" >/dev/null
+}
+
+init_config () {
+    # default options
+    display_on=0
+    span_image=false
+    lock_timeout=300
+    fx_list=(dim blur dimblur pixel dimpixel color)
+    dim_level=40
+    blur_level=1
+    pixel_scale=10,1000
+    solid_color=333333
+    description=""
+    quiet=false
+    i3lockcolor_bin="i3lock-color"
+    suspend_command="systemctl suspend"
+    convert_command="magick"
+    composite_command="magick composite"
+
+    if ! cmd_exists "$i3lockcolor_bin" && cmd_exists "i3lock"; then
+        i3lockcolor_bin="i3lock"
+    fi
+
+    if ! cmd_exists "magick"; then
+        convert_command="convert"
+        composite_command="composite"
+    fi
+
+    # default theme
+    loginbox=00000066
+    loginshadow=00000000
+    locktext="Type password to unlock..."
+    font="sans-serif"
+    ringcolor=ffffffff
+    insidecolor=00000000
+    separatorcolor=00000000
+    ringvercolor=ffffffff
+    insidevercolor=00000000
+    ringwrongcolor=ffffffff
+    insidewrongcolor=d23c3dff
+    timecolor=ffffffff
+    time_format="%H:%M:%S"
+    greetercolor=ffffffff
+    layoutcolor=ffffffff
+    keyhlcolor=d23c3dff
+    bshlcolor=d23c3dff
+    veriftext="Verifying..."
+    verifcolor=ffffffff
+    wrongtext="Failure!"
+    wrongcolor=d23c3dff
+    modifcolor=d23c3dff
+    bgcolor=000000ff
+    wallpaper_cmd="feh --bg-fill"
+
+    # read user config
+    USER_CONF_DIR="${XDG_CONFIG_HOME:-$HOME/.config}"
+    USER_CONF="$USER_CONF_DIR/betterlockscreenrc"
+    SYS_CONF="/etc/betterlockscreenrc"
+    XDG_USER_CONF_DIR="$USER_CONF_DIR/betterlockscreen"
+    XDG_USER_CONF="$XDG_USER_CONF_DIR/betterlockscreenrc"
+
+    if [ -e "$SYS_CONF" ]; then
+        # shellcheck source=/dev/null
+        source "$SYS_CONF"
+    fi
+
+    if [ -e "$USER_CONF" ]; then
+        echof error "Please, migrate your config $USER_CONF to $XDG_USER_CONF. Old location will soon be deprecated."
+        echof info "mkdir -p ~/.config/betterlockscreen/ && mv $USER_CONF $XDG_USER_CONF"
+
+        # shellcheck source=/dev/null
+        source "$USER_CONF"
+    fi
+
+    if [ -e "$XDG_USER_CONF" ]; then
+        # shellcheck source=/dev/null
+        source "$XDG_USER_CONF"
+    fi
+
+    if ! cmd_exists "$i3lockcolor_bin"; then
+        echof error "Unable to find i3lock-color binary under detected/configured name: '$i3lockcolor_bin'!"
+        exit
+    fi
+
+    # Please make sure to adjust this before release!
+    VERSION="4.3.0"
+
+    # paths
+    CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/betterlockscreen"
+    CUR_DIR="$CACHE_DIR/current"
+
+    # wallpaper
+    CUR_W_RESIZE="$CUR_DIR/wall_resize.png"
+    CUR_W_DIM="$CUR_DIR/wall_dim.png"
+    CUR_W_BLUR="$CUR_DIR/wall_blur.png"
+    CUR_W_DIMBLUR="$CUR_DIR/wall_dimblur.png"
+    CUR_W_PIXEL="$CUR_DIR/wall_pixel.png"
+    CUR_W_DIMPIXEL="$CUR_DIR/wall_dimpixel.png"
+    CUR_W_COLOR="$CUR_DIR/wall_color.png"
+
+    # lockscreen
+    CUR_L_RESIZE="$CUR_DIR/lock_resize.png"
+    CUR_L_DIM="$CUR_DIR/lock_dim.png"
+    CUR_L_BLUR="$CUR_DIR/lock_blur.png"
+    CUR_L_DIMBLUR="$CUR_DIR/lock_dimblur.png"
+    CUR_L_PIXEL="$CUR_DIR/lock_pixel.png"
+    CUR_L_DIMPIXEL="$CUR_DIR/lock_dimpixel.png"
+    CUR_L_COLOR="$CUR_DIR/lock_color.png"
+
+    # Original DPMS timeout
+    DEFAULT_TIMEOUT=$(cut -d ' ' -f4 <<< "$(xset q | sed -n '25p')")
+    # Original DPMS status
+    DEFAULT_DPMS=$(xset q | awk '/^[[:blank:]]*DPMS is/ {print $(NF)}')
+
+    # Dunst
+    DUNST_INSTALLED=false && [[ -e "$(command -v dunstctl)" ]] && DUNST_INSTALLED=true
+    DUNST_IS_RUNNING=false && [[ "$DUNST_INSTALLED" == "true" ]] && [[ "$(pgrep -c dunst)" -gt 0 ]] && DUNST_IS_RUNNING=true
+    DUNST_IS_PAUSED=false && [[ "$DUNST_IS_RUNNING" == "true" ]] && DUNST_IS_PAUSED=$(dunstctl is-paused)
+
+    # Feh
+    FEH_INSTALLED=false && [[ -e "$(command -v feh)" ]] && FEH_INSTALLED=true
+}
+
+# called before screen is locked
+prelock() {
+    # set dpms timeout
+    if [ "$DEFAULT_DPMS" == "Enabled" ]; then
+        xset dpms "$lock_timeout"
+    fi
+
+    # If dusnt is already paused don't pause it again
+    if [[ "$DUNST_IS_RUNNING" == "true" && "$DUNST_IS_PAUSED" == "false" ]]; then
+        dunstctl set-paused true
+    fi
+
+    if [ -e "$XDG_USER_CONF_DIR/custom-pre.sh" ]; then
+        # shellcheck source=/dev/null
+        source "$XDG_USER_CONF_DIR/custom-pre.sh"
+    fi
+}
+
+# lock screen with specified image
+lock() {
+    local image="$1"
+    local fontlg=32
+    local fontmd=16
+    local fontsm=12
+
+    if [ -f "$image" ]; then
+        echof act "Locking screen..."
+    else
+        echof act "Locking screen... (FAILSAFE MODE)"
+    fi
+
+    $i3lockcolor_bin \
+        ${image:+-i "$image"} \
+        --color "$bgcolor" \
+        ${display_on:+-S "$display_on"} \
+        --ind-pos="x+310:y+h-80" \
+        --radius=25 \
+        --ring-width=5 \
+        --inside-color="$insidecolor" \
+        --ring-color="$ringcolor" \
+        --separator-color=$separatorcolor \
+        --insidever-color="$insidevercolor" \
+        --insidewrong-color="$insidewrongcolor" \
+        --ringver-color="$ringvercolor" \
+        --ringwrong-color="$ringwrongcolor" \
+        --line-uses-inside \
+        --keyhl-color="$keyhlcolor" \
+        --bshl-color="$bshlcolor" \
+        --clock --force-clock \
+        --time-pos="ix-265:iy-10" \
+        --time-align 1 \
+        --time-str "$time_format" \
+        --time-color="$timecolor" \
+        --time-font="$font" \
+        --time-size="$fontlg" \
+        --date-str "" \
+        --greeter-pos="ix-265:iy+12" \
+        --greeter-align 1 \
+        --greeter-text "$locktext" \
+        --greeter-color="$greetercolor" \
+        --greeter-font="$font" \
+        --greeter-size="$fontmd" \
+        --layout-pos="ix-265:iy+32" \
+        --layout-align 1 \
+        --layout-color="$layoutcolor" \
+        --layout-font="$font" \
+        --layout-size="$fontsm" \
+        --verif-pos="ix+35:iy-34" \
+        --verif-align 2 \
+        --verif-text="$veriftext" \
+        --verif-color="$verifcolor" \
+        --verif-font="$font" \
+        --verif-size="$fontsm" \
+        --wrong-pos="ix+24:iy-34" \
+        --wrong-align 2 \
+        --wrong-text="$wrongtext" \
+        --wrong-color="$wrongcolor" \
+        --wrong-font="$font" \
+        --wrong-size="$fontsm" \
+        --modif-pos="ix+45:iy+43" \
+        --modif-align 2 \
+        --modif-size="$fontsm" \
+        --modif-color="$modifcolor" \
+        --noinput-text="" \
+        --pass-media-keys \
+        --pass-screen-keys \
+        --pass-volume-keys \
+        --pass-power-keys \
+        "${lockargs[@]}"
+}
+
+# called after screen is unlocked
+postlock() {
+    # restore default dpms timeout
+    if [ "$DEFAULT_DPMS" == "Enabled" ]; then
+        xset dpms "$DEFAULT_TIMEOUT"
+    fi
+
+    # If dunst already paused before locking don't unpause dunst
+    if [[ "$DUNST_IS_RUNNING" == "true" && "$DUNST_IS_PAUSED" == "false" ]]; then
+        dunstctl set-paused false
+    fi
+
+    if [ -e "$XDG_USER_CONF_DIR/custom-post.sh" ]; then
+        # shellcheck source=/dev/null
+        source "$XDG_USER_CONF_DIR/custom-post.sh"
+    fi
+}
+
+# select effect and lock screen
+lockinit() {
+    if pgrep -u "$USER" "$i3lockcolor_bin"; then
+        echof error "i3lock already running"
+        exit 1
+    fi
+
+    echof act "Running prelock..."
+    prelock
+
+    if [[ $runsuspend ]]; then
+        lockselect "$@" &
+        $suspend_command
+        wait $!
+    else
+        lockselect "$@"
+    fi
+
+    echof act "Running postlock..."
+    postlock
+}
+
+lockselect() {
+    case "$1" in
+        dim) lock "$CUR_L_DIM" ;;
+        blur) lock "$CUR_L_BLUR" ;;
+        dimblur) lock "$CUR_L_DIMBLUR" ;;
+        pixel) lock "$CUR_L_PIXEL" ;;
+        dimpixel) lock "$CUR_L_DIMPIXEL" ;;
+        color) lock "$CUR_L_COLOR" ;;
+        *) lock "$CUR_L_RESIZE" ;;
+    esac
+}
+
+# calculate adjustments for hidpi displays
+logical_px() {
+    # $1: number of pixels to convert
+    # $2: 1 for width. 2 for height
+    local pixels="$1"
+    local direction="$2"
+    local dpi
+
+    # use DPI set by user in .Xresources
+    dpi=$(xrdb -q | grep -oP '^\s*Xft.dpi:\s*\K\d+' | bc)
+
+    # or get dpi value from xdpyinfo
+    if [ -z "$dpi" ]; then
+        dpi=$(xdpyinfo | sed -En "s/\s*resolution:\s*([0-9]*)x([0-9]*)\s.*/\\$direction/p" | head -n1)
+    fi
+
+    # adjust scaling
+    if [ -n "$dpi" ]; then
+        local scale
+        scale=$(echo "scale=3; $dpi / 96.0" | bc)
+        echo "$scale * $pixels / 1" | bc
+    else
+        # return the default value if no DPI is set
+        echo "$pixels"
+    fi
+}
+
+# get total resolution, sets $TOTAL_SIZE
+get_total_size () {
+    TOTAL_SIZE=$(xdpyinfo | grep -w "dimensions" | sed -r 's/^[^0-9]*([0-9]+x[0-9]+).*$/\1/')
+}
+
+# get list of displays, sets $DISPLAY_LIST
+get_display_list () {
+    local count=0
+    mapfile -t displays < <(xrandr --listactivemonitors)
+    for display in "${displays[@]:1}"; do
+        ((count++))
+        display="$(echo "$display" | sed -r 's/\/[0-9]*//g')"
+        IFS=' ' read -r -a info  <<< "$display"
+        DISPLAY_LIST+=("$count ${info[3]} ${info[2]}")
+    done
+}
+
+# populate $WALL_LIST depending on number of displays and images passed
+get_wall_list() {
+    local paths=("$@")
+    declare -ga WALL_LIST
+
+    # multiple images and spanning conflict, bail out
+    if [ "${#paths[@]}" -gt 1 ] && [ "$span_image" = true ]; then
+        echof err "Can't use --span with multiple images!"
+        exit 1
+    fi
+
+    # if spanning return 1 image
+    if [ "$span_image" = true ]; then
+        get_image "${paths[0]}"
+
+    # if # paths is 1
+    elif [ "${#paths[@]}" -eq 1 ]; then
+        for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+            # add same image to $WALL_LIST for each display
+            get_image "${paths[0]}"
+        done
+
+    # if # of paths equals # of displays
+    elif [ ${#paths[@]} -eq "${#DISPLAY_LIST[@]}" ]; then
+        for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+            # add each image to $WALL_LIST
+            get_image "${paths[$i]}"
+        done
+
+    # if # of paths differ from # of display, bail out
+    else
+        echof err "${#paths[@]} images provided for ${#DISPLAY_LIST[@]} displays!"
+        exit 1
+    fi
+}
+
+# get image path, append to $WALL_LIST
+get_image() {
+    local path="$1"
+
+    # we have a file
+    if [ -f "$path" ]; then
+        WALL_LIST+=("$path")
+        return
+    # we have a directory
+    elif [ -d "$path" ]; then
+        dir=("$path"/*)
+        rdir="${dir[RANDOM % ${#dir[@]}]}"
+        get_image "$rdir" # <-- calls itself
+    # not file or directory, bail out
+    else
+        echof err "invalid path: $path"
+        exit 1
+    fi
+
+}
+
+# scale base image and generate effects
+resize_and_render () {
+    local base="$1"
+    local path="$2"
+    local resolution="$3"
+
+    # resource paths
+    RES_RESIZE="$path/resize.png"
+    RES_DIM="$path/dim.png"
+    RES_BLUR="$path/blur.png"
+    RES_DIMBLUR="$path/dimblur.png"
+    RES_PIXEL="$path/pixel.png"
+    RES_DIMPIXEL="$path/dimpixel.png"
+    RES_COLOR="$path/color.png"
+
+    # resize
+    base_resize "$base" "$RES_RESIZE" "$resolution"
+
+    # effects
+    for effect in "${fx_list[@]}"; do
+        case $effect in
+            dim) fx_dim "$RES_RESIZE" "$RES_DIM";;
+            blur) fx_blur "$RES_RESIZE" "$RES_BLUR" "$resolution";;
+            dimblur) fx_dimblur "$RES_RESIZE" "$RES_DIMBLUR" "$resolution";;
+            pixel) fx_pixel "$RES_RESIZE" "$RES_PIXEL";;
+            dimpixel) fx_dimpixel "$RES_RESIZE" "$RES_DIMPIXEL";;
+            color) fx_color "$RES_COLOR" "$resolution";;
+        esac
+    done
+
+}
+
+# apply resize
+base_resize() {
+    local input="$1"
+    local output="$2"
+    local size="$3"
+
+    echof act "Resizing base image..."
+    eval $convert_command "$input" \
+        -resize "$size""^" \
+        -gravity center \
+        -extent "$size" \
+        "$output"
+}
+
+# apply dim
+fx_dim() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'dim' effect..."
+    eval $convert_command "$input" \
+        -fill black -colorize "$dim_level"% \
+        "$output"
+}
+
+# apply blur
+fx_blur() {
+    local input="$1"
+    local output="$2"
+    local size="$3"
+
+    echof act "Rendering 'blur' effect..."
+    blur_shrink=$(echo "scale=2; 20 / $blur_level" | bc)
+    blur_sigma=$(echo "scale=2; 0.6 * $blur_level" | bc)
+    eval $convert_command "$input" \
+        -filter Gaussian \
+        -resize "$blur_shrink%" \
+        -define "filter:sigma=$blur_sigma" \
+        -resize "$size^" -gravity center -extent "$size" \
+        "$output"
+}
+
+# apply dimblur
+fx_dimblur() {
+    local input="$1"
+    local output="$2"
+    local size="$3"
+
+    echof act "Rendering 'dimblur' effect..."
+    blur_shrink=$(echo "scale=2; 20 / $blur_level" | bc)
+    blur_sigma=$(echo "scale=2; 0.6 * $blur_level" | bc)
+    eval $convert_command "$input" \
+        -fill black -colorize "$dim_level"% \
+        -filter Gaussian \
+        -resize "$blur_shrink%" \
+        -define "filter:sigma=$blur_sigma" \
+        -resize "$size^" -gravity center -extent "$size" \
+        "$output"
+}
+
+# pixelate
+fx_pixel() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'pixel' effect..."
+    IFS=',' read -ra range <<< "$pixel_scale"
+    eval $convert_command "$input" \
+        -scale "${range[0]}"% -scale "${range[1]}"% \
+        "$output"
+}
+
+# apply dimpixel
+fx_dimpixel() {
+    local input="$1"
+    local output="$2"
+
+    echof act "Rendering 'dimpixel' effect..."
+    IFS=',' read -ra range <<< "$pixel_scale"
+    eval $convert_command "$input" \
+        -fill black -colorize "$dim_level"% \
+        -scale "${range[0]}"% -scale "${range[1]}"% \
+        "$output"
+}
+
+# create solid color
+fx_color() {
+    local output="$1"
+    local size="$2"
+
+    echof act "Rendering 'color' effect..."
+    eval $convert_command -size "$size" canvas:\#"$solid_color" "$RES_COLOR"
+}
+
+# create loginbox rectangle, set "$RECTANGLE"
+create_loginbox () {
+    RECTANGLE="$CUR_DIR/rectangle.png"
+    local shadow="$CUR_DIR/shadow.png"
+    local width height
+    width=$(logical_px 340 1)
+    height=$(logical_px 100 2)
+    $convert_command -size "$width"x"$height" xc:\#"$loginbox" -fill none "$RECTANGLE"
+    $convert_command "$RECTANGLE" \
+        \( -clone 0 -background \#"$loginshadow" -shadow 100x5+0+0 \) +swap \
+        -background none -layers merge +repage "$shadow"
+    $composite_command -compose Dst_Out -gravity center \
+        "$RECTANGLE" "$shadow" -alpha Set "$shadow"
+    $convert_command "$shadow" "$RECTANGLE" -geometry +10+10 -composite "$RECTANGLE"
+    [[ "$shadow" ]] && rm "$shadow"
+}
+
+# create rectangle with description, set "$DESCRECT"
+create_description () {
+    DESCRECT="$CUR_DIR/description.png"
+    local shadow="$CUR_DIR/shadow.png"
+    $convert_command -background none -family "$(fc-match "$font" family)" -style Normal -pointsize 14 -fill \#"$greetercolor" label:"\ $description\ " -bordercolor \#"$loginbox" -border 10 "$DESCRECT"
+    $convert_command "$DESCRECT" \
+        \( -clone 0 -background \#"$loginshadow" -shadow 100x5+0+0 \) +swap \
+        -background none -layers merge +repage "$shadow"
+    $composite_command -compose Dst_Out -gravity center \
+        "$DESCRECT" "$shadow" -alpha Set "$shadow"
+    $convert_command "$shadow" "$DESCRECT" -geometry +10+10 -composite "$DESCRECT"
+    [[ "$shadow" ]] && rm "$shadow"
+}
+
+# delete and recreate directory
+purge_cache () {
+    if [[ -d "$1" ]]; then
+        rm -r "$1"
+    fi
+    mkdir -p "$1"
+}
+
+# update lockscreen and wallpaper images
+update () {
+    local images=("$@")
+
+    echof act "Updating image cache..."
+    mkdir -p "$CACHE_DIR" &>/dev/null
+
+    get_display_list # DISPLAY_LIST
+    get_total_size # TOTAL_SIZE
+    echof info "Detected ${#DISPLAY_LIST[@]} display(s) @ $TOTAL_SIZE total resolution"
+
+    get_wall_list "${images[@]}" # WALL_LIST
+    echof info "Original image(s): ${WALL_LIST[*]##*/}"
+
+    # Prepare description box to obtain width for positioning
+    local descwidth
+    local descheight
+    if [ -z "$description" ]; then
+        descwidth=0
+        descheight=0
+    else
+        create_description
+        descwidth=$(identify -format "%[fx:w]" "$DESCRECT")
+        descheight=$(identify -format "%[fx:h]" "$DESCRECT")
+    fi
+
+    for ((i=0; i<${#DISPLAY_LIST[@]}; i++)); do
+        display="${DISPLAY_LIST[$i]}"
+        USER_WALL="${WALL_LIST[$i]}"
+
+        # escape spaces for IM
+        if echo "$USER_WALL" | grep -E -q "[[:space:]]"; then
+            USER_WALL="${USER_WALL// /\\ }"
+        fi
+
+        IFS=' ' read -r -a dinfo  <<< "$display"
+        local id="${dinfo[0]}"
+        local device="${dinfo[1]}"
+        local geometry="${dinfo[2]}"
+
+        read -r -a cols <<< "${geometry//[x+-]/ }"
+        local position="${geometry#*"${cols[1]}"}"
+        local resolution="${geometry%"${position}"*}"
+
+        if [[ $id -eq "$display_on" ]] || [[ "$display_on" -eq 0 ]]; then
+
+            IFS='x' read -r -a dimension <<< "$resolution"
+            res_x="${dimension[0]}"
+            res_y="${dimension[1]}"
+            read -r -a val <<< "${position//[+-]/ }"
+            read -r -a sym <<< "${position//[0-9]/ }"
+            pos_x="${sym[0]}${val[0]}"
+            pos_y="${sym[1]}${val[1]}"
+
+            rect_x=$((pos_x + $(logical_px 15 1)))
+            rect_y=$((pos_y + res_y - $(logical_px 140 2)))
+            positions+=("+$((rect_x))+$((rect_y))")
+
+            descrect_x=$((pos_x + res_x - descwidth - $(logical_px 15 1)))
+            descrect_y=$((pos_y + res_y - descheight - $(logical_px 20 2)))
+            positions_desc+=("+$((descrect_x))+$((descrect_y))")
+        fi
+
+        local path="$CACHE_DIR/$id-$device"
+        purge_cache "$path"
+
+        if [ "$span_image" = true ]; then
+            if [ "$id" -gt 1 ]; then
+                continue
+            else
+                device="[span]"
+                id="*"
+                resolution="$TOTAL_SIZE"
+            fi
+        fi
+
+        echof info "Processing display: $device ($id)"
+        echof info "Resolution: $resolution"
+
+        if [ "$span_image" = true ]; then
+            resize_and_render "$USER_WALL" "$path" "$resolution"
+        else
+            resize_and_render "$USER_WALL" "$path" "$resolution"
+
+            PARAM_RESIZE="$PARAM_RESIZE $RES_RESIZE -geometry $position -composite "
+            PARAM_DIM="$PARAM_DIM $RES_DIM -geometry $position -composite "
+            PARAM_BLUR="$PARAM_BLUR $RES_BLUR -geometry $position -composite "
+            PARAM_DIMBLUR="$PARAM_DIMBLUR $RES_DIMBLUR -geometry $position -composite "
+            PARAM_PIXEL="$PARAM_PIXEL $RES_PIXEL -geometry $position -composite "
+            PARAM_DIMPIXEL="$PARAM_DIMPIXEL $RES_DIMPIXEL -geometry $position -composite "
+            PARAM_COLOR="$PARAM_COLOR $RES_COLOR -geometry $position -composite "
+        fi
+
+    done
+
+    purge_cache "$CUR_DIR"
+
+    if [ "$span_image" = true ] || [ ${#DISPLAY_LIST[@]} -lt 2 ]; then
+        echof act "Rendering final wallpaper images..."
+        [[ -f "$RES_RESIZE" ]] && eval "cp $RES_RESIZE $CUR_W_RESIZE"
+        [[ -f "$RES_DIM" ]] && eval "cp $RES_DIM $CUR_W_DIM"
+        [[ -f "$RES_BLUR" ]] && eval "cp $RES_BLUR $CUR_W_BLUR"
+        [[ -f "$RES_DIMBLUR" ]] && eval "cp $RES_DIMBLUR $CUR_W_DIMBLUR"
+        [[ -f "$RES_PIXEL" ]] && eval "cp $RES_PIXEL $CUR_W_PIXEL"
+        [[ -f "$RES_DIMPIXEL" ]] && eval "cp $RES_DIMPIXEL $CUR_W_DIMPIXEL"
+        [[ -f "$RES_COLOR" ]] && eval "cp $RES_COLOR $CUR_W_COLOR"
+    else
+        echof act "Creating canvas: $TOTAL_SIZE"
+        [[ -f "$RES_RESIZE" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_RESIZE"
+        [[ -f "$RES_DIM" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIM"
+        [[ -f "$RES_BLUR" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_BLUR"
+        [[ -f "$RES_DIMBLUR" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIMBLUR"
+        [[ -f "$RES_PIXEL" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_PIXEL"
+        [[ -f "$RES_DIMPIXEL" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_DIMPIXEL"
+        [[ -f "$RES_COLOR" ]] && eval "$convert_command -size $TOTAL_SIZE 'xc:blue' $CUR_W_COLOR"
+
+        echof act "Rendering final wallpaper images..."
+        [[ -f "$CUR_W_RESIZE" ]] && eval "$convert_command $CUR_W_RESIZE $PARAM_RESIZE $CUR_W_RESIZE"
+        [[ -f "$CUR_W_DIM" ]] && eval "$convert_command $CUR_W_DIM $PARAM_DIM $CUR_W_DIM"
+        [[ -f "$CUR_W_BLUR" ]] && eval "$convert_command $CUR_W_BLUR $PARAM_BLUR $CUR_W_BLUR"
+        [[ -f "$CUR_W_DIMBLUR" ]] && eval "$convert_command $CUR_W_DIMBLUR $PARAM_DIMBLUR $CUR_W_DIMBLUR"
+        [[ -f "$CUR_W_PIXEL" ]] && eval "$convert_command $CUR_W_PIXEL $PARAM_PIXEL $CUR_W_PIXEL"
+        [[ -f "$CUR_W_DIMPIXEL" ]] && eval "$convert_command $CUR_W_DIMPIXEL $PARAM_DIMPIXEL $CUR_W_DIMPIXEL"
+        [[ -f "$CUR_W_COLOR" ]] && eval "$convert_command $CUR_W_COLOR $PARAM_COLOR $CUR_W_COLOR"
+    fi
+
+    echof act "Rendering final lockscreen images..."
+
+    create_loginbox
+    for pos in "${positions[@]}"; do
+        PARAM_RECT="$PARAM_RECT $RECTANGLE -geometry $pos -composite "
+    done
+
+    if [ -n "$description" ]; then
+        create_description
+        for descpos in "${positions_desc[@]}"; do
+            PARAM_RECT="$PARAM_RECT $DESCRECT -geometry $descpos -composite "
+        done
+    fi
+
+    [[ -f "$CUR_W_RESIZE" ]] && eval "$convert_command $CUR_W_RESIZE $PARAM_RECT $CUR_L_RESIZE"
+    [[ -f "$CUR_W_DIM" ]] && eval "$convert_command $CUR_W_DIM $PARAM_RECT $CUR_L_DIM"
+    [[ -f "$CUR_W_BLUR" ]] && eval "$convert_command $CUR_W_BLUR $PARAM_RECT $CUR_L_BLUR"
+    [[ -f "$CUR_W_DIMBLUR" ]] && eval "$convert_command $CUR_W_DIMBLUR $PARAM_RECT $CUR_L_DIMBLUR"
+    [[ -f "$CUR_W_PIXEL" ]] && eval "$convert_command $CUR_W_PIXEL $PARAM_RECT $CUR_L_PIXEL"
+    [[ -f "$CUR_W_DIMPIXEL" ]] && eval "$convert_command $CUR_W_DIMPIXEL $PARAM_RECT $CUR_L_DIMPIXEL"
+    [[ -f "$CUR_W_COLOR" ]] && eval "$convert_command $CUR_W_COLOR $PARAM_RECT $CUR_L_COLOR"
+
+    [[ "$RECTANGLE" ]] && rm "$RECTANGLE"
+    [[ "$DESCRECT" ]] && rm "$DESCRECT"
+
+    echof ok "Done"
+
+}
+
+# set wallpaper with effect
+wallpaper() {
+    local effect="$1"
+
+    # make wallpaper span displays
+    get_display_list
+    if [ "$span_image" = true ] || [[ "${#DISPLAY_LIST[@]}" -gt 1 ]]; then
+        wallpaper_cmd="$wallpaper_cmd --no-xinerama"
+    fi
+
+    # set wallpaper
+    case "$effect" in
+        dim) wallpaper="$CUR_W_DIM";;
+        blur) wallpaper="$CUR_W_BLUR";;
+        dimblur) wallpaper="$CUR_W_DIMBLUR";;
+        pixel) wallpaper="$CUR_W_PIXEL";;
+        dimpixel) wallpaper="$CUR_W_DIMPIXEL";;
+        color) wallpaper="$CUR_W_COLOR";;
+        *) wallpaper="$CUR_W_RESIZE";;
+    esac
+    eval "$wallpaper_cmd $wallpaper"
+}
+
+# wrap echo with fancy prefix
+echof() {
+    local prefix="$1"
+    local message="$2"
+
+    case "$prefix" in
+        header) msgpfx="[\e[1;95mB\e[m]";;
+        info) msgpfx="[\e[1;97m=\e[m]";;
+        act) msgpfx="[\e[1;92m*\e[m]";;
+        ok) msgpfx="[\e[1;93m+\e[m]";;
+        error) msgpfx="[\e[1;91m!\e[m]";;
+        *) msgpfx="";;
+    esac
+    [ "$quiet" != true ] && echo -e "$msgpfx $message"
+}
+
+# help message
+usage() {
+    echo
+    echo "Usage: betterlockscreen [-u <PATH>] [-l <EFFECT>] [-w <EFFECT>]"
+    echo
+    echo "  -q --quiet"
+    echo "      Do not produce any text output on locking"
+    echo
+    echo "  -u --update <PATH>"
+    echo "      Update lock screen image"
+    echo
+    echo "  -l --lock <EFFECT>"
+    echo "      Lock screen with cached image"
+    echo
+    echo "  -w --wall <EFFECT>"
+    echo "      Set wallpaper with cached image"
+    echo
+    echo "Additional arguments:"
+    echo
+    echo "  --display <N>"
+    echo "      Set display to draw loginbox"
+    echo
+    echo "  --span"
+    echo "      Scale image to span multiple displays"
+    echo
+    echo "  --off <N>"
+    echo "      Turn display off after N seconds"
+    echo
+    echo "  --fx <EFFECT,EFFECT,EFFECT>"
+    echo "      List of effects to generate"
+    echo
+    echo "  --desc <DESCRIPTION>"
+    echo "      Set a description for the new lock screen image"
+    echo "      (Only has an effect in combination with --update)"
+    echo
+    echo "  --show-layout"
+    echo "      Show current keyboard layout"
+    echo
+    echo "  --wallpaper-cmd <command>"
+    echo "      to set your custom wallpaper setter"
+    echo
+    echo "  --time-format <format>"
+    echo "      to set the time format used by i3lock-color"
+    echo
+    echo "  -- <ARGS>"
+    echo "      Pass additional arguments to i3lock"
+    echo
+    echo "Effects arguments:"
+    echo
+    echo "  --dim <N>"
+    echo "      Dim image N percent (0-100)"
+    echo
+    echo "  --blur <N>"
+    echo "      Blur image N amount (0.0-1.0)"
+    echo
+    echo "  --pixel <N,N>"
+    echo "      Pixelate image with N shrink and N grow (unsupported)"
+    echo
+    echo "  --color <HEX>"
+    echo "      Solid color background with HEX"
+    echo
+    exit 1
+}
+
+lockargs=(-n)
+
+init_config
+
+# show usage when no arguments passed
+[[ "$1" = "" ]] && usage
+
+# process arguments
+for arg in "$@"; do
+    [[ "${arg:0:1}" = '-' ]] || continue
+
+    case "$1" in
+
+        -q | --quiet)
+            quiet=true
+            shift
+            ;;
+
+        -u | --update)
+            runupdate=true
+            imagepaths+=("$2")
+            shift 2
+            ;;
+
+        -s | --suspend)
+            runsuspend=true
+            ;&
+
+        -l | --lock)
+            runlock=true
+            if [[ ${2:0:1} = '-' ]]; then
+                shift 1
+            else
+                lockstyle="$2"; shift 2
+            fi
+            ;;
+
+        -w | --wall)
+            wallpaper "$2"
+            shift 2
+            ;;
+
+        --wallpaper-cmd)
+            wallpaper_cmd="$2"
+            shift 2
+            ;;
+
+        --time-format)
+            time_format="$2"
+            shift 2
+            ;;
+
+        --display)
+            display_on="$2"
+            shift 2
+            ;;
+
+        --span)
+            span_image=true
+            shift 1
+            ;;
+
+        --off)
+            lock_timeout="$2"
+            shift 2
+            ;;
+
+        --text)
+            locktext="$2"
+            shift 2
+            ;;
+
+        --show-layout)
+            keylayout="$2";
+            lockargs+=(--keylayout "${keylayout:-0}")
+            shift 2
+            ;;
+
+        --fx)
+            IFS=',' read -ra fx_list <<< "$2"
+            shift 2
+            ;;
+
+        --dim)
+            dim_level="$2"
+            shift 2
+            ;;
+
+        --blur)
+            blur_level="$2"
+            shift 2
+            ;;
+
+        --pixel)
+            pixel_scale="$2"
+            shift 2
+            ;;
+
+        --color)
+            solid_color="${2//\#/}"
+            shift 2
+            ;;
+
+        --desc)
+            description="$2"
+            shift 2
+            ;;
+
+        -v | --version)
+            echo
+            echo "Betterlockscreen: version: v$VERSION (dunst: $DUNST_INSTALLED, feh: $FEH_INSTALLED)"
+            $i3lockcolor_bin --version
+            $convert_command --version
+
+            if [[ "$DUNST_INSTALLED" == "true" ]]; then
+                dunstctl debug
+            fi
+
+            if [[ "$FEH_INSTALLED" == "true" ]]; then
+                feh --version
+            fi
+
+            break
+            ;;
+
+        --)
+            lockargs+=("${@:2}")
+            break
+            ;;
+
+        -h | --help | *)
+            usage
+            ;;
+    esac
+done
+
+echof header "Betterlockscreen"
+
+# Run image generation
+[[ $runupdate ]] && update "${imagepaths[@]}"
+
+# Activate lockscreen
+[[ $runlock ]] && lockinit "$lockstyle"
+
+exit 0
diff --git a/bin/blackpearl-emoji.sh b/bin/blackpearl-emoji.sh
new file mode 100644 (file)
index 0000000..a240225
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+rofi -no-lazy-grab -modi emoji -show emoji -theme darknix/runner.rasi
+
diff --git a/bin/blackpearl-notes.sh b/bin/blackpearl-notes.sh
new file mode 100644 (file)
index 0000000..a11244a
--- /dev/null
@@ -0,0 +1,28 @@
+#! /bin/bash
+
+rofi_command="rofi -theme darknix/notes.rasi"
+
+# list of existing notes passed to rofi
+options=$(notes -pl)
+
+# how to run the script
+PARAM="$1"
+case $PARAM in
+       -a )
+               alacritty --hold --class notes --title notes -e notes -a
+               ;;
+       -e )
+               # note_ID
+               selected=$(echo -e "$options" | $rofi_command -p "edit note" -dmenu -selected-row 0 | cut -d " " -f1)
+               alacritty --hold --class notes --title notes -e notes -e ${selected}
+               ;;
+       -d )
+               # note_ID
+               selected=$(echo -e "$options" | $rofi_command -p "delete note" -dmenu -selected-row 0 | cut -d " " -f1)
+               alacritty --hold --class notes --title notes -e notes -d ${selected}
+               ;;
+       * )
+               selected=$(echo -e "$options" | $rofi_command -p "notes" -dmenu -selected-row 0 | cut -d " " -f1)
+               alacritty --hold --class notes --title notes -e notes -s $selected
+               ;;
+esac
index c81cfd6718600e48a4c4d6438b66a197b03ffd36..fad6b1951e2fc21c43ec904c35d2bfdd4fc80e71 100644 (file)
@@ -7,31 +7,31 @@ rofi_command="rofi -theme darknix/powermenu.rasi"
 power_off=""
 reboot=""
 lock=""
-suspend="⏾" 
-log_out=""
+#suspend="⏾" 
+log_out="󰿅"
 # Variable passed to rofi
-options="$power_off\n$reboot\n$lock\n$suspend\n$log_out"
+options="$power_off\n$reboot\n$lock\n$log_out"
 
 chosen="$(echo -e "$options" | $rofi_command -dmenu -selected-row 0)"
 case $chosen in
     $power_off)
         notify-send 'shutting down' 'the system is going to shutdown now'
         sleep 1
-        sudo /sbin/shutdown -h now
+        /usr/bin/loginctl poweroff
         ;;
     $reboot)
         notify-send 'rebooting the system' 'the system is going to reboot now'
         sleep 1
-        sudo /sbin/shutdown -r now
+        /usr/bin/loginctl reboot
         ;;
     $lock)
         sleep 1
         i3lock-fancy
         ;;
-    $suspend)
-        sleep 1
-        i3suspend
-        ;;
+#    $suspend)
+#        sleep 1
+#        i3suspend
+#        ;;
     $log_out)
         i3-exit
         ;;
diff --git a/bin/blackpearl-symbols.sh b/bin/blackpearl-symbols.sh
new file mode 100644 (file)
index 0000000..5723bd1
--- /dev/null
@@ -0,0 +1 @@
+rofi -no-lazy-grab -show sym -modes "sym:symbols.sh" -theme darknix/runner.rasi
index 9bcab99bf695bf7f1f019b6fd69fe115c28fb3a3..8c2beaa56b87ef93ab1eb8d3592664ecbe934970 100644 (file)
@@ -11,7 +11,7 @@ options="$wpaper\n$webdevel"
 chosen="$(echo -e "$options" | $rofi_command -dmenu -selected-row 1)"
 case $chosen in
     $wpaper)
-        change_wallpaper.sh
+        qwalwal.sh
         ;;
     $webdevel)
         webdevel
index eb4f161480cc2dc16771a9b1aa865d0db0e21361..68d4d4fa1e73b1351f775e33fea3630f42ace08d 100644 (file)
@@ -2,10 +2,10 @@
 
 case $1 in
        all )
-               rofi -no-lazy-grab -show window -theme darknix/main.rasi
+               rofi -no-lazy-grab -show window -theme darknix/appslist.rasi -window-format " [{w}]     {c}     {t:20}" -window-thumbnail
                ;;
        desktop )
-               rofi -no-lazy-grab -show windowcd -theme darknix/main.rasi
+               rofi -no-lazy-grab -show windowcd -theme darknix/appslist.rasi
                ;;
 esac
 
index dd93b2313a75e6111ab58830e0fa093ceb52bc8d..e3d293a08bda82a4cf672467679b9d7a560e6fa7 100644 (file)
@@ -1,8 +1,12 @@
 #! /bin/bash
 
+# uncomment for debug
+# set -x
+
 PID=$$
 PIDFILE=${PIDFILE:-/tmp/wallpaper.pid}
 WAIT_CYCLE="5m"
+INPUT=$1
 
 trap "rm -f $PIDFILE" SIGTERM
 
@@ -86,7 +90,7 @@ function file_chooser() {
 function run() {
        if [[ $(basename $0) == "wallpaper.sh" ]]; then
                # we were called as wallpaper.sh, so simple wallpaper setter without qarma interaction
-               wpapers $1
+               wpapers "$1"
        elif [[ $(basename $0) == "change_wallpaper.sh" ]]; then
                # we use qarma to set the wallpaper
                $QARMA --question --title="Change Wallpaper" --text="Do you want to change the wallpaper?"
@@ -108,10 +112,16 @@ if [[ -r $PIDFILE ]]; then
        # let's kill it and run again
        kill -s 15 $(cat $PIDFILE) > /dev/null 2>&1
        # should already be deleted by trap, but just to be sure
+       rm /tmp/choice || true
        rm $PIDFILE
 fi
 
 # create PIDFILE
 echo $PID > $PIDFILE
 
-run
+if [[ ! -z $1 ]]; then
+    run $1
+else
+    run
+fi
+
diff --git a/bin/dunst-snooze.sh b/bin/dunst-snooze.sh
new file mode 100644 (file)
index 0000000..59bf6b0
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+case "$1" in
+    --toggle)
+        dunstctl set-paused toggle
+        ;;
+    *)
+        if [ "$(dunstctl is-paused)" = "true" ]; then
+            echo "  "
+        else
+            echo "  "
+        fi
+        ;;
+esac
diff --git a/bin/dunst_vol_brig.sh b/bin/dunst_vol_brig.sh
new file mode 100644 (file)
index 0000000..a255d34
--- /dev/null
@@ -0,0 +1,87 @@
+#! /bin/bash
+# See README.md for usage instructions
+bar_color="#ffbf00"
+volume_step=5
+brightness_step=10
+
+# Uses regex to get volume from pactl
+function get_volume {
+    pactl get-sink-volume @DEFAULT_SINK@ | grep -Po '[0-9]{1,3}(?=%)' | head -1
+}
+
+# Uses regex to get mute status from pactl
+function get_mute {
+    pactl get-sink-mute @DEFAULT_SINK@ | grep -Po '(?<=Mute: )(yes|no)'
+}
+
+# Uses regex to get brightness from xbacklight
+function get_brightness {
+    xbacklight | grep -Po '[0-9]{1,3}(?=\.)'
+}
+
+# Returns a mute icon, a volume-low icon, or a volume-high icon, depending on the volume
+function get_volume_icon {
+    volume=$(get_volume)
+    mute=$(get_mute)
+    if [ $volume -eq 0 ] || [ $mute == "yes" ] ; then
+        volume_icon=""
+    elif [ $volume -lt 50 ]; then
+        volume_icon=""
+    else
+        volume_icon=""
+    fi
+}
+
+# Always returns the same icon - I couldn't get the brightness-low icon to work with fontawesome
+function get_brightness_icon {
+    brightness_icon="󰃠"
+}
+
+# Displays a volume notification using dunstify
+function show_volume_notif {
+    volume=$(get_volume)
+    get_volume_icon
+    if [ $volume -eq 0 ] || [ $mute == "yes" ] ; then
+        volstr="SHHH!!"
+    else
+        volstr=${volume}%
+    fi
+    dunstify -i audio-volume-muted -t 1000 -r 2593 -u normal "$volume_icon $volstr" -h int:value:$volume -h string:hlcolor:$bar_color
+}
+
+# Displays a brightness notification using dunstify
+function show_brightness_notif {
+    brightness=$(get_brightness)
+    get_brightness_icon
+    dunstify -t 1000 -r 2593 -u normal "$brightness_icon $brightness%" -h int:value:$brightness -h string:hlcolor:$bar_color
+}
+
+# Main function - Takes user input, "volume_up", "volume_down", "brightness_up", or "brightness_down"
+case $1 in
+    vol_u)
+        # Unmutes and increases volume, then displays the notification
+        pactl set-sink-mute @DEFAULT_SINK@ 0
+        pactl set-sink-volume @DEFAULT_SINK@ +$volume_step%
+        show_volume_notif
+        ;;
+    vol_d)
+        # Raises volume and displays the notification
+        pactl set-sink-volume @DEFAULT_SINK@ -$volume_step%
+        show_volume_notif
+        ;;
+    mute)
+        # Toggles mute and displays the notification
+        pactl set-sink-mute @DEFAULT_SINK@ toggle
+        show_volume_notif
+        ;;
+    brig_u)
+        # Increases brightness and displays the notification
+        xbacklight -inc $brightness_step -time 0 
+        show_brightness_notif
+        ;;
+    brig_d)
+        # Decreases brightness and displays the notification
+        xbacklight -dec $brightness_step -time 0
+        show_brightness_notif
+        ;;
+esac
diff --git a/bin/executors/battery-level b/bin/executors/battery-level
deleted file mode 100644 (file)
index 4078b35..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/bash
-
-BAT_LEVEL=$(acpi -b | awk ' { print ($4)-0}')
-CHARGER_ON=$(acpi -a | grep -i "on")
-CHARGER_OFF=$(acpi -a | grep -i "off")
-
-if [ "$BAT_LEVEL" -le "20" ] ; then 
-       if [ "$CHARGER_OFF" ]; then
-               logger "battery not charging, we're gonna die soon."
-               notify-send -u critical -i dialog-error "BATTERY LOW" "battery level is below 20%, please plug the AC charger"
-               pactl set-sink-volume 0 100\%
-               pactl set-sink-mute 0 0
-               play -q /usr/share/sounds/Oxygen-Sys-App-Error.ogg
-       else
-               logger "battery low but charging. It's all fine."
-       fi
-elif [ "$BAT_LEVEL" -lt "10" ]; then
-       if [ "$CHARGER_ON" ]; then
-               logger "battery extremely low but charging. It's all fine."
-       else
-               notify-send -u critical -i dialog-error "BATTERY EXTREMELY LOW" "battery level is below 10%, the system is going to shutdown."
-               pactl set-sink-volume 0 100\%
-               pactl set-sink-mute 0 0
-               play -q /usr/share/sounds/Oxygen-Sys-App-Error-Serious.ogg
-       fi
-fi
diff --git a/bin/feh-blur b/bin/feh-blur
new file mode 100644 (file)
index 0000000..da1f499
--- /dev/null
@@ -0,0 +1,412 @@
+#!/usr/bin/env bash
+# https://github.com/rstacruz/feh-blur
+
+if [[ "$1" != "--worker" ]]; then
+  # Where to write stuff
+  export CACHE_DIR="/tmp/feh-blur.$$"
+
+  # How much to blur (--blur N)
+  export BLUR_STRENGTH="32"
+
+  # Contrast (--uncontrast)
+  export REDUCE_CONTRAST="0"
+
+  # How much to dim (--dim N)
+  export DIM_STRENGTH="32"
+
+  # Dimmer
+  export DIM_COLOR="#000"
+
+  # Where to write the final blurred image (--save-image PATH)
+  export BLUR_IMAGE_SAVE_LOCATION=""
+
+  # Interval between frames in an animation
+  export ANIMATION_INTERVAL=0.005
+
+  # Fade in and out?
+  export ANIMATE_FADE=1
+
+  # Interval to check with wmctrl
+  export POLL_INTERVAL=0.3
+
+  # The verbosity. --verbose sets this to 2, and --quiet sets it to 0.
+  export VERBOSE=1
+fi
+
+# The name of this program
+export BIN="$(basename "$0")"
+
+# Expression for proc grepping
+PROC_EXPR="bash.*$(basename "$0")"
+
+# Run mode. -d sets this to background (daemon) mode.
+# Values: background | foreground | noop
+MODE=foreground
+
+# Guard so that do_cleanup will only be invoked once.
+CLEANING_UP=0
+
+# Image extension to use. 'ppm' is used because it's faster to read/write to, I
+# think.
+EXT="ppm"
+
+# The original source.
+wall_original="$CACHE_DIR/original.$EXT"
+
+# Echo some info. Only if verbose=1
+info () {
+  if [[ "$VERBOSE" -gt 0 ]]; then
+    echo "    $1"
+  fi
+}
+
+head () {
+  if [[ "$VERBOSE" -gt 0 ]]; then
+    echo ""
+    echo -e " \033[31m>>\033[32m $1\033[0m"
+  fi
+}
+
+# Log some debug info
+debug () {
+  if [[ "$VERBOSE" -gt 1 ]]; then
+    echo "  - $1"
+  fi
+}
+
+# Generate a bunch of images
+generate_blurred_images () {
+  mkdir -p "$CACHE_DIR"
+  local source="$1"
+  local original="$CACHE_DIR/original.$EXT"
+
+  gm convert "$source" -resize 1920x "$original"
+
+  head "Found wallpaper"
+  info "$source"
+  info "Generating blurred images..."
+
+  local fx1=""
+  local fx2=""
+  local fx3=""
+
+  if [[ "$BLUR_STRENGTH" != "0" ]]; then 
+    fx1="$fx1 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 4 )) -scale 400%"
+    fx2="$fx2 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 2 )) -scale 400%"
+    fx3="$fx3 -scale 25% -blur 0x$(( "$BLUR_STRENGTH" / 1 )) -scale 400%"
+  fi
+
+  if [[ "$REDUCE_CONTRAST" = "1" ]]; then
+    fx1="+contrast $fx1"
+    fx2="+contrast +contrast $fx2"
+    fx3="+contrast +contrast +contrast $fx3"
+  fi
+
+  if [[ "$DIM_STRENGTH" != "0" ]]; then
+    fx1="$fx1 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 4 ))%"
+    fx2="$fx2 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 2 ))%"
+    fx3="$fx3 -fill $DIM_COLOR -colorize $(( "$DIM_STRENGTH" / 1 ))%"
+  fi
+
+  gm convert "$original" \
+    $fx1 \
+    "$CACHE_DIR/blur-0.$EXT"
+  gm convert "$CACHE_DIR/blur-0.$EXT" \
+    $fx2 \
+    "$CACHE_DIR/blur-1.$EXT"
+  gm convert "$CACHE_DIR/blur-0.$EXT" \
+    $fx3 \
+    "$CACHE_DIR/blur-final.$EXT"
+
+  if [[ -n "$BLUR_IMAGE_SAVE_LOCATION" ]]; then
+    gm convert \
+      "$CACHE_DIR/blur-final.$EXT" \
+      "$BLUR_IMAGE_SAVE_LOCATION"
+  fi
+
+  info "Done."
+}
+
+# Get current feh wallpaper
+get_feh_wallpaper() {
+  tail -n1 "$HOME/.fehbg" | sed 's/--no-fehbg //g' | cut -d"'" -f2
+}
+
+# Get wallpaper mode like --bg-tile
+get_feh_wallpaper_mode() {
+  tail -n1 "$HOME/.fehbg" | sed 's/--no-fehbg //g' | cut -d' ' -f2
+}
+
+# get_current_workspace => "2"
+get_current_workspace() {
+  # 2 * DG: N/A VP: 0,0 WA: N/A Name
+  wmctrl -d | grep '\*' | cut -d' ' -f1
+}
+
+# get_open_windows_count() => "2"
+get_open_windows_count() {
+  workspace="$(get_current_workspace)"
+  wmctrl -l | cut -d' ' -f3 | grep -c "$workspace"
+}
+
+is_blank() {
+  count=$(get_open_windows_count)
+  [[ "$count" -eq 0 ]]
+}
+
+set_blurred_wallpaper() {
+  debug "Setting blurred wallpaper"
+  local mode="$1" # --bg-tile
+
+  if [[ "$ANIMATE_FADE" == 1 ]]; then
+    # We're going to redirect output to /dev/null to supress feh warnings
+    feh --no-fehbg "$mode" "$CACHE_DIR/blur-0.$EXT" &> /dev/null
+    sleep $ANIMATION_INTERVAL
+    feh --no-fehbg "$mode" "$CACHE_DIR/blur-1.$EXT" &> /dev/null
+    sleep $ANIMATION_INTERVAL
+  fi
+
+  feh --no-fehbg "$mode" "$CACHE_DIR/blur-final.$EXT" &> /dev/null
+}
+
+set_original_wallpaper() {
+  debug "Setting original wallpaper"
+  local mode="$1" # --bg-tile
+
+  if [[ "$ANIMATE_FADE" == 1 ]]; then
+    feh --no-fehbg "$mode" "$CACHE_DIR/blur-1.$EXT" &> /dev/null
+    sleep $ANIMATION_INTERVAL
+    feh --no-fehbg "$mode" "$CACHE_DIR/blur-0.$EXT" &> /dev/null
+    sleep $ANIMATION_INTERVAL
+  fi
+
+  feh --no-fehbg "$mode" "$wall_original" &> /dev/null
+}
+
+kill_other_instances() {
+  if [[ "$(pgrep -fcl "$PROC_EXPR")" -gt 1 ]]; then
+    head "Stopping other instances of $BIN..."
+
+    local count=1
+    while [[ "$(pgrep -fcl "$PROC_EXPR")" -gt 1 ]]; do
+      count=$(( count + 1 ))
+      old_pid="$(pgrep -fo "$PROC_EXPR")"
+
+      # Kill it; if it refuses after some time, force-stop it
+      if [[ "$count" -gt 10 ]]; then
+        kill -9 "$old_pid"
+      else
+        kill "$old_pid"
+      fi
+      sleep 0.1
+    done
+  fi
+}
+
+run_loop () {
+  prev_blank="-"
+  prev_wallpaper="-"
+  first_run="1"
+
+  while true; do
+    wallpaper="$(get_feh_wallpaper)"
+
+    # Check if wallpaper has changed.
+    if [[ "$prev_wallpaper" != "$wallpaper" ]]; then
+      wallpaper_mode="$(get_feh_wallpaper_mode)"
+
+      # If there's no wallpaper, try again later.
+      if [[ -z "$wallpaper" ]]; then
+        sleep "$POLL_INTERVAL"
+        continue
+      else
+        generate_blurred_images "$wallpaper"
+        prev_wallpaper="$wallpaper"
+        prev_blank=""
+      fi
+    fi
+
+    blank="$(is_blank && echo 1 || echo 0)"
+    if [[ "$prev_blank" != "$blank" ]]; then
+      if [[ "$blank" == 0 ]]; then
+        set_blurred_wallpaper "$wallpaper_mode"
+      elif [[ "$first_run" == "0" ]]; then
+        # Skip set_original_wallpaper if we were started without
+        # an active window so that the animation is skipped
+        set_original_wallpaper "$wallpaper_mode"
+      fi
+      prev_blank="$blank"
+    fi
+
+    first_run=0
+    sleep "$POLL_INTERVAL"
+  done
+}
+
+show_help() {
+  echo "Usage: $BIN [-v|--verbose]"
+  echo ''
+  echo 'Options:'
+  echo '  -b, --blur N            set blur strength to N (4...128, default 32)'
+  echo '      --darken N          darken image by N (4...100, default 32)'
+  echo '      --lighten N         lengthen image by N (4...100, default 0)'
+  echo '  -c, --uncontrast        reduce contrast'
+  echo '      --save-image PATH   save blurred image to PATH'
+  echo '      --no-animate        skip fading animation'
+  echo ''
+  echo 'Daemon options:'
+  echo '  -d, --daemon            run in background'
+  echo '  -s, --stop              stop previously-ran daemon'
+  echo ''
+  echo 'Other options:'
+  echo '  -v, --verbose           show more messages'
+  echo '  -q, --quiet             supress messages'
+  echo ''
+}
+
+parse_opts() {
+  while [[ "$1" =~ ^- && ! "$1" == "--" ]]; do case $1 in
+    -h | --help)
+      MODE=noop
+      show_help
+      ;;
+    -V | --version )
+      MODE=noop
+      echo version
+      ;;
+    -b | --blur )
+      shift
+      BLUR_STRENGTH="$1"
+      ;;
+    -c | --uncontrast )
+      REDUCE_CONTRAST=1
+      ;;
+    --save-image )
+      shift
+      BLUR_IMAGE_SAVE_LOCATION="$1"
+      ;;
+    --no-animate )
+      ANIMATE_FADE=0
+      ;;
+    -D | --dim | --darken )
+      shift
+      DIM_COLOR="#000"
+      DIM_STRENGTH="$1"
+      ;;
+    --lighten )
+      shift
+      DIM_COLOR="#fff"
+      DIM_STRENGTH="$1"
+      ;;
+    --tint-color )
+      shift
+      DIM_COLOR="$1"
+      ;;
+    --tint-strength )
+      shift
+      DIM_STRENGTH="$1"
+      ;;
+    -d | --daemon )
+      MODE=background
+      ;;
+    -s | --stop )
+      MODE=stop
+      ;;
+    -q | --quiet )
+      VERBOSE=0
+      ;;
+    -v | --verbose )
+      VERBOSE=2
+      ;;
+  esac; shift; done
+  if [[ "$1" == '--' ]]; then shift; fi
+}
+
+ensure_feh() {
+  if ! command -v feh >/dev/null; then
+    echo "$BIN requires Feh to set wallpapers."
+    exit
+  fi
+}
+
+# Ensure that 'graphicsmagick' is available.
+ensure_gm() {
+  if ! command -v gm >/dev/null; then
+    echo "$BIN requires GraphicsMagick to set wallpapers."
+    exit
+  fi
+}
+
+ensure_wmctrl() {
+  if ! command -v wmctrl >/dev/null; then
+    echo "$BIN requires wmctrl to detect events."
+    exit
+  fi
+}
+
+print_usage() {
+  head "Monitoring changes"
+  info "$BIN will now blur any wallpapers set using 'feh'."
+  info "To change your wallpaper, try:"
+  info ""
+  info "    feh --bg-tile your-image.jpg"
+}
+
+main() {
+  ensure_feh
+  ensure_gm
+  ensure_wmctrl
+  parse_opts "$@"
+
+  case "$MODE" in
+    background)
+      kill_other_instances
+      print_usage
+      "$0" --worker --quiet & disown
+
+      head "Background mode"
+      info "$BIN started in background mode!"
+      info "To stop, use '$BIN --stop'."
+      ;;
+  
+    stop)
+      kill_other_instances
+      ;;
+
+    noop)
+      exit
+      ;;
+
+    *)
+      kill_other_instances
+      print_usage
+      run_loop
+      ;;
+  esac
+}
+
+# Perform cleanup operations before stopping.
+do_cleanup () {
+  # Guard clause so that it's only ran once
+  if [[ "$CLEANING_UP" == "1" ]]; then return; fi
+  CLEANING_UP=1
+
+  rm -rf "$CACHE_DIR"
+
+  # Restore original wallpaper before exiting
+  if [[ "$MODE" == "foreground" ]] && [[ -e "$HOME/.fehbg" ]]; then
+    head "Restoring original wallpaper"
+    source "$HOME/.fehbg"
+  fi
+}
+
+finish () {
+  do_cleanup
+  exit 1
+}
+
+trap finish EXIT
+trap finish SIGHUP
+trap finish SIGINT
+trap finish SIGTERM
+main "$@"
diff --git a/bin/gify.sh b/bin/gify.sh
new file mode 100644 (file)
index 0000000..ee38bc0
--- /dev/null
@@ -0,0 +1,170 @@
+#! /bin/bash
+
+
+# ERROR & EXIT STATUSES
+SHOWHELP=61
+USERABORTED=62
+
+E_INTERROR=71
+E_NOOPTS=72
+E_NOARGS=73
+E_FILEXISTS=74
+E_NOIMAGES=75
+E_UNKNOWNOPT=76
+
+# TOOLS
+PWD=$(pwd)
+MOGRIFY=$(which mogrify)
+CONVERT=$(which convert)
+
+# we need mogrify and convert from the imagemagik toolset for this script to work
+if [[ ! -x $MOGRIFY || ! -x $CONVERT ]]; then
+    showerror missingdeps
+    exit $E_MISSINGDEPS
+fi
+
+
+# showhelp
+showhelp ()
+{
+case $1 in
+    resize )
+        echo "USAGE: $(basename $0) -r | --resize [width] [extension]"
+        ;;
+    gif )
+        echo "USAGE: $(basename $0) -g | --gif [delay] [extension] [output file name]"
+        ;;
+    * )
+                #|----------------------- TEXT MAX WIDTH - 80 CHARS ----------------------------|
+        echo -e "$(basename $0) - create animated gifs from images inside current directory"
+        echo -e "USAGE: $(basename $0) <option> [arguments]"
+        echo -e "\twhere <option> is one between:";echo
+        echo -e "\t-r | --resize [width] [extension]"
+        echo -e "\t\tresizes all the images matching the extension in the current folder to"
+        echo -e "\t\tthe width specified as argument.";echo
+        echo -e "\tg | --gif [delay] [extension] [output file name]"
+        echo -e "\t\tcreates the gif file using all the images in the current folder."
+        echo
+        echo -e "EXAMPLES:"
+        echo -e "$(basename $0) --resize 900 jpg"
+        echo -e "\twill resize all jpg images in the folder to 900px wide and mantain the"
+        echo -e "\taspect ratio of the original images"
+        echo
+        echo -e "$(basename $0) --gif 8 jpg france"
+        echo -e "\twill create a looping gif named france.gif using all the jpg files found"
+        echo -e "\tin the current folder and passing a tick delay of 8 between frames".
+        echo
+        ;;
+esac
+}
+
+# showerror
+showerror ()
+{
+    if [ -z $1 ];then
+        echo "INTERNAL ERROR - ABORTING"; echo
+        exit $E_INTERROR
+    fi
+    case $1 in
+        unknownopt)
+            echo "unknown option. Exiting."; echo
+        ;;
+        noopts)
+            echo "you didn't specify any options for the script to run. Exiting."; echo
+        ;;
+        noargs)
+            echo "you didn't specify any arguments for this option. Exiting."; echo
+        ;;
+        filexists)
+            echo "the file you want to write already exists. Exiting."; echo
+        ;;
+        noimages)
+            echo "at least two files must exist within $PWD with the"
+            echo "specified extension. Exiting"; echo
+        ;;
+        missingdeps)
+            echo "$(basename $0) requires both mogrify and convert from"
+            echo "the imagemagik tool suite. Install imagemagik using your"
+            echo "favourite package manager and then run this script again. Exiting."; echo
+    esac
+}
+
+##### MAIN #####
+if [ $# -eq 0 ];then
+    showerror noopts
+    showhelp
+    exit $E_NOOPTS
+else
+
+    while [ $# -gt 0 ];do
+        case $1 in
+            -h|--help)
+                showhelp
+                exit $SHOWHELP
+            ;;
+            -r|--resize)
+                WIDTH=$2
+                EXT=$3
+                shift
+                if [[ -z $WIDTH || -z $EXT ]];then
+                    showhelp resize
+                    showerror noargs
+                    exit $E_NOARGS
+                fi
+                IMAGES="$(ls -1 *.$EXT 2>/dev/null | wc -l)"
+                if [[ $IMAGES == 0 ]]; then
+                    showerror noimages
+                    exit $E_NOIMAGES
+                fi
+                clear
+                COUNT="$(ls -1 *.$EXT 2>/dev/null | wc -l)"
+                echo "you're going to resize all $COUNT .$EXT images inside $PWD at a fixed width of ${WIDTH}px"
+                read -p "do you wish to continue? [y/n] " -n 1 -r; echo
+                if [[ ! $REPLY =~ ^[Yy]$ ]]
+                then
+                    exit $USERABORTED
+                else
+                $MOGRIFY -resize $WIDTH *.$EXT
+                exit 0
+                fi
+            ;;
+            -g|--gif)
+                DELAY=$2
+                EXT=$3
+                OUTPUT=$4
+                shift
+                if [[ -z $DELAY || -z $EXT || -z $OUTPUT ]];then
+                    showhelp gif
+                    showerror noargs
+                    exit $E_NOARGS
+                elif [[ -f ${OUTPUT}.gif ]]; then
+                    showerror filexists
+                    exit $E_FILEXISTS
+                fi
+                IMAGES="$(ls -1 *.$EXT 2>/dev/null | wc -l)"
+                if [[ $IMAGES == 0 ]]; then
+                    showerror noimages
+                    exit $E_NOIMAGES
+                fi
+                clear
+                COUNT="$(ls -1 *.$EXT 2>/dev/null | wc -l)"
+                echo "you're going to create a looping gif named ${OUTPUT}.gif"
+                echo "out of all the $COUNT $EXT files inside $PWD with a tick"
+                echo "delay of $DELAY/100 of a second"; echo
+                read -p "do you wish to continue? [y/n] " -n 1 -r; echo
+                if [[ ! $REPLY =~ ^[Yy]$ ]]
+                then
+                    exit $USERABORTED
+                else
+                    $CONVERT -delay $DELAY *.$EXT -loop 0 ${OUTPUT}.gif
+                    exit 0
+                fi
+            ;;
+            *)
+                showerror unknownopt
+                showhelp
+                exit $E_UNKNOWNOPT
+        esac
+        shift
+    done
+fi
diff --git a/bin/hideIt.sh b/bin/hideIt.sh
new file mode 100644 (file)
index 0000000..9c925e2
--- /dev/null
@@ -0,0 +1,686 @@
+#!/usr/bin/env bash
+#
+#   Automagically hide/show a window by its name when the cursor is
+#   within a defined region or you mouse over it.
+#
+#   This script was initially written to imitate gnome-shell's systray
+#   but should be generic enough to do other things as well.
+#
+#   Requirements:
+#      bash, xdotool, xwininfo, xev
+#
+
+# Global variables used throughout the script
+WIN_ID=""
+WIN_NAME=""
+WIN_CLASS=""
+WIN_INSTANCE=""
+WAIT=1
+
+WIN_WIDTH=""
+WIN_HEIGHT=""
+WIN_POSX=""
+WIN_POSY=""
+
+SCREEN_WIDTH=""
+SCREEN_HEIGHT=""
+
+MINX=""
+MINY=""
+MAXX=""
+MAXY=""
+
+HOVER=1
+SIGNAL=1
+INTERVAL=1
+PEEK=3
+DIRECTION="left"
+STEPS=3
+NO_TRANS=1
+TOGGLE=1
+TOGGLE_PEEK=1
+
+_IS_HIDDEN=1
+_DOES_PEEK=0
+_HAS_REGION=1
+_WAIT_PID=""
+_PID_FILE=""
+
+
+usage() {
+    # Print usage
+    printf "usage: $0 [options]\n"
+    printf "\n"
+    printf "Required (At least on):\n"
+    printf " -N, --name [pattern]\n"
+    printf "   Match against the window name.\n"
+    printf "   This is the same string that is displayed in the window titlebar.\n"
+    printf "\n"
+    printf " -C, --class [pattern]\n"
+    printf "   Match against the window class.\n"
+    printf "\n"
+    printf " -I, --instance [pattern]\n"
+    printf "   Match against the window instance.\n"
+    printf "\n"
+    printf " --id [window-id]\n"
+    printf "   Explicitly specify a window id rather than searching for one.\n"
+    printf "\n"
+    printf "Optional:\n"
+    printf " -w, --wait\n"
+    printf "   Wait until a matching window was found.\n"
+    printf "   This will check once every second.\n"
+    printf "\n"
+    printf " -r, --region [posXxposY+offsetX+offsetY]\n"
+    printf "   Cursor region at which to trigger.\n"
+    printf "   Examples:\n"
+    printf "     --region 0x1080+10+-10 (Bottom left incl. a 10 pixel offset)\n"
+    printf "     --region 1920x1080+0+0 (Bottom right without offset)\n"
+    printf "\n"
+    printf " -H, --hover\n"
+    printf "   Show the window when hovering over it.\n"
+    printf "   If --region was defined, --hover will be ignored!\n"
+    printf "   This will only work if --peek is greater 0.\n"
+    printf "   By default, hover is off.\n"
+    printf "\n"
+    printf " -S, --signal\n"
+    printf "   Toggle the visibility by sending a 'SIGUSR1' signal.\n"
+    printf "   Both --region and --hover will be ignored.\n"
+    printf "\n"
+    printf " -i, --interval [interval]\n"
+    printf "   Interval in seconds to check the cursors location.\n"
+    printf "   Defaults to 1.\n"
+    printf "\n"
+    printf " -p, --peek [amount]\n"
+    printf "   When hidden, peek 'amount' of pixels to indicate the window.\n"
+    printf "   Required if --hover is used."
+    printf "   Defaults to 3.\n"
+    printf "\n"
+    printf " -d, --direction [left|right|top|bottom]\n"
+    printf "   direction in which to move the window.\n"
+    printf "   Defaults to left.\n"
+    printf "\n"
+    printf " -s, --steps [amount]\n"
+    printf "   steps in pixel used to move the window. The higher the value,\n"
+    printf "   the faster it will move at the cost of smoothness.\n"
+    printf "   Defaults to 3.\n"
+    printf "\n"
+    printf " -T, --no-trans\n"
+    printf "   Turn of the transition effect.\n"
+    printf "\n"
+    printf " -t, --toggle\n"
+    printf "   Send a SIGUSR1 signal to the process matching the same window.\n"
+    printf "   This will toggle the visibility of the window."
+    printf "\n\n"
+    printf " -P, --toggle-peek\n"
+    printf "   Send a SIGUSR2 signal to the process matching the same window.\n"
+    printf "   This will toggle the hidden state of the window if --peek is greater 0."
+    printf "\n\n"
+    printf "Examples:\n"
+    printf "  Dropdown Terminal:\n"
+    printf "    # Start a terminal with a unique name\n"
+    printf "    # (Make sure yourself it is positioned correctly)\n"
+    printf "    $ termite --title=dropdown-terminal &\n"
+    printf "\n"
+    printf "    # Hide it and wait for a SIGUSR1 signal\n"
+    printf "    $ hideIt.sh --name '^dropdown-terminal$' --direction top --steps 5 --signal\n"
+    printf "\n"
+    printf "    # Send a SIGUSR1 signal (This could be mapped to a keyboard shortcut)\n"
+    printf "    $ hideIt.sh --name '^dropdown-terminal$' --toggle\n"
+}
+
+
+argparse() {
+    # Parse system args
+
+    while [ $# -gt 0 ]; do
+        case $1 in
+            "-N"|"--name")
+                WIN_NAME="$2"
+                shift
+                ;;
+            "-C"|"--class")
+                WIN_CLASS="$2"
+                shift
+                ;;
+            "-I"|"--instance")
+                WIN_INSTANCE="$2"
+                shift
+                ;;
+            "--id")
+                if [[ ! $2 =~ [0-9]+ ]]; then
+                    printf "Invalid window id. Should be a number.\n" 1>&2
+                    exit 1
+                fi
+
+                WIN_ID="$2"
+                shift
+                ;;
+            "-w"|"--wait")
+                WAIT=0
+                ;;
+            "-H"|"--hover")
+                HOVER=0
+                ;;
+            "-S"|"--signal")
+                SIGNAL=0
+                ;;
+            "-r"|"--region")
+                local posX posY offsetX offsetY
+                read posX posY offsetX offsetY <<<$(echo "$2" | \
+                    sed -rn 's/^([0-9]+)x([0-9]+)\+(-?[0-9]+)\+(-?[0-9]+)/\1 \2 \3 \4/p')
+
+                # Test if we have proper values by trying
+                # to add them all together
+                expr $posX + $posY + $offsetX + $offsetY > /dev/null 2>&1
+                if [ $? -ne 0 ]; then
+                    printf "Invalid region. See --help for usage.\n" 1>&2
+                    exit 1
+                fi
+
+                MINX=$posX
+                MAXX=$((${MINX} + ${offsetX}))
+                if [ $MINX -gt $MAXX ]; then
+                    read MINX MAXX <<< "$MAXX $MINX"
+                fi
+
+                MINY=$posY
+                MAXY=$((${MINY} + ${offsetY}))
+                if [ $MINY -gt $MAXY ]; then
+                    read MINY MAXY <<< "$MAXY $MINY"
+                fi
+
+                if [[ ! $MINX =~ [0-9]+ ]] || [[ ! $MINY =~ [0-9]+ ]] \
+                        || [[ ! $MAXY =~ [0-9]+ ]] || [[ ! $MAXY =~ [0-9]+ ]]; then
+                    printf "Missing or invalid region. See --help for usage.\n" 1>&2
+                    exit 1
+                fi
+                _HAS_REGION=0
+                shift
+                ;;
+            "-i"|"--interval")
+                INTERVAL="$2"
+                if [[ ! $INTERVAL =~ [0-9]+ ]]; then
+                    printf "Interval should be a number. " 1>&2
+                    exit 1
+                fi
+                shift
+                ;;
+            "-p"|"--peek")
+                PEEK="$2"
+                if [[ ! $PEEK =~ [0-9]+ ]]; then
+                    printf "Peek should be a number. " 1>&2
+                    exit 1
+                fi
+                shift
+                ;;
+            "-d"|"--direction")
+                DIRECTION="$2"
+                if [[ ! "$DIRECTION" =~ ^(left|right|top|bottom)$ ]]; then
+                    printf "Invalid direction. See --help for usage.\n" 1>&2
+                    exit 1
+                fi
+                shift
+                ;;
+            "-s"|"--steps")
+                STEPS="$2"
+                if [[ ! $STEPS =~ [0-9]+ ]]; then
+                    printf "Steps should be a number. " 1>&2
+                    exit 1
+                fi
+                shift
+                ;;
+            "-T"|"--no-trans")
+                NO_TRANS=0
+                ;;
+            "-t"|"--toggle")
+                TOGGLE=0
+                ;;
+            "-P"|"--toggle-peek")
+                TOGGLE_PEEK=0
+                ;;
+            "-h"|"--help")
+                usage
+                exit 0
+                ;;
+            **)
+                printf "Didn't understand '$1'\n" 1>&2
+                printf "See --help for usage.\n"
+                exit 1
+                ;;
+        esac
+        shift
+    done
+
+    # Check required arguments
+    local _names="${WIN_ID}${WIN_NAME}${WIN_CLASS}${WIN_INSTANCE}"
+    if [ -z "$_names" ] && [ -z "$WIN_ID" ]; then
+        printf "At least one of --name, --class, --instance or --id" 1>&2
+        printf " is required!\n" 1>&2
+        exit 1
+    fi
+
+    if [ $TOGGLE -ne 0 ] && [ $TOGGLE_PEEK -ne 0 ] && [ $SIGNAL -ne 0 ] \
+            && [ $_HAS_REGION -ne 0 ] && [ $HOVER -ne 0 ]; then
+        printf "At least one of --toggle, --signal, --hover or" 1>&2
+        printf " --region is required!\n" 1>&2
+        exit 1
+    fi
+}
+
+
+function fetch_window_id() {
+    # Sets the values for the following global
+    #   WIN_ID
+
+    # We already have a window id
+    if [ ! -z "$WIN_ID" ]; then
+        _PID_FILE="/tmp/hideIt-${WIN_ID}.pid"
+        return
+    fi
+
+    local _id=-1
+
+    # Search all windows matching the provided class
+    local _tmp1=()
+    if [ ! -z "$WIN_CLASS" ]; then
+        _tmp1=($(xdotool search --class "$WIN_CLASS"))
+        _tmp1=${_tmp1:--1}
+    fi
+
+    # Search all windows matching the provided instance
+    local _tmp2=()
+    if [ ! -z "$WIN_INSTANCE" ]; then
+        _tmp2=($(xdotool search --classname "$WIN_INSTANCE"))
+        _tmp2=${_tmp2:--1}
+    fi
+
+    # Search all windows matching the provided name (title)
+    local _tmp3=()
+    if [ ! -z "$WIN_NAME" ]; then
+        _tmp3=($(xdotool search --name "$WIN_NAME"))
+        _tmp3=${_tmp3:--1}
+    fi
+
+    # Shift values upwards
+    for i in {1..2}; do
+        if [ -z $_tmp1 ]; then
+            _tmp1=(${_tmp2[@]})
+            _tmp2=()
+        fi
+
+        if [ -z $_tmp2 ]; then
+            _tmp2=(${_tmp3[@]})
+            _tmp3=()
+        fi
+    done
+
+    if [ -z $_tmp2 ]; then
+        # We only have one list of ids so we pick the first one from it
+        _id=${_tmp1[0]}
+    else
+        # We have multiple lists so we have to find the id that appears
+        # in all of them
+        local _oldIFS=$IFS
+        IFS=$'\n\t'
+
+        local _ids=($(comm -12 \
+            <(echo "${_tmp1[*]}" | sort) \
+            <(echo "${_tmp2[*]}" | sort)))
+
+        if [ ! -z $_tmp3 ]; then
+            _ids=($(comm -12 \
+                <(echo "${_tmp3[*]}" | sort) \
+                <(echo "${_ids[*]}" | sort)))
+        fi
+        IFS=$_oldIFS
+
+        _id=${_ids[0]}
+    fi
+
+    if [[ $_id =~ [0-9]+ ]] && [ $_id -gt 0 ]; then
+        WIN_ID=$_id
+        _PID_FILE="/tmp/hideIt-${WIN_ID}.pid"
+    fi
+}
+
+
+function fetch_screen_dimensions() {
+    # Sets the values for the following globals
+    #    SCREEN_WIDTH, SCREEN_HEIGHT
+
+    local win_info=$(xwininfo -root)
+    SCREEN_WIDTH=$(echo "$win_info" | sed -rn 's/.*Width: +([0-9]+)/\1/p')
+    SCREEN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
+}
+
+
+function fetch_window_dimensions() {
+    # Sets the values for the following globals unless no WIN_ID exists
+    #    WIN_WIDTH, WIN_HEIGHT, WIN_POSX, WIN_POSY
+
+    if [[ ! $WIN_ID =~ [0-9]+ ]]; then
+        return
+    fi
+
+    local win_info=$(xwininfo -id $WIN_ID)
+
+    WIN_WIDTH=$(echo "$win_info" | sed -rn 's/.*Width: +([0-9]+)/\1/p')
+    WIN_HEIGHT=$(echo "$win_info" | sed -rn 's/.*Height: +([0-9]+)/\1/p')
+
+    if [ ! -z "$1" ] && [ $1 -eq 0 ]; then
+        WIN_POSX=$(echo "$win_info" | \
+            sed -rn 's/.*Absolute upper-left X: +(-?[0-9]+)/\1/p')
+        WIN_POSY=$(echo "$win_info" | \
+            sed -rn 's/.*Absolute upper-left Y: +(-?[0-9]+)/\1/p')
+    fi
+}
+
+
+function send_signal() {
+    # Send a SIGUSR1 to an active hideIt.sh instance
+    # if a pid file was found.
+    local signal=$1
+    if [ ! -f "$_PID_FILE" ]; then
+        printf "Pid file at \"${_PID_FILE}\" doesn't exist!\n" 1>&2
+        exit 1
+    fi
+
+    local _pid=`cat $_PID_FILE`
+    printf "Sending ${signal} to instance...\n"
+
+    if [[ $_pid =~ [0-9]+ ]]; then
+        kill -${signal} $_pid
+        exit 0
+    else
+        printf "Invalid pid in \"${_PID_FILE}\".\n" 1>&2
+        exit 1
+    fi
+}
+
+
+function hide_window() {
+    # Move the window in or out
+    # Args:
+    #     hide: 0 to hide, 1 to show
+
+    local hide=$1
+
+    # Make sure window still exists and exit if not.
+    xwininfo -id $WIN_ID &> /dev/null
+    if [ $? -ne 0 ]; then
+        printf "Window doesn't exist anymore, exiting!\n"
+        exit 0
+    fi
+
+    _IS_HIDDEN=$hide
+
+    # Update WIN_WIDTH, WIN_HEIGHT in case they changed
+    fetch_window_dimensions
+
+    # Activate the window.
+    # Should bring it to the front, change workspace etc.
+    if [ $hide -ne 0 ]; then
+        xdotool windowactivate $WIN_ID > /dev/null 2>&1
+    fi
+
+    # Generate the sequence used to move the window
+    local to=()
+    local sequence=()
+    if [ "$DIRECTION" == "left" ]; then
+        to=-$(($WIN_WIDTH - $PEEK))
+        if [ $hide -eq 0 ]; then
+            sequence=($(seq $WIN_POSX -$STEPS $to))
+            sequence+=($to)
+        else
+            sequence=($(seq $to $STEPS $WIN_POSX))
+            sequence+=($WIN_POSX)
+        fi
+
+    elif [ "$DIRECTION" == "right" ]; then
+        to=$(($SCREEN_WIDTH - $PEEK))
+        if [ $hide -eq 0 ]; then
+            sequence=($(seq $WIN_POSX $STEPS $to))
+            sequence+=($to)
+        else
+            sequence=($(seq $to -$STEPS $WIN_POSX))
+            sequence+=($WIN_POSX)
+        fi
+
+    elif [ "$DIRECTION" == "bottom" ]; then
+        to=$(($SCREEN_HEIGHT - $PEEK))
+        if [ $hide -eq 0 ]; then
+            sequence=($(seq $WIN_POSY $STEPS $to))
+            sequence+=($to)
+        else
+            sequence=($(seq $to -$STEPS $WIN_POSY))
+            sequence+=($WIN_POSY)
+        fi
+
+    elif [ "$DIRECTION" == "top" ]; then
+        to=-$(($WIN_HEIGHT - $PEEK))
+        if [ $hide -eq 0 ]; then
+            sequence=($(seq $WIN_POSY -$STEPS $to))
+            sequence+=($to)
+        else
+            sequence=($(seq $to $STEPS $WIN_POSY))
+            sequence+=($WIN_POSY)
+        fi
+    fi
+
+    # Actually move the window
+    if [ $NO_TRANS -ne 0 ]; then
+        for pos in ${sequence[@]}; do
+            if [[ "$DIRECTION" =~ ^(left|right)$ ]]; then
+                xdotool windowmove $WIN_ID $pos $WIN_POSY
+            elif [[ "$DIRECTION" =~ ^(top|bottom)$ ]]; then
+                xdotool windowmove $WIN_ID $WIN_POSX $pos
+            fi
+        done
+    else
+        pos=${sequence[-1]}
+        if [[ "$DIRECTION" =~ ^(left|right)$ ]]; then
+            xdotool windowmove $WIN_ID $pos $WIN_POSY
+        elif [[ "$DIRECTION" =~ ^(top|bottom)$ ]]; then
+            xdotool windowmove $WIN_ID $WIN_POSX $pos
+        fi
+    fi
+
+    # In case we hid the window, try to give focus to whatever is
+    # underneath the cursor.
+    if [ $hide -eq 0 ]; then
+        eval $(xdotool getmouselocation --shell)
+        xdotool windowactivate $WINDOW > /dev/null 2>&1
+    fi
+}
+
+
+function toggle() {
+    # Toggle the hidden state of the window
+
+    if [ $_IS_HIDDEN -eq 0 ]; then
+        hide_window 1
+    else
+        hide_window 0
+    fi
+}
+
+function toggle_peek() {
+    # Completely hide/unhide the window in case PEEK is greater 0
+
+    if [ $PEEK -eq 0 ]; then
+        return
+    fi
+
+    local _peek=$PEEK
+    local _win_posx=$WIN_POSX
+    local _win_posy=$WIN_POSY
+
+    fetch_window_dimensions 0
+
+    if [ $_DOES_PEEK -eq 0 ]; then
+        _DOES_PEEK=1
+        PEEK=0
+    else
+        _DOES_PEEK=0
+    fi
+
+    hide_window 0
+
+    PEEK=$_peek
+    WIN_POSX=$_win_posx
+    WIN_POSY=$_win_posy
+}
+
+function serve_region() {
+    # Check the cursors location and act accordingly
+
+    local _hide=0
+    while true; do
+        if [ $_DOES_PEEK -eq 0 ]; then
+            # Get cursor x, y position and active window
+            eval $(xdotool getmouselocation --shell)
+
+            # Test if the cursor is within the region
+            if [ $X -ge $MINX -a $X -le $MAXX ] \
+                    && [ $Y -ge $MINY -a $Y -le $MAXY ]; then
+                _hide=1
+            else
+                _hide=0
+            fi
+
+            # Don't hide if the cursor is still above the window
+            if [ $_IS_HIDDEN -ne 0 ] \
+                    && [ $_hide -eq 0 ] \
+                    && [ $WINDOW -eq $WIN_ID ]; then
+                _hide=1
+            fi
+
+            # Only do something if necessary
+            if [ $_IS_HIDDEN -ne $_hide ]; then
+                hide_window $_hide
+            fi
+        fi
+
+        # Cut some slack
+        sleep $INTERVAL
+    done
+}
+
+
+function serve_xev() {
+    # Wait for cursor "Enter" and "Leave" events reported by
+    # xev and act accordingly
+
+    xev -id $WIN_ID -event mouse | while read line; do
+        if [[ "$line" =~ ^EnterNotify.* ]]; then
+            hide_window 1
+        elif [[ "$line" =~ ^LeaveNotify.* ]]; then
+            hide_window 0
+        fi
+    done
+}
+
+
+function restore() {
+    # Called by trap once we receive an EXIT
+
+    if [ -n "$_WAIT_PID" ]; then
+        kill -- "-${_WAIT_PID}"
+    fi
+
+    if [ -f "$_PID_FILE" ]; then
+        rm "$_PID_FILE"
+    fi
+
+    if [ $_IS_HIDDEN -eq 0 ]; then
+        printf "Restoring original window position...\n"
+        hide_window 1
+    fi
+
+    exit 0
+}
+
+
+function main() {
+    # Entry point for hideIt
+
+    # Parse all the args!
+    argparse "$@"
+
+    printf "Searching window...\n"
+    fetch_window_id
+
+    # If enabled, wait until a window was found.
+    if [ $WAIT -eq 0 ] && [[ ! $WIN_ID =~ [0-9]+ ]]; then
+        printf "Waiting for window"
+        while [[ ! $WIN_ID =~ [0-9]+ ]]; do
+            printf "."
+            fetch_window_id
+            sleep 1
+        done
+        printf "\n"
+    fi
+
+    if [[ ! $WIN_ID =~ [0-9]+ ]]; then
+        printf "No window found!\n" 1>&2
+        exit 1
+    else
+        printf "Found window with id: $WIN_ID\n"
+    fi
+
+    if [ $TOGGLE -eq 0 ]; then
+        send_signal SIGUSR1
+        exit 0
+    fi
+
+    if [ $TOGGLE_PEEK -eq 0 ]; then
+        send_signal SIGUSR2
+        exit 0
+    fi
+
+    printf "Fetching window dimensions...\n"
+    fetch_window_dimensions 0
+
+    printf "Fetching screen dimensions...\n"
+    fetch_screen_dimensions
+
+    trap restore EXIT
+
+    printf "Initially hiding window...\n"
+    hide_window 0
+
+    # Save our pid into a file
+    echo "$$" > /tmp/hideIt-${WIN_ID}.pid
+    trap toggle_peek SIGUSR2
+
+    # Start observing
+    if [ $_HAS_REGION -eq 0 ]; then
+        printf "Defined region:\n"
+        printf "  X: $MINX $MAXX\n"
+        printf "  Y: $MINY $MAXY\n"
+        printf "\n"
+        printf "Waiting for region...\n"
+        serve_region &
+        _WAIT_PID=$!
+    elif [ $SIGNAL -eq 0 ]; then
+        printf "Waiting for SIGUSR1...\n"
+        trap toggle SIGUSR1
+        sleep infinity &
+        _WAIT_PID=$!
+    elif [ $HOVER -eq 0 ]; then
+        printf "Waiting for HOVER...\n"
+        serve_xev &
+        _WAIT_PID=$!
+    fi
+
+    if [ -n "$_WAIT_PID" ]; then
+        while true; do
+            wait "$_WAIT_PID"
+            printf "Received signal...\n"
+        done
+    fi
+}
+
+# Lets do disss!
+set -m
+main "$@"
diff --git a/bin/hidebars.sh b/bin/hidebars.sh
new file mode 100644 (file)
index 0000000..fe3a494
--- /dev/null
@@ -0,0 +1,10 @@
+#! /bin/bash
+
+# kill all previous instances of hideIt
+kill $(cat /tmp/hideIt-*.pid)
+
+#hide bars
+hideIt.sh --name "^polybar-top_VGA-1$" --hover --peek 3 --direction top --steps 25 & disown
+hideIt.sh --name "^polybar-bottom_VGA-1$" --hover --peek 3 --direction bottom --steps 25 & disown
+hideIt.sh --name "^stalonetray$" --region 0x120+0+300 --peek 3 --direction left --steps 25 & disown
+
index 0ad7e9c6773a56e2043147578dcf0f4fda0adaa1..4e393c7db6684c28d745fe2f95004ed0b17b5a0a 100644 (file)
-#! /bin/bash
+#!/usr/bin/env bash
+# Author: Dolores Portalatin <hello@doloresportalatin.info>
+# Dependencies: imagemagick, i3lock-color-git, scrot, wmctrl (optional)
+set -o errexit -o noclobber -o nounset
 
-CACHE=$HOME/.cache/i3lockblur
-TMPBG=$CACHE/screen.png
-NOW=$(date +'%d %b %Y')
-FACE=~/.face
-USER=$CACHE/face.png
-RES=$(xrandr | grep 'current' | sed -E 's/.*current\s([0-9]+)\sx\s([0-9]+).*/\1x\2/')
+hue=(-level "0%,100%,0.6")
+effect=(-filter Gaussian -resize 20% -define "filter:sigma=1.5" -resize 500.5%)
+# default system sans-serif font
+font=$(magick convert -list font | awk "{ a[NR] = \$2 } /family: $(fc-match sans -f "%{family}\n")/ { print a[NR-1]; exit }")
+image=$(mktemp --suffix=.png)
+shot=(import -silent -window root)
+desktop=""
+i3lock_cmd=(i3lock -i "$image")
+shot_custom=false
 
-if [[ ! -d $CACHE ]]; then
-       mkdir -p $CACHE
+options="Options:
+    -h, --help       This help menu.
+
+    -d, --desktop    Attempt to minimize all windows before locking.
+
+    -g, --greyscale  Set background to greyscale instead of color.
+
+    -p, --pixelate   Pixelate the background instead of blur, runs faster.
+
+    -f <fontname>, --font <fontname>  Set a custom font.
+
+    -t <text>, --text <text> Set a custom text prompt.
+
+    -l, --listfonts  Display a list of possible fonts for use with -f/--font.
+                     Note: this option will not lock the screen, it displays
+                     the list and exits immediately.
+
+    -n, --nofork     Do not fork i3lock after starting.
+
+    --               Must be last option. Set command to use for taking a
+                     screenshot. Default is 'import -window root'. Using 'scrot'
+                     or 'maim' will increase script speed and allow setting
+                     custom flags like having a delay."
+
+# move pipefail down as for some reason "convert -list font" returns 1
+set -o pipefail
+trap 'rm -f "$image"' EXIT
+temp="$(getopt -o :hdnpglt:f: -l desktop,help,listfonts,nofork,pixelate,greyscale,text:,font: --name "$0" -- "$@")"
+eval set -- "$temp"
+
+# l10n support
+case "${LANG:-}" in
+    af_* ) text="Tik wagwoord om te ontsluit" ;; # Afrikaans
+    cs_* ) text="Pro odemčení zadajte heslo" ;; # Czech
+    de_* ) text="Bitte Passwort eingeben" ;; # Deutsch
+    da_* ) text="Indtast adgangskode" ;; # Danish
+    en_* ) text="Type password to unlock" ;; # English
+    es_* ) text="Ingrese su contraseña" ;; # Española
+    fr_* ) text="Entrez votre mot de passe" ;; # Français
+    he_* ) text="הקלד סיסמה לביטול הנעילה" ;; # Hebrew עברית
+    hi_* ) text="अनलॉक करने के लिए पासवर्ड टाईप करें" ;; #Hindi
+    id_* ) text="Masukkan kata sandi Anda" ;; # Bahasa Indonesia
+    it_* ) text="La sai?" ;; # Italian
+    ja_* ) text="パスワードを入力してください" ;; # Japanese
+    lv_* ) text="Ievadi paroli" ;; # Latvian
+    nb_* ) text="Skriv inn passord" ;; # Norwegian
+    pl_* ) text="Podaj hasło" ;; # Polish
+    pt_* ) text="Digite a senha para desbloquear" ;; # Português
+    sk_* ) text="Pre odomknutie zadajte heslo" ;; # Slovak
+    tr_* ) text="Giriş yapmak için şifrenizi girin" ;; # Turkish
+    ru_* ) text="Введите пароль" ;; # Russian
+    zh_* ) text="请输入密码以解锁" ;; # Chinese
+    * ) text="Type password to unlock" ;; # Default to English
+esac
+
+while true ; do
+    case "$1" in
+        -h|--help)
+            printf "Usage: %s [options]\n\n%s\n\n" "${0##*/}" "$options"; exit 1 ;;
+        -d|--desktop) desktop=$(command -V wmctrl) ; shift ;;
+        -g|--greyscale) hue=(-level "0%,100%,0.6" -set colorspace Gray -average) ; shift ;;
+        -p|--pixelate) effect=(-scale 10% -scale 1000%) ; shift ;;
+        -f|--font)
+            case "$2" in
+                "") shift 2 ;;
+                *) font=$2 ; shift 2 ;;
+            esac ;;
+        -t|--text) text=$2 ; shift 2 ;;
+        -l|--listfonts)
+           magick convert -list font | awk -F: '/Font: / { print $2 }' | sort -du | command -- ${PAGER:-less}
+           exit 0 ;;
+       -n|--nofork) i3lock_cmd+=(--nofork) ; shift ;;
+        --) shift; shot_custom=true; break ;;
+        *) echo "error" ; exit 1 ;;
+    esac
+done
+
+if "$shot_custom" && [[ $# -gt 0 ]]; then
+    shot=("$@");
+fi
+
+command -- "${shot[@]}" "$image"
+
+value="60" #brightness value to compare to
+
+color=$(magick convert "$image" -gravity center -crop 100x100+0+0 +repage -colorspace hsb \
+    -resize 1x1 txt:- | awk -F '[%$]' 'NR==2{gsub(",",""); printf "%.0f\n", $(NF-1)}');
+
+if [[ $color -gt $value ]]; then #white background image and black text
+    bw="black"
+#    icon="/usr/share/i3lock-fancy/icons/lockdark.png"
+    icon="/home/danix/.round.face"
+    param=("--inside-color=0000001c" "--ring-color=0000003e" \
+        "--line-color=00000000" "--keyhl-color=0000ff80" "--ringver-color=ffffff00" \
+        "--separator-color=22222260" "--insidever-color=ffffff1c" \
+        "--ringwrong-color=ffffff55" "--insidewrong-color=ffffff1c" \
+        "--verif-color=ffffff00" "--wrong-color=ff000000" "--time-color=ffffff00" \
+        "--date-color=ffffff00" "--layout-color=ffffff00")
+else #black
+    bw="white"
+#    icon="/usr/share/i3lock-fancy/icons/lock.png"
+    icon="/home/danix/.round.face"
+    param=("--inside-color=ffffff1c" "--ring-color=ffffff3e" \
+        "--line-color=ffffff00" "--keyhl-color=0000ff80" "--ringver-color=00000000" \
+        "--separator-color=22222260" "--insidever-color=0000001c" \
+        "--ringwrong-color=00000055" "--insidewrong-color=0000001c" \
+        "--verif-color=00000000" "--wrong-color=ff000000" "--time-color=00000000" \
+        "--date-color=00000000" "--layout-color=00000000")
+fi
+
+magick convert "$image" "${hue[@]}" "${effect[@]}" -font "$font" -pointsize 26 -fill "$bw" -gravity center \
+    -annotate +0+160 "$text" "$icon" -gravity center -composite "$image"
+
+# If invoked with -d/--desktop, we'll attempt to minimize all windows (ie. show
+# the desktop) before locking.
+${desktop} ${desktop:+-k on}
+
+# try to use i3lock with prepared parameters
+if ! "${i3lock_cmd[@]}" "${param[@]}" >/dev/null 2>&1; then
+    # We have failed, lets get back to stock one
+    "${i3lock_cmd[@]}"
 fi
 
-convert $FACE -resize 100x100 -alpha set \( \
-       +clone -distort DePolar 0 -virtual-pixel HorizontalTile \
-       -background None -distort Polar 0\
-       \) -compose Dst_In -composite -trim +repage $USER
-
-ffmpeg -f x11grab -video_size $RES -y -i $DISPLAY -i $USER \
-       -filter_complex "boxblur=7:15,overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" \
-       -vframes 1 $TMPBG -loglevel quiet
-
-slowfade () {
-    dis=$(echo -n "$DISPLAY" | tr -c '[:alnum:]' _)
-    ifc='com.github.chjj.compton'
-    obj='/com/github/chjj/compton'
-    if [[ "$1" == "start" ]]; then
-        dbus-send --print-reply --dest=$ifc.$dis \
-            $obj $ifc.opts_set string:fade_in_step double:0.02
-        dbus-send --print-reply --dest=$ifc.$dis \
-            $obj $ifc.opts_set string:fade_out_step double:0.02
-    else
-        dbus-send --print-reply --dest=$ifc.$dis \
-            $obj $ifc.opts_set string:fade_in_step double:0.1
-        dbus-send --print-reply --dest=$ifc.$dis \
-            $obj $ifc.opts_set string:fade_out_step double:0.1
-    fi
-}
-
-FG_COLOR=fefefeff #fefefeff
-RING_COLOR=31313aff #31313aff
-WRONG_COLOR=f82a11aa #f82a11aa
-HLIGHT_COLOR=ffbf00ff #ffbf00ff
-VERIF_COLOR=fefefe66 #fefefe66
-
-slowfade start
-i3lock -n --force-clock -i $TMPBG \
-       --indpos="w/2:h/2" --timepos="w/2:h/2-170" --datepos="w/2:h/2-100" --greeterpos="w/2:h/2-70" \
-       --insidevercolor=$VERIF_COLOR --insidewrongcolor=$WRONG_COLOR --insidecolor=fefefe00 \
-       --ringvercolor=$VERIF_COLOR --ringwrongcolor=$WRONG_COLOR --ringcolor=$RING_COLOR \
-       --keyhlcolor=$HLIGHT_COLOR --bshlcolor=$HLIGHT_COLOR --separatorcolor=00000000 \
-       --datecolor=$FG_COLOR --timecolor=$FG_COLOR --greetercolor=$FG_COLOR \
-       --timestr="%H" --timesize=70 \
-       --datestr="%M" --datesize=70 \
-       --greetertext="$NOW" --greetersize=25\
-       --line-uses-inside --radius 50 --ring-width 2 --indicator \
-       --veriftext=""  --wrongtext="" --noinputtext="" \
-       --clock --date-font="Roboto" --time-font="Roboto"
-sleep 1
-slowfade end
+# As above, if we were passed -d/--desktop, we'll attempt to restore all windows
+# after unlocking.
+${desktop} ${desktop:+-k off}
index 373ff43b52145ce6b48038f24c68174fc3c485f9..410cc076a64f3abbf96f720720639e96e88bbf4d 100644 (file)
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-i3lock-blur &
+i3lock-fancy &
 sleep 3
 dbus-send --system --print-reply --dest="org.freedesktop.UPower" /org/freedesktop/UPower org.freedesktop.UPower.Suspend
 exit
diff --git a/bin/info-airqualityindex.sh b/bin/info-airqualityindex.sh
new file mode 100644 (file)
index 0000000..3aebddf
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+TOKEN="78eaad275bf877526d8888ea01e18adcddc0b85d"
+CITY="Verona"
+
+API="https://api.waqi.info/feed"
+
+if [ -n "$CITY" ]; then
+    aqi=$(curl -sf "$API/$CITY/?token=$TOKEN")
+else
+    location=$(curl -sf https://location.services.mozilla.com/v1/geolocate?key=geoclue)
+
+    if [ -n "$location" ]; then
+        location_lat="$(echo "$location" | jq '.location.lat')"
+        location_lon="$(echo "$location" | jq '.location.lng')"
+
+        aqi=$(curl -sf "$API/geo:$location_lat;$location_lon/?token=$TOKEN")
+    fi
+fi
+
+if [ -n "$aqi" ]; then
+    if [ "$(echo "$aqi" | jq -r '.status')" = "ok" ]; then
+        aqi=$(echo "$aqi" | jq '.data.aqi')
+
+        if [ "$aqi" -lt 50 ]; then
+            echo "%{F#009966}󰌪 %{F-} $aqi"
+        elif [ "$aqi" -lt 100 ]; then
+            echo "%{F#ffde33}󰌪 %{F-} $aqi"
+        elif [ "$aqi" -lt 150 ]; then
+            echo "%{F#ff9933}󰌪 %{F-} $aqi"
+        elif [ "$aqi" -lt 200 ]; then
+            echo "%{F#cc0033}󰌪 %{F-} $aqi"
+        elif [ "$aqi" -lt 300 ]; then
+            echo "%{F#660099}󰌪 %{F-} $aqi"
+        else
+            echo "%{F#7e0023}󰌪 %{F-} $aqi"
+        fi
+    else
+        echo "$aqi" | jq -r '.data'
+    fi
+fi
diff --git a/bin/lightsOn.sh b/bin/lightsOn.sh
new file mode 100644 (file)
index 0000000..89fed42
--- /dev/null
@@ -0,0 +1,240 @@
+#!/bin/bash
+# lightsOn.sh
+
+# Copyright (c) 2013 iye.cba at gmail com
+# url: https://github.com/iye/lightsOn
+# This script is licensed under GNU GPL version 2.0 or above
+
+# Description: Bash script that prevents the screensaver and display power
+# management (DPMS) to be activated when you are watching Flash Videos
+# fullscreen on Firefox and Chromium.
+# Can detect mplayer, minitube, and VLC when they are fullscreen too.
+# Also, screensaver can be prevented when certain specified programs are running.
+# lightsOn.sh needs xscreensaver or kscreensaver to work.
+
+
+# HOW TO USE: Start the script with the number of seconds you want the checks
+# for fullscreen to be done. Example:
+# "./lightsOn.sh 120 &" will Check every 120 seconds if Mplayer, Minitube
+# VLC, Firefox or Chromium are fullscreen and delay screensaver and Power Management if so.
+# You want the number of seconds to be ~10 seconds less than the time it takes
+# your screensaver or Power Management to activate.
+# If you don't pass an argument, the checks are done every 50 seconds.
+#
+# An optional array variable exists here to add the names of programs that will delay the screensaver if they're running.
+# This can be useful if you want to maintain a view of the program from a distance, like a music playlist for DJing,
+# or if the screensaver eats up CPU that chops into any background processes you have running,
+# such as realtime music programs like Ardour in MIDI keyboard mode.
+# If you use this feature, make sure you use the name of the binary of the program (which may exist, for instance, in /usr/bin).
+
+
+# Modify these variables if you want this script to detect if Mplayer,
+# VLC, Minitube, or Firefox or Chromium Flash Video are Fullscreen and disable
+# xscreensaver/kscreensaver and PowerManagement.
+mplayer_detection=1
+vlc_detection=0
+firefox_flash_detection=1
+chromium_flash_detection=0
+minitube_detection=0
+
+# Names of programs which, when running, you wish to delay the screensaver.
+delay_progs=('duckstation-qt') # For example ('ardour2' 'gmpc')
+
+
+# YOU SHOULD NOT NEED TO MODIFY ANYTHING BELOW THIS LINE
+
+
+# enumerate all the attached screens
+displays=""
+while read id
+do
+    displays="$displays $id"
+done < <(xvinfo | sed -n 's/^screen #\([0-9]\+\)$/\1/p')
+
+
+# Detect screensaver been used (xscreensaver, kscreensaver or none)
+screensaver=`pgrep -l xscreensaver | grep -wc xscreensaver`
+if [ $screensaver -ge 1 ]; then
+    screensaver=xscreensaver
+else
+    screensaver=`pgrep -l kscreensaver | grep -wc kscreensaver`
+    if [ $screensaver -ge 1 ]; then
+        screensaver=kscreensaver
+    else
+        screensaver=None
+        echo "No screensaver detected"
+    fi
+fi
+
+checkDelayProgs()
+{
+    for prog in "${delay_progs[@]}"; do
+        if [ `pgrep -lfc "$prog"` -ge 1 ]; then
+            notify-send "screensaver delayed because \"$prog\" is running..."
+            echo "Delaying the screensaver because a program on the delay list, \"$prog\", is running..."
+            delayScreensaver
+            break
+        fi
+    done
+}
+
+checkFullscreen()
+{
+    # loop through every display looking for a fullscreen window
+    for display in $displays
+    do
+        #get id of active window and clean output
+        activ_win_id=`DISPLAY=:0.${display} xprop -root _NET_ACTIVE_WINDOW`
+        #activ_win_id=${activ_win_id#*# } #gives error if xprop returns extra ", 0x0" (happens on some distros)
+        activ_win_id=${activ_win_id:40:9}
+
+        # Skip invalid window ids (commented as I could not reproduce a case
+        # where invalid id was returned, plus if id invalid
+        # isActivWinFullscreen will fail anyway.)
+        #if [ "$activ_win_id" = "0x0" ]; then
+        #     continue
+        #fi
+
+        # Check if Active Window (the foremost window) is in fullscreen state
+        isActivWinFullscreen=`DISPLAY=:0.${display} xprop -id $activ_win_id | grep _NET_WM_STATE_FULLSCREEN`
+            if [[ "$isActivWinFullscreen" = *NET_WM_STATE_FULLSCREEN* ]];then
+                isAppRunning
+                var=$?
+                if [[ $var -eq 1 ]];then
+                    delayScreensaver
+                fi
+            fi
+    done
+}
+
+
+
+
+
+# check if active windows is mplayer, vlc or firefox
+#TODO only window name in the variable activ_win_id, not whole line.
+#Then change IFs to detect more specifically the apps "<vlc>" and if process name exist
+
+isAppRunning()
+{
+    #Get title of active window
+    activ_win_title=`xprop -id $activ_win_id | grep "WM_CLASS(STRING)"`   # I used WM_NAME(STRING) before, WM_CLASS more accurate.
+
+
+
+    # Check if user want to detect Video fullscreen on Firefox, modify variable firefox_flash_detection if you dont want Firefox detection
+    if [ $firefox_flash_detection == 1 ];then
+        if [[ "$activ_win_title" = *unknown* || "$activ_win_title" = *plugin-container* ]];then
+        # Check if plugin-container process is running
+            flash_process=`pgrep -l plugin-containe | grep -wc plugin-containe`
+            #(why was I using this line avobe? delete if pgrep -lc works ok)
+            #flash_process=`pgrep -lc plugin-containe`
+            if [[ $flash_process -ge 1 ]];then
+                return 1
+            fi
+        fi
+    fi
+
+
+    # Check if user want to detect Video fullscreen on Chromium, modify variable chromium_flash_detection if you dont want Chromium detection
+    if [ $chromium_flash_detection == 1 ];then
+        if [[ "$activ_win_title" = *exe* ]];then
+        # Check if Chromium/Chrome Flash process is running
+            flash_process=`pgrep -lfc ".*((c|C)hrome|chromium).*flashp.*"`
+            if [[ $flash_process -ge 1 ]];then
+                return 1
+            fi
+        fi
+    fi
+
+
+    #check if user want to detect mplayer fullscreen, modify variable mplayer_detection
+    if [ $mplayer_detection == 1 ];then
+        if [[ "$activ_win_title" = *mplayer* || "$activ_win_title" = *MPlayer* ]];then
+            #check if mplayer is running.
+            #mplayer_process=`pgrep -l mplayer | grep -wc mplayer`
+            mplayer_process=`pgrep -lc mplayer`
+            if [ $mplayer_process -ge 1 ]; then
+                return 1
+            fi
+        fi
+    fi
+
+
+    # Check if user want to detect vlc fullscreen, modify variable vlc_detection
+    if [ $vlc_detection == 1 ];then
+        if [[ "$activ_win_title" = *vlc* ]];then
+            #check if vlc is running.
+            #vlc_process=`pgrep -l vlc | grep -wc vlc`
+            vlc_process=`pgrep -lc vlc`
+            if [ $vlc_process -ge 1 ]; then
+                return 1
+            fi
+        fi
+    fi
+
+    # Check if user want to detect minitube fullscreen, modify variable minitube_detection
+    if [ $minitube_detection == 1 ];then
+        if [[ "$activ_win_title" = *minitube* ]];then
+            #check if minitube is running.
+            #minitube_process=`pgrep -l minitube | grep -wc minitube`
+            minitube_process=`pgrep -lc minitube`
+            if [ $minitube_process -ge 1 ]; then
+                return 1
+            fi
+        fi
+    fi
+
+return 0
+}
+
+
+delayScreensaver()
+{
+
+    # reset inactivity time counter so screensaver is not started
+    if [ "$screensaver" == "xscreensaver" ]; then
+        xscreensaver-command -deactivate > /dev/null
+    elif [ "$screensaver" == "kscreensaver" ]; then
+        qdbus org.freedesktop.ScreenSaver /ScreenSaver SimulateUserActivity > /dev/null
+    fi
+
+
+    #Check if DPMS is on. If it is, deactivate and reactivate again. If it is not, do nothing.
+    dpmsStatus=`xset -q | grep -ce 'DPMS is Enabled'`
+    if [ $dpmsStatus == 1 ];then
+            xset -dpms
+            xset dpms
+    fi
+
+}
+
+
+
+delay=$1
+
+
+# If argument empty, use 50 seconds as default.
+if [ -z "$1" ];then
+    delay=50
+fi
+
+
+# If argument is not integer quit.
+if [[ $1 = *[^0-9]* ]]; then
+    echo "The Argument \"$1\" is not valid, not an integer"
+    echo "Please use the time in seconds you want the checks to repeat."
+    echo "You want it to be ~10 seconds less than the time it takes your screensaver or DPMS to activate"
+    exit 1
+fi
+
+
+while true
+do
+    checkDelayProgs
+    checkFullscreen
+    sleep $delay
+done
+
+
+exit 0
diff --git a/bin/maiumin b/bin/maiumin
new file mode 100644 (file)
index 0000000..3ff920d
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+if [ $# -lt 1 ]; then
+   echo " Uso: $0 percorso/nome-directory"
+   exit 1
+fi
+DIRIN="$PWD"
+DIRTOLOWER="$1"
+cd $DIRTOLOWER
+for MAIU in *
+  do
+     MINU=`echo $MAIU | tr 'A-Z' 'a-z'`
+     if [ "$MAIU" != "$MINU" ]; then
+        mv "$MAIU" "$MINU"
+     fi
+  done
+cd $DIRIN
+
diff --git a/bin/mkpass b/bin/mkpass
new file mode 100644 (file)
index 0000000..b687d1f
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/bash
+#  Su macchine un po' vecchie, 
+#+ potrebbe essere necessario cambiare l'intestazione in #!/bin/bash2.
+#
+#  Generatore di password casuali per Bash 2.x +
+#+ di Antek Sawicki <tenox@tenox.tc>,
+#+ che ha generosamente permesso all'autore de Guida ASB il suo utilizzo.
+#
+# ==> Commenti aggiunti dall'autore del libro ==>
+
+
+MATRICE='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?!.,-_$()^%&+"*'
+#MATRICE="abcdefghijklmnopqrstuvwxyz"
+#MATRICE="0123456789"
+#MATRICE="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+# ==> La password viene formata con caratteri alfanumerici.
+if [[ -z "$1" ]];then LUNGHEZZA=15;else LUNGHEZZA="$1";fi
+
+
+while [ "${n:=1}" -le "$LUNGHEZZA" ]
+# ==> Ricordo che := è l'operatore "sostiruzione default".
+# ==> Quindi, se 'n' non è stata inizializzata, viene impostata ad 1.
+do
+       PASS="$PASS${MATRICE:$(($RANDOM%${#MATRICE})):1}"
+       # ==> Molto intelligente e scaltro.
+
+       # ==> Iniziando dall'annidamento più interno...
+       # ==> ${#MATRICE} restituisce la lunghezza dell'array MATRICE.
+
+       # ==> $RANDOM%${#MATRICE} restituisce un numero casuale compreso tra 1
+       # ==> e [lunghezza di MATRICE] - 1.
+
+       # ==> ${MATRICE:$(($RANDOM%${#MATRICE})):1}
+       # ==> restituisce l'espansione di lunghezza 1 di MATRICE 
+       # ==> partendo da una posizione casuale.
+       # ==> Vedi la sostituzione di parametro {var:pos:lun},
+       # ==> con relativi esempi, al Capitolo 9.
+
+       # ==> PASS=... aggiunge semplicemente il risultato al precedente 
+       # ==> valore di PASS (concatenamento).
+
+       # ==> Per visualizzare tutto questo più chiaramente, 
+       # ==> decommentate la riga seguente
+       #                 echo "$PASS"
+       # ==> e vedrete come viene costruita PASS,
+       # ==> un carattere alla volta ad ogni iterazione del ciclo.
+
+       let n+=1
+       # ==> Incrementa 'n' per il passaggio successivo.
+done
+
+echo "$PASS"      # ==> Oppure, se preferite, redirigetela in un file.
+
+exit 0
diff --git a/bin/mvb b/bin/mvb
new file mode 100644 (file)
index 0000000..e2e86ec
--- /dev/null
+++ b/bin/mvb
@@ -0,0 +1,164 @@
+#! /bin/bash
+#----------------------------------------------------
+# Change the path above to point to the location on
+# your computer of either the Bourne shell (sh) or
+# the BASH (Bourne Again) shell (bash).
+#
+# This shell script was written to "batch rename" files
+# (change the name of many files at once) in the
+# current working directory.
+# 
+# For his personal use the author named this script
+# mvb (MV-Batch) in reference to the mv command
+# of *nix/Linux (which this script uses).
+#
+# Written by: Steve Doonan, Portales, NM US
+# Email: xscd at xscd.com
+# Date: October, 2003
+#----------------------------------------------------
+
+if [ $# -eq 0 ]
+   then
+      cat << _EOF_
+
+--------------------------------------------------
+You did not specify a NEWNAME for the files.
+
+After the name of the command please enter
+a SPACE followed by the name you would like
+all the files in the current directory to be
+renamed to.
+--------------------------------------------------
+
+_EOF_
+      exit
+fi
+
+NEWNAME="$(echo "$1" | tr -Cs '[:alnum:]' '_')"
+
+cat << _EOF_
+
+-------------------------------------------------------
+Rename files to--> $NEWNAME
+Current directory--> $(pwd)
+
+   Continue? (Press RETURN or ENTER)
+   TO QUIT, type q (then press RETURN or ENTER)
+   FOR INFORMATION, type i (then press RETURN or ENTER)
+-------------------------------------------------------
+
+_EOF_
+
+read CONTINUE
+case $CONTINUE
+in
+    [!i]* ) exit ;;
+       i  ) cat << _EOF_
+
+----------------------------------------------------------------
+INFORMATION
+
+This shell script (Bourne or BASH) will RENAME all visible files
+(files that don't begin with a dot) in the current directory, to
+a name you specify, appending a numerical index to each filename
+so that each is unique, and retaining the original filename
+extension, if one exists.
+
+This script will NOT rename subdirectories or symbolic links
+contained within the current directory, nor will it descend into
+subdirectories to rename files within them.
+
+If the script does not see what looks like an existing valid
+FILENAME EXTENSION (3-4 characters following a dot at the end
+of a filename), it will ask for one. If you WANT to add a
+filename extension, just type 3 or 4 characters (i.e. jpg, txt,
+html), with or without a preceding dot--the script will provide
+the dot if you do not. If you do NOT want the filename to have
+an extension, just press RETURN or ENTER at that prompt without
+typing any characters, and no filename extension will be added.
+
+To QUIT this program at any time, press CONTROL-C
+To CONTINUE, press RETURN or ENTER
+----------------------------------------------------------------
+
+_EOF_
+    read CONTINUE ;;
+esac
+
+if [ -z $2 ];then
+       INDEX=0
+else
+       INDEX=$2
+fi
+
+make_zero-padded_index_number ()
+{
+INDEX=$(($INDEX + 1))
+INDEX_COUNT="$(echo "$INDEX" | wc -c)"
+PADDING_ZEROS="$(ls "$(pwd)" | wc -l | tr '[:digit:]' '0' | tr -d '[:space:]')"
+INDEX_ALPHANUMERIC="$(echo "${PADDING_ZEROS}${INDEX}" | cut -c$INDEX_COUNT-)"
+}
+
+for I in *
+   do
+      #-----------------------------------------
+      # if file is NOT a directory or a link...
+      #-----------------------------------------
+      if [ -f "$I" -a ! -L "$I" ]
+         then
+         #-----------------------------------------------
+         # if filename has a 3 or 4 character extension...
+         #-----------------------------------------------
+         if echo "$I" | grep "\.[^.0-9]\{3,4\}$" > /dev/null
+            then
+            #------------------------------------------------
+            # assign filename extension to variable EXTENSION
+            #------------------------------------------------
+            EXTENSION="$(echo "$I" | sed 's/^.*\(\.[^.]*\)$/\1/')"
+         #-----------------------------------------------------
+         # otherwise, ask for a filename extension (or none)...
+         #-----------------------------------------------------
+         else
+            echo ""
+            echo '------------------------------------------------------------'
+            echo "FILENAME: $I"
+            echo "No (or improbable) filename extension found"
+            echo "Enter new filename extension, or press RETURN or ENTER"
+            echo -n "for no filename extension: "
+            read NEW_EXTENSION
+            #-----------------------------------------------------------------
+            # cut the new extension (if any) down to no more than 4 characters
+            #-----------------------------------------------------------------
+            NEW_EXTENSION="$(echo "$NEW_EXTENSION" | sed 's/^\.*\(.\{0,4\}\).*$/\1/'| tr -C '[:alnum:]\12' '_' )"
+            echo '------------------------------------------------------------'
+            echo ""
+            if [ -n "$NEW_EXTENSION" ]
+               then
+               EXTENSION=".${NEW_EXTENSION}"
+            else
+               EXTENSION=''
+            fi
+         fi
+         #----------------------------------------------------------------------
+         # at this point, EXTENSION should be set correctly--an alphanumeric
+         # index number is created (by the function make_zero-padded_index_number)
+         # and the file is renamed (with a slightly different name if the computed
+         # filename already exists in the current directory).
+         #----------------------------------------------------------------------
+         make_zero-padded_index_number
+         RENAME_TO="${NEWNAME}${INDEX_ALPHANUMERIC}${EXTENSION}"
+         if [ -e "$RENAME_TO" ]
+            then
+               RENAME_TO="${NEWNAME}${INDEX_ALPHANUMERIC}a${EXTENSION}"
+         fi
+         chmod 664 "$I"
+         mv -iv -- "$I" "$RENAME_TO"
+      fi
+   done
+cat << _EOF_
+
+---------------------------------------------------
+  The files have been renamed. Script exiting...
+---------------------------------------------------
+
+_EOF_
diff --git a/bin/my_netstat b/bin/my_netstat
new file mode 100644 (file)
index 0000000..89071cb
--- /dev/null
@@ -0,0 +1,8 @@
+clear;
+while (( 1 ));
+    do
+      netstat --tcp --udp -nap | sed -n '1p;2{s/PID/  PID/;p};/ESTABLISHED/{s/D/D   /;p;d};/LISTEN/{s/N/N   /;p;d};/0\.0\.0\.0:/{s/\( \)\([[:digit:]]\+\/.*\)/\1   \2/;p;d};'
+      sleep 5;
+      clear;
+    done
+
diff --git a/bin/nopy.sh b/bin/nopy.sh
new file mode 100644 (file)
index 0000000..e61bfcf
--- /dev/null
@@ -0,0 +1,77 @@
+#!/bin/bash
+echo -e "\n\e[38;5;146m      ,.....,\e[0m"
+echo -e "\e[38;5;146m   pd\"\"\"\`\`\`\"\"\"bq\e[0m"
+echo -e "\e[38;5;146m  6P           YA\e[0m"
+echo -e "\e[38;5;146m 6M'  \e[0mdMpMMMo.\e[38;5;146m  \`Mb\e[0m  ,pW\"Wq.  dMMMMAo. dM    MF"
+echo -e "\e[38;5;146m MN   \e[0mMM    MM\e[38;5;146m   8M\e[0m 6W'   \`Wb MM   \`Wb  VA  ,V"
+echo -e "\e[38;5;146m YM.  \e[0mMM    MM\e[38;5;146m  ,M9\e[0m YA.   ,A9 MM   ,AP   VVV\""
+echo -e "\e[38;5;146m  Mb  \e[0mJM    MM\e[38;5;146m  dM\e[0m   \`Ybmd9'  MMbmmd'    ,V"
+echo -e "\e[38;5;146m   Ybq,______,pdY\e[0m             MM        ,V"
+echo -e "\e[38;5;146m     \"\"\"\`\`\`\`\"\"\"\e[0m               JM       Ob\" \e[38;5;146mv\e[0m0.1"
+echo -e "\e[0m"
+
+# Make sure we have the required binaries
+has_curl=`which curl 2>/dev/null || echo false`
+has_jq=`which jq 2>/dev/null || echo false`
+has_aria2=`which aria2c 2>/dev/null || echo false`
+
+if [ $has_curl = "false" ]; then
+       echo -e " ! Error: Missing curl binary\n"
+       exit 1
+fi
+
+if [ $has_jq = "false" ]; then
+       echo -e " ! Error: Missing jq binary\n"
+       exit 1
+fi
+
+# Make sure the supplied URL looks valid
+if [ "$(grep -Poc 'nopy.to\/([a-zA-Z0-9]{8})\/(.*?)$' <<< $1)" -lt 1 ]; then
+       echo -e " ! Error: Only nopy.to URLs are supported\n"
+       exit 1
+fi
+
+# Parse the code and file from URL
+code=`echo $1 | sed -n 's/.*nopy.to\/\([a-zA-Z0-9]\{8\}\)\/.*/\1/p'`
+file=`echo $1 | sed -n 's/.*nopy.to\/[a-zA-Z0-9]\{8\}\/\(.*\)\/\?/\1/p'`
+
+# Fetch the session
+echo -e " Fetching session ...\n"
+sessionreq=`curl -s --data-urlencode "code=$code" --data-urlencode "file=$file" -X POST https://data.nopy.to/file`
+
+if [ "$(echo $sessionreq | jq -r '.status')" != "ok" ]; then
+       echo -e " ! Error: Session request failed\n"
+       exit 1
+fi
+
+if [ "$(echo $sessionreq | jq -r '.msg.error_fatal')" != "false" ]; then
+       echo -e " ! Error: Nopy is having technical issues\n"
+       exit 1
+fi
+
+if [ -f "$(echo $sessionreq | jq -r '.msg.filename')" ]; then
+       echo -e " ! Error: File \"$(echo $sessionreq | jq -r '.msg.filename')\" already exists\n"
+       exit 1
+fi
+
+# Fetch the download URL
+echo -e " Requesting download ticket ...\n"
+downloadreq=`curl -s --data-urlencode "code=$code" --data-urlencode "fid=$(echo $sessionreq | jq -r '.msg.fid')" --data-urlencode "request=$(echo $sessionreq | jq -r '.msg.request')" --data-urlencode "session=$(echo $sessionreq | jq -r '.msg.session')" -X POST https://data.nopy.to/download`
+
+if [ "$(echo $downloadreq | jq -r '.status')" != "ok" ]; then
+       echo -e " ! Error: Download request failed\n"
+       exit 1
+fi
+
+# Finally, download the file
+echo -e " Downloading \"$file\" from: $(echo $downloadreq | jq -r '.msg.server') ..."
+
+if [ $has_aria2 = "false" ]; then
+       echo -e ""
+       curl -J -O "$(echo $downloadreq | jq -r '.msg.download')"
+else
+       aria2c -x 4 --summary-interval=0 --auto-file-renaming=false "$(echo $downloadreq | jq -r '.msg.download')"
+fi
+
+echo -e "\n Finished!\n"
+
diff --git a/bin/nospaces b/bin/nospaces
new file mode 100644 (file)
index 0000000..905652d
--- /dev/null
@@ -0,0 +1,14 @@
+#! /bin/bash
+
+dir_to_work=$1
+IFS=$'\n\t'
+
+cd $dir_to_work
+
+for item in *; do
+       item_nospace=$(echo $item |tr [:blank:] '_')
+       if [[ $item != $item_nospace ]];then
+               mv $item $item_nospace
+       fi
+done
+
diff --git a/bin/notes b/bin/notes
new file mode 100644 (file)
index 0000000..a9afd60
--- /dev/null
+++ b/bin/notes
@@ -0,0 +1,726 @@
+#! /bin/bash
+
+# bash-notes © 2023 by danix is licensed under CC BY-NC 4.0. 
+# To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/
+
+# to debug the script run it like:
+# DEBUG=true notes.sh ...
+# and check /tmp/debug_bash-notes.log
+if [[ $DEBUG == true ]]; then
+       exec 5> /tmp/debug_bash-notes.log
+       BASH_XTRACEFD="5"
+       PS4='$LINENO: '
+       set -x
+fi
+
+PID=$$
+BASENAME=$( basename "$0" )
+NOW=$(date +%s)
+
+VERSION="0.4git"
+DBVERSION=${VERSION}_${NOW}
+
+set_defaults() {
+# Binaries to use
+JQ=${JQ:-/usr/bin/jq}
+EDITOR=${EDITOR:-/usr/bin/vim}
+TERMINAL=${TERMINAL:-/usr/bin/alacritty}
+# Git binary only used if $USEGIT is true - See below
+GIT=${GIT:-/usr/bin/git}
+# add options for your terminal. Remember to add the last option to execute
+# your editor program, otherwise the script will fail.
+# see example in the addnote function
+TERM_OPTS="--class notes --title notes -e "
+# Setting PAGER here overrides whatever is set in your default shell
+# comment this option to use your default pager if set in your shell.
+PAGER=${PAGER:-/usr/bin/more}
+
+# set this to true to have output in plain text
+# or use the -p option on the command line before every other option
+PLAIN=false
+# base directory for program files
+BASEDIR=${BASEDIR:-~/.local/share/bash-notes}
+# notes database in json format
+DB=${BASEDIR}/db.json
+# directory containing the actual notes
+NOTESDIR=${BASEDIR}/notes
+
+### GIT SUPPORT
+
+# If you want to store your notes in a git repository set this to true
+USEGIT=true
+# Address of your remote repository. Without this GIT will refuse to work
+GITREMOTE=${GITREMOTE:-""}
+# How long should we wait (in seconds) between sync on the git remote. Default 3600 (1 hour)
+GITSYNCDELAY=${GITSYNCDELAY:-"3600"}
+# The name of this client. If left empty, defaults to the output of hostname
+GITCLIENT=${GITCLIENT:-""}
+
+} # end set_defaults, do not change this line.
+
+set_defaults
+
+# Do not edit below this point
+RCFILE=${RCFILE:-~/.config/bash-notes.rc}
+TMPDB=/tmp/db.json
+
+if [ ! -x "$JQ" ]; then
+       echo "jq not found in your PATH"
+       echo "install jq to continue"
+       exit 1
+fi
+
+# IMPORT USER DEFINED OPTIONS IF ANY
+if [[ -f $RCFILE ]]; then
+       # shellcheck disable=SC1090
+       source "$RCFILE"
+fi
+
+# We prevent the program from running more than one instance:
+PIDFILE=/var/tmp/$(basename "$0" .sh).pid
+
+# Make sure the PID file is removed when we kill the process
+trap 'rm -f $PIDFILE; exit 1' TERM INT
+
+if [[ -r $PIDFILE ]]; then
+       # PIDFILE exists, so I guess there's already an instance running
+       # let's kill it and run again
+       # shellcheck disable=SC2046,SC2086
+       kill -s 15 $(cat $PIDFILE) > /dev/null 2>&1
+       # should already be deleted by trap, but just to be sure
+       rm "$PIDFILE"
+fi
+
+# create PIDFILE
+echo $PID > "$PIDFILE"
+
+# Export config to file
+export_config() {
+       if [ -r ${RCFILE} ]; then
+               echo "Backing up current '${RCFILE}'...."
+               mv -f ${RCFILE} ${RCFILE}.$(date +%Y%m%d_%H%M)
+       fi
+       echo "Writing '${RCFILE}'...."
+       sed  -n '/^set_defaults() {/,/^} # end set_defaults, do not change this line./p' $0 \
+       | grep -v set_defaults \
+       | sed -e 's/^\([^=]*\)=\${\1:-\([^}]*\)}/\1=\2/' \
+       > ${RCFILE}
+       if [ -r ${RCFILE} ]; then
+               echo "Taking no further action."
+               exit 0
+       else
+               echo "Could not write '${RCFILE}'...!"
+               exit 1
+       fi
+}
+
+# we should expand on this function to add a sample note and explain a little bit
+# how the program works.
+firstrun() {
+       [ -f $RCFILE ] && RC=$RCFILE || RC="none"
+
+       clear
+       echo "${BASENAME} configuration:
+
+base directory:                ${BASEDIR}/
+notes archive:         ${NOTESDIR}/
+notes database:                ${DB}
+rc file:               $RC
+text editor:           ${EDITOR}
+terminal:              ${TERMINAL}
+jq executable:         ${JQ}
+"
+
+       echo "Now I'll create the needed files and directories."
+       read -r -p "Do you wish to continue? (y/N) " ANSWER
+       case $ANSWER in
+               y|Y )
+                       mkdir -p $NOTESDIR
+                       cat << __EOL__ > ${DB}
+{
+       "params": {
+               "version": "${VERSION}",
+               "dbversion": "${DBVERSION}"
+       },
+       "git": {
+               "lastpull": ""
+       },
+       "notes": []
+}
+__EOL__
+                       echo; echo "All done, you can now write your first note."
+                       ;;
+               * )
+                       echo "No changes made. Exiting"
+                       exit
+                       ;;
+       esac
+}
+
+# check for notes dir existance and create it in case it doesn't exists
+if [[ ! -d $NOTESDIR ]]; then
+       # we don't have a directory. FIRST RUN?
+       firstrun
+fi
+# check if input is a number, returns false or the number itself
+check_noteID() {
+       IN=$1
+       case $IN in
+               ''|*[!0-9]*)
+                       false
+                       ;;
+               *)
+                       echo "$IN"
+                       ;;
+       esac
+}
+
+helptext() {
+    echo "Usage:"
+    echo "  $0 [PARAMS] [note ID]..."
+       echo ""
+    echo "${BASENAME} parameters are:"
+    echo -e "  -h | --help\t\t\t: This help text"
+    echo -e "  -p | --plain\t\t\t: Output is in plain text"
+    echo -e "\t\t\t\t  (without this option the output is formatted)"
+    echo -e "\t\t\t\t  (this option must precede all others)"
+    echo -e "  -l | --list\t\t\t: List existing notes"
+    echo -e "  -a | --add=[\"<title>\"]\t: Add new note"
+    echo -e "  -e | --edit=[<note>]\t\t: Edit note"
+    echo -e "  -d | --delete=[<note> | all]    : Delete single note or all notes at once"
+    echo -e "  -s | --show=[<note>]\t\t: Display note using your favourite PAGER"
+    echo -e "  -r | --restore=[<dir>]\t: Restore a previous backup from dir"
+    echo -e "  -v | --version\t\t: Print version"
+    echo -e "  --userconf\t\t\t: Export User config file"
+    echo -e "  --backup [<dest>]\t\t: Backup your data in your destination folder"
+    echo -e "  --showconf\t\t\t: Display running options"
+    echo -e "  --sync\t\t\t: Sync notes to git repository"
+    echo ""
+    echo -e "if a non option is passed and is a valid note ID, the note will be displayed."
+}
+
+configtext() {
+    [ $USEGIT ] && GITUSE="enabled" || GITUSE="disabled"
+    if [ -n $GITCLIENT ]; then
+        CLIENTGIT="$( hostname )"
+    else
+        CLIENTGIT="$GITCLIENT"
+    fi
+    clear
+    echo -e "${BASENAME} configuration is:"
+
+    echo -e "\tbase directory:     ${BASEDIR}/"
+    echo -e "\tnotes archive:      ${NOTESDIR}/"
+    echo -e "\tnotes database:     ${DB}"
+    echo -e "\trc file:            $RCFILE"
+    echo -e "\tdebug file:         /tmp/debug_bash-note.log"
+    echo
+    echo -e "\ttext editor:        ${EDITOR}"
+    echo -e "\tterminal:           ${TERMINAL}"
+    echo -e "\tjq executable:      ${JQ}"
+    echo -e "\tPAGER:              ${PAGER}"
+    echo
+    echo -e "\tGIT:                ${GITUSE} - ${GIT}"
+    echo -e "\tGIT remote:         ${GITREMOTE}"
+    echo -e "\tGIT sync delay:     ${GITSYNCDELAY}"
+    echo -e "\tGIT client name:    ${CLIENTGIT}"
+}
+
+# this function returns a random 2 words title
+random_title() {
+    # Constants 
+    X=0
+    DICT=/usr/share/dict/words
+    OUTPUT=""
+     
+    # total number of non-random words available 
+    COUNT=$(cat $DICT | wc -l)
+     
+    # while loop to generate random words  
+    while [ "$X" -lt 2 ] 
+    do 
+        RAND=$(od -N3 -An -i /dev/urandom | awk -v f=0 -v r="$COUNT" '{printf "%i\n", f + r * $1 / 16777216}')
+        OUTPUT+="$(sed `echo $RAND`"q;d" $DICT)"
+        (("X = X + 1"))
+        [[ $X -eq 1 ]] && OUTPUT+=" "
+    done
+
+    echo $OUTPUT
+}
+
+# check if GITCLIENT has been set or set it to the output of hostname
+if [ -z "$GITCLIENT" ]; then
+    GITCLIENT=$( hostname )
+fi
+# returns true if the argument provided directory is a git repository
+is_git_repo() {
+    DIR=$1
+    if [[ -d $DIR ]]; then
+        cd $DIR
+        if git rev-parse 2>/dev/null; then
+            true
+        else
+            false
+        fi
+    fi
+}
+
+# sync local repository to remote
+# accepts -f parameter to skip last sync check
+gitsync() {
+    FORCE=$1
+    if [[ $USEGIT && -n $GITREMOTE ]]; then
+        [ $PLAIN == false ] && echo "Syncing notes with git on remote \"$GITREMOTE\""
+        NOWSYNC=$(date +%s)
+        if [[ $FORCE == "-f" ]]; then
+            $JQ --arg n "$NOWSYNC" '.git["lastpull"] = $n' "$DB" > $TMPDB
+            mv $TMPDB $DB
+            cd $BASEDIR
+            [ $PLAIN == false ] && $GIT pull || $GIT pull -q
+        else
+            # LASTSYNC is the last time we synced to the remote, or 0 if it's the first time.
+            LASTSYNC=$($JQ -r '.git["lastpull"] // 0' "$DB")
+            SYNCDIFF=$(( ${NOWSYNC} - ${LASTSYNC} ))
+            if (( $SYNCDIFF > $GITSYNCDELAY )); then
+                #more than our delay time has passed. We can sync again.
+                $JQ --arg n "$NOWSYNC" '.git["lastpull"] = $n' "$DB" > $TMPDB
+                mv $TMPDB $DB
+                cd $BASEDIR
+                [ $PLAIN == false ] && $GIT pull || $GIT pull -q
+            else
+                # Last synced less than $GITSYNCDELAY seconds ago. We shall wait
+                [ $PLAIN == false ] && echo "Last synced less than $GITSYNCDELAY seconds ago. We shall wait"
+            fi
+        fi
+    else
+        # no git, so we just keep going
+        true
+    fi
+}
+
+# add note to git and push it to remote
+gitadd() {
+    if [[ $USEGIT && -n $GITREMOTE ]]; then
+        [ $PLAIN == false ] && echo "Adding note to remote \"$GITREMOTE\""
+        cd $BASEDIR
+        $GIT add .
+        $GIT commit -m "$(basename $0) - adding note from ${GITCLIENT}"
+        $GIT push origin master
+    else
+        # no git, so we just keep going
+        true
+    fi
+}
+
+# edited note added to git and pushed it to remote
+gitedit() {
+    if [[ $USEGIT && -n $GITREMOTE ]]; then
+        [ $PLAIN == false ] && echo "Editing note on remote \"$GITREMOTE\""
+        cd $BASEDIR
+        $GIT add .
+        $GIT commit -m "$(basename $0) - ${GITCLIENT} note edited."
+        $GIT push origin master
+    else
+        # no git, so we just keep going
+        true
+    fi
+}
+
+# add note to git and push it to remote
+gitremove() {
+    NOTE=$1
+    FILE=$2
+    if [[ $USEGIT && -n $GITREMOTE ]]; then
+        [ $PLAIN == false ] && echo "Deleting notes from remote \"$GITREMOTE\""
+        if [ "all" == $NOTE ];then
+            echo "Deleting all notes"
+            cd $BASEDIR
+            $GIT rm notes/*
+            $GIT commit -m "$(basename $0) - ${GITCLIENT} removing all notes."
+            $GIT push origin master
+        else
+            local OK=$(check_noteID "$NOTE")
+            if [[ "$OK" ]]; then
+                echo "Deleting note ID ${NOTE}"
+                cd $BASEDIR
+                $GIT rm notes/${FILE}
+                $GIT add .
+                $GIT commit -m "$(basename $0) - ${GITCLIENT} removing note ID ${NOTE}."
+                $GIT push origin master
+            fi
+        fi
+    else
+        # no git, so we just keep going
+        true
+    fi
+}
+
+# check for USEGIT and subsequent variables
+if [[ $USEGIT && -n $GITREMOTE ]]; then
+    # GIT is a go.
+    if ! is_git_repo $BASEDIR; then
+        # initializing git repository
+        cd $BASEDIR
+        $GIT init
+        echo "adding all files to git"
+        $GIT add .
+        $GIT commit -m "$(basename $0) - initial commit from ${GITCLIENT}"
+        $GIT remote add origin $GITREMOTE
+        $GIT push -u origin master
+    fi
+elif [[ $USEGIT && -z $GITREMOTE ]]; then
+    echo "GITREMOTE variable not set. reverting USEGIT to false"
+    USEGIT=false
+fi
+
+addnote() {
+       # attempt syncing before adding a note
+       gitsync -f
+       # remove eventually existing temp DB file
+       if [[ -f $TMPDB ]]; then
+               rm $TMPDB
+       fi
+
+       # RANDOM TITLE
+       RTITLE=$(random_title)
+
+       if [[ -z $1 ]]; then
+               read -r -p "Title: " TITLE
+               case "$TITLE" in
+                       '' )
+                               NOTETITLE="$RTITLE"
+                               ;;
+                       * )
+                               NOTETITLE=$TITLE
+                               ;;
+               esac
+       fi
+
+       # [[ -z "$1" ]] && NOTETITLE="$RTITLE" || NOTETITLE="$1"
+       echo "adding new note - \"$NOTETITLE\""
+       # shellcheck disable=SC2086
+       LASTID=$($JQ '.notes[-1].id // 0 | tonumber' $DB)
+       # [ "" == $LASTID ] && LASTID=0
+       NOTEID=$(( LASTID + 1 ))
+       # shellcheck disable=SC2086
+       touch ${NOTESDIR}/${NOW}
+       # shellcheck disable=SC2016
+       $JQ --arg i "$NOTEID" --arg t "$NOTETITLE" --arg f "$NOW" '.notes += [{"id": $i, "title": $t, "file": $f}]' "$DB" > $TMPDB
+       # shellcheck disable=SC2086
+       mv $TMPDB $DB
+       # example for alacritty:
+       # alacritty --class notes --title notes -e /usr/bin/vim ...
+       # shellcheck disable=SC2086,SC2091
+       $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${NOW})
+       # add note to git and push to remote
+       gitadd
+}
+backup_data() {
+       BACKUPDIR="$1"
+    echo "backing up data in $BACKUPDIR"
+
+
+    if [ -d $BACKUPDIR ]; then
+       if [ $(/bin/ls -A $BACKUPDIR) ]; then
+               echo "$BACKUPDIR is not empty. Cannot continue"
+               exit
+           else
+               echo "$BACKUPDIR is ok. Continuing!"
+           fi
+       else
+               # BACKUPDIR doesn't exists
+               echo "$BACKUPDIR doesn't exists"
+               read -r -p "Do you want me to create it for you? (y/N) " ANSWER
+               case $ANSWER in
+                       y|Y )
+                               mkdir -p $BACKUPDIR
+                               ;;
+                       * )
+                               echo "No changes made. Exiting"
+                               exit
+                               ;;
+               esac
+    fi
+    # ok, we have a backup directory
+    if [ -r $RCFILE ]; then
+       BCKUP_COMM=$(rsync -avz --progress ${RCFILE}* ${BASEDIR}/ ${BACKUPDIR})
+    else
+       BCKUP_COMM=$(rsync -avz --progress ${BASEDIR}/ ${BACKUPDIR})
+    fi
+    # run the command
+    if [ "$BCKUP_COMM" ]; then 
+           echo -e "All files backed up."
+           echo -e "BACKUP directory:\t$BACKUPDIR"
+           tree $BACKUPDIR | $PAGER
+           echo; echo "BACKUP COMPLETED"
+       fi
+}
+
+backup_restore() {
+       BACKUPDIR="$1"
+       echo "restoring backup from $BACKUPDIR"
+       echo "This will overwrite all your notes and configurations with the backup."
+       read -r -p "Do you want to continue? (y/N) " ANSWER
+       case $ANSWER in
+               y|Y )
+                       # restoring rc file
+                       BACKUPRC=$(basename $RCFILE)
+                       if [ -r ${BACKUPDIR}/${BACKUPRC} ]; then
+                               if [ -r ${RCFILE} ]; then
+                                       echo "Backing up current '${RCFILE}'...."
+                                       mv -f ${RCFILE} ${RCFILE}.$(date +%Y%m%d_%H%M)
+                               fi
+                               cp --verbose ${BACKUPDIR}/${BACKUPRC} $RCFILE
+                       fi
+                       # restoring notes directory
+                       if [ -d $BACKUPDIR/notes ]; then
+                               if [ $(/bin/ls -A $NOTESDIR) ]; then
+                                       rm --verbose $NOTESDIR/*
+                               fi
+                               cp -r --verbose $BACKUPDIR/notes $BASEDIR
+                       fi
+                       # restoring database
+                       BACKUPDB=$(basename $DB)
+                       if [ -f ${BACKUPDIR}/${BACKUPDB} ]; then
+                               if [ -r ${DB} ]; then
+                                       echo "Backing up current '${DB}'...."
+                                       mv -f ${DB} ${DB}.$(date +%Y%m%d_%H%M)
+                               fi
+                               cp --verbose ${BACKUPDIR}/${BACKUPDB} $DB
+                       fi
+                       # restoring git repo subdirectory
+                       if [ -d $BACKUPDIR/.git ]; then
+                               if [ /bin/ls -A ${BASEDIR}/.git ]; then
+                                       rm -rf ${BASEDIR}/.git
+                               fi
+                               cp -r --verbose ${BACKUPDIR}/.git ${BASEDIR}/
+                       fi
+                       ;;
+               * )
+                       echo "No changes made. Exiting"
+                       exit
+                       ;;
+       esac
+}
+
+editnote() {
+       NOTE=$1
+       # shellcheck disable=SC2155
+       local OK=$(check_noteID "$NOTE")
+       if [ ! "$OK" ]; then
+               echo "invalid note \"$NOTE\""
+               echo "Use the note ID that you can fetch after listing your notes"
+               exit 1
+       fi
+
+       # shellcheck disable=SC2016,SC2086
+       TITLE=$($JQ --arg i $OK '.notes[] | select(.id == $i) | .title' $DB)
+       # shellcheck disable=SC2016,SC2086
+       FILE=$($JQ -r --arg i $OK '.notes[] | select(.id == $i) | .file' $DB)
+       if [ "$TITLE" ]; then
+               echo "editing note $TITLE"
+               # shellcheck disable=SC2086,SC2091
+               $(${TERMINAL} ${TERM_OPTS} ${EDITOR} ${NOTESDIR}/${FILE})
+               gitedit
+       else
+                echo "note not found"
+                exit 1
+       fi
+}
+listnotes() {
+       # attempt syncing before listing all notes
+       gitsync
+       # [ $PLAIN == true ] && echo "output is plain text" || echo "output is colored"
+       if [[ $(ls -A "$NOTESDIR") ]]; then
+               if [ $PLAIN == false ]; then
+                       echo "listing all notes"
+                       echo ""
+               fi
+               [ $PLAIN == false ] && echo "[ID]       [TITLE]         [CREATED]"
+               for i in "${NOTESDIR}"/*; do
+                       # shellcheck disable=SC2155
+                       local fname=$(basename $i)
+                       DATE=$(date -d @${fname} +"%d/%m/%Y %R %z%Z")
+                       # shellcheck disable=SC2016,SC2086
+                       TITLE=$($JQ -r --arg z $(basename $i) '.notes[] | select(.file == $z) | .title' $DB)
+                       # shellcheck disable=SC2016,SC2086
+                       ID=$($JQ -r --arg z $(basename $i) '.notes[] | select(.file == $z) | .id' $DB)
+                       [ $PLAIN == false ] && echo "[${ID}]    ${TITLE}        ${DATE}" || echo "${ID} - ${TITLE} - ${DATE}"
+               done
+       else
+               echo "no notes yet. You can add your first one with: ${BASENAME} -a \"your note title\""
+       fi
+}
+rmnote() {
+       # remove eventually existing temp DB file
+       if [[ -f $TMPDB ]]; then
+               rm $TMPDB
+       fi
+
+       NOTE=$1
+       if [ "all" == "$NOTE" ]; then
+               echo "You're going to delete all notes."
+               read -r -p "Do you wish to continue? (y/N) " ANSWER
+               case $ANSWER in
+                       y|Y )
+                               # shellcheck disable=SC2086
+                               $JQ 'del(.notes[])' $DB > $TMPDB
+                               # shellcheck disable=SC2086
+                               mv $TMPDB $DB
+                               # shellcheck disable=SC2086
+                               rm $NOTESDIR/*
+                               gitremove "all"
+                               echo "Deleted all notes"
+                               ;;
+                       * )
+                               echo "Aborting, no notes were deleted."
+                               exit 1
+                               ;;
+               esac
+       else
+               # shellcheck disable=SC2155
+               local OK=$(check_noteID "$NOTE")
+               if [ ! "$OK" ]; then
+                       echo "invalid note \"$NOTE\""
+                       echo "Use the note ID that you can fetch after listing your notes"
+                       sleep 1
+                       exit 1
+               fi
+
+               # shellcheck disable=SC2016,SC2086
+               TITLE=$($JQ --arg i $OK '.notes[] | select(.id == $i) | .title' $DB)
+               # shellcheck disable=SC2016,SC2086
+               FILE=$($JQ -r --arg i $OK '.notes[] | select(.id == $i) | .file' $DB)
+               if [ "$TITLE" ]; then
+                       # shellcheck disable=SC2016,SC2086
+                       $JQ -r --arg i $OK 'del(.notes[] | select(.id == $i))' $DB > $TMPDB
+                       # shellcheck disable=SC2086
+                       mv $TMPDB $DB
+                       rm $NOTESDIR/$FILE
+                       gitremove $OK $FILE
+                       echo "Deleted note $TITLE"
+                       sleep 1
+                       exit
+               else
+                        echo "note not found"
+                        sleep 1
+                        exit 1
+               fi
+       fi
+}
+shownote() {
+       NOTE=$1
+
+       # shellcheck disable=SC2155
+       local OK=$(check_noteID "$NOTE")
+       if [ ! "$OK" ]; then
+               echo "invalid note \"$NOTE\""
+               echo "Use the note ID that you can fetch after listing your notes"
+               exit 1
+       fi
+
+       FILE=$($JQ -r --arg i $OK '.notes[] | select(.id == $i) | .file' $DB)
+
+       if [ "$FILE" ]; then
+               $PAGER ${NOTESDIR}/${FILE}
+       fi
+}
+# shellcheck disable=SC2006
+GOPT=$(getopt -o hvplr:a::e:d:s: --long help,version,list,plain,userconf,showconf,sync,restore:,backup:,add::,edit:,delete:,show: -n 'bash-notes' -- "$@")
+
+# shellcheck disable=SC2181
+if [ $? != 0 ] ; then helptext >&2 ; exit 1 ; fi
+
+# Note the quotes around `$GOPT': they are essential!
+eval set -- "$GOPT"
+unset GOPT
+
+while true; do
+       case "$1" in
+               -h | --help )
+                       helptext
+               exit
+               ;;
+               -v | --version )
+                       echo $BASENAME v${VERSION}
+                       exit
+                       ;;
+           -p | --plain )
+                       PLAIN=true
+                       shift
+               ;;
+           -l | --list )
+                       listnotes
+                       exit
+               ;;
+           -a | --add )
+                       TITLE=$2
+                       shift 2
+                       addnote "$TITLE"
+                       exit
+               ;;
+               -e | --edit )
+                       NOTE=$2
+                       shift 2
+                       editnote "$NOTE"
+                       exit
+                       ;;
+               -d | --delete )
+                       NOTE=$2
+                       shift 2
+                       rmnote "$NOTE"
+                       exit
+                       ;;
+               -s | --show )
+                       NOTE=$2
+                       shift 2
+                       shownote "$NOTE"
+                       exit
+                       ;;
+               -r | --restore )
+                       RDIR=$2
+                       shift 2
+                       backup_restore $RDIR
+                       exit
+                       ;;
+               --sync )
+                       # I'm forcing it because if you run it manually, chances are that you need to.
+                       gitsync -f
+                       shift
+                       exit
+                       ;;
+               --userconf )
+                       export_config
+                       # shellcheck disable=SC2317
+                       echo "config exported to \"$RCFILE\""
+                       # shellcheck disable=SC2317
+                       exit
+                       ;;
+               --showconf )
+                       configtext
+                       exit
+                       ;;
+               --backup )
+                       BDIR=$2
+                       shift 2
+                       backup_data $BDIR
+                       exit
+                       ;;
+               -- )
+                       shift
+                       break
+                       ;;
+               * )
+                       break
+                       ;;
+       esac
+done
+
+for arg; do
+       if [ $(check_noteID $arg) ]; then
+               shownote $arg
+       else
+               helptext
+               exit
+       fi
+done
diff --git a/bin/polybar-kdeconnect.sh b/bin/polybar-kdeconnect.sh
new file mode 100644 (file)
index 0000000..9f576c1
--- /dev/null
@@ -0,0 +1,123 @@
+#!/usr/bin/env bash
+
+# CONFIGURATION
+LOCATION=0
+YOFFSET=0
+XOFFSET=0
+WIDTH=12
+WIDTH_WIDE=24
+THEME="darknix/main"
+
+# Color Settings of Icon shown in Polybar
+COLOR_DISCONNECTED='#000'       # Device Disconnected
+COLOR_NEWDEVICE='#ff0'          # New Device
+COLOR_BATTERY_90='#fff'         # Battery >= 90
+COLOR_BATTERY_80='#ccc'         # Battery >= 80
+COLOR_BATTERY_70='#aaa'         # Battery >= 70
+COLOR_BATTERY_60='#888'         # Battery >= 60
+COLOR_BATTERY_50='#666'         # Battery >= 50
+COLOR_BATTERY_LOW='#f00'        # Battery <  50
+
+# Icons shown in Polybar
+ICON_SMARTPHONE=''
+ICON_TABLET=''
+SEPERATOR='|'
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
+
+show_devices (){
+    IFS=$','
+    devices=""
+    for device in $(qdbus --literal org.kde.kdeconnect /modules/kdeconnect org.kde.kdeconnect.daemon.devices); do
+        deviceid=$(echo "$device" | awk -F'["|"]' '{print $2}')
+        devicename="$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid" org.kde.kdeconnect.device.name)"
+        devicetype=$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid" org.kde.kdeconnect.device.type)
+        isreach="$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid" org.kde.kdeconnect.device.isReachable)"
+        istrust="$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid" org.kde.kdeconnect.device.isTrusted)"
+        if [ "$isreach" = "true" ] && [ "$istrust" = "true" ]
+        then
+            battery="$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid/battery" org.kde.kdeconnect.device.battery.charge)"
+            icon=$(get_icon "$battery" "$devicetype")
+            devices+="%{A1:$DIR/polybar-kdeconnect.sh -n '$devicename' -i $deviceid -b $battery -m:}$icon%{A}$SEPERATOR"
+        elif [ "$isreach" = "false" ] && [ "$istrust" = "true" ]
+        then
+            devices+="$(get_icon -1 "$devicetype")$SEPERATOR"
+        else
+            haspairing="$(qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$deviceid" org.kde.kdeconnect.device.hasPairingRequests)"
+            if [ "$haspairing" = "true" ]
+            then
+                show_pmenu2 "$devicename" "$deviceid"
+            fi
+            icon=$(get_icon -2 "$devicetype")
+            devices+="%{A1:$DIR/polybar-kdeconnect.sh -n $devicename -i $deviceid -p:}$icon%{A}$SEPERATOR"
+
+        fi
+    done
+    echo "${devices::-1}"
+}
+
+show_menu () {
+    menu="$(rofi -sep "|" -dmenu -i -p "$DEV_NAME" -location $LOCATION -yoffset $YOFFSET -xoffset $XOFFSET -theme $THEME -width $WIDTH -hide-scrollbar -line-padding 4 -padding 20 -lines 5 <<< "Battery: $DEV_BATTERY%|Ping|Find Device|Send File|Browse Files|Unpair")"
+                case "$menu" in
+                    *Ping) qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/ping" org.kde.kdeconnect.device.ping.sendPing ;;
+                    *'Find Device') qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/findmyphone" org.kde.kdeconnect.device.findmyphone.ring ;;
+                    *'Send File') qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/share" org.kde.kdeconnect.device.share.shareUrl "file://$(qarma --file-selection)" ;;
+                    *'Browse Files')
+                        if "$(qdbus --literal org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/sftp" org.kde.kdeconnect.device.sftp.isMounted)" == "false"; then
+                            qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/sftp" org.kde.kdeconnect.device.sftp.mount
+                        fi
+                        qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID/sftp" org.kde.kdeconnect.device.sftp.startBrowsing
+                        ;;
+                    *'Unpair' ) qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID" org.kde.kdeconnect.device.unpair
+                esac
+}
+
+show_pmenu () {
+    menu="$(rofi -sep "|" -dmenu -i -p "$DEV_NAME" -location $LOCATION -yoffset $YOFFSET -xoffset $XOFFSET -theme $THEME -width $WIDTH -hide-scrollbar -line-padding 1 -padding 20 -lines 1<<<"Pair Device")"
+                case "$menu" in
+                    *'Pair Device') qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$DEV_ID" org.kde.kdeconnect.device.requestPair
+                esac
+}
+
+show_pmenu2 () {
+    menu="$(rofi -sep "|" -dmenu -i -p "$1 has sent a pairing request" -location $LOCATION -yoffset $YOFFSET -xoffset $XOFFSET -theme $THEME -width $WIDTH_WIDE -hide-scrollbar -line-padding 4 -padding 20 -lines 2 <<< "Accept|Reject")"
+                case "$menu" in
+                    *'Accept') qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$2" org.kde.kdeconnect.device.acceptPairing ;;
+                    *) qdbus org.kde.kdeconnect "/modules/kdeconnect/devices/$2" org.kde.kdeconnect.device.rejectPairing
+                esac
+
+}
+get_icon () {
+    if [ "$2" = "tablet" ]
+    then
+        icon=$ICON_TABLET
+    else
+        icon=$ICON_SMARTPHONE
+    fi
+    case $1 in
+    "-1")     ICON="%{F$COLOR_DISCONNECTED}$icon%{F-}" ;;
+    "-2")     ICON="%{F$COLOR_NEWDEVICE}$icon%{F-}" ;;
+    5*)     ICON="%{F$COLOR_BATTERY_50}$icon%{F-}" ;;
+    6*)     ICON="%{F$COLOR_BATTERY_60}$icon%{F-}" ;;
+    7*)     ICON="%{F$COLOR_BATTERY_70}$icon%{F-}" ;;
+    8*)     ICON="%{F$COLOR_BATTERY_80}$icon%{F-}" ;;
+    9*|100) ICON="%{F$COLOR_BATTERY_90}$icon%{F-}" ;;
+    *)      ICON="%{F$COLOR_BATTERY_LOW}$icon%{F-}" ;;
+    esac
+    echo $ICON
+}
+
+unset DEV_ID DEV_NAME DEV_BATTERY
+while getopts 'di:n:b:mp' c
+do
+    # shellcheck disable=SC2220
+    case $c in
+        d) show_devices ;;
+        i) DEV_ID=$OPTARG ;;
+        n) DEV_NAME=$OPTARG ;;
+        b) DEV_BATTERY=$OPTARG ;;
+        m) show_menu  ;;
+        p) show_pmenu ;;
+    esac
+done
+
diff --git a/bin/qwalwal.sh b/bin/qwalwal.sh
new file mode 100644 (file)
index 0000000..d0bc3f8
--- /dev/null
@@ -0,0 +1,131 @@
+#! /bin/bash
+
+# walwal.sh - set wallpaper and global color theme using pywal
+
+# uncomment for debug
+# set -x
+
+PID=$$
+PIDFILE=${PIDFILE:-/tmp/walwal.pid}
+WAIT_CYCLE="15m"
+INPUT=$1
+
+trap "rm -f $PIDFILE" SIGTERM
+
+WP_SETTER="/usr/bin/wal"
+QARMA="/usr/bin/qarma"
+EXTRAS="/home/danix/bin/wal.sh"
+
+function set_wp() {
+       NEW_WP=$1
+       $WP_SETTER -i $NEW_WP -o $EXTRAS
+}
+
+# set background function (requires input)
+function wpapers() {
+       if [[ -f $1 ]]; then
+               # We have a single file as input
+               set_wp $1
+               exit 0
+       elif [[ -d $1 ]]; then
+               # directory as input
+               while true; do
+                       BGIMG=$(find $1 -type f -print | shuf -n1)
+                       set_wp ${BGIMG}
+                       sleep $WAIT_CYCLE
+               done
+               exit 0
+       fi
+}
+
+function file_or_dir() {
+       if [[ -f /tmp/choice ]]; then
+               rm /tmp/choice
+       fi
+
+       FOD=$($QARMA --list --text="single image or directory?" --hide-header "file" "directory" > /tmp/choice)
+       case $? in
+               0 )
+                       file_chooser $(cat /tmp/choice)
+                       ;;
+               1 )
+                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                       ;;
+               -1 )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function file_chooser() {
+       case $1 in
+               "file" )
+                       FILE="$($QARMA --file-selection --title='Choose your Wallpaper')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               "directory" )
+                       FILE="$($QARMA --file-selection --directory --title='Choose your Wallpaper directory')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               * )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function run() {
+       if [[ $(basename $0) == "walwal.sh" ]]; then
+               # we were called as walwal.sh, so simple wallpaper setter without qarma interaction
+               wpapers "$1"
+       elif [[ $(basename $0) == "qwalwal.sh" ]]; then
+               # we use qarma to set the wallpaper
+               $QARMA --question --title="Change Wallpaper" --text="Do you want to change the wallpaper?"
+               case $? in
+                       0 )
+                               file_or_dir
+                               ;;
+                       1 )
+                               $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                               ;;
+                       -1 )
+                               $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+               esac
+       fi
+}
+
+if [[ -r $PIDFILE ]]; then
+       # PIDFILE exists, so I guess there's already an instance running
+       # let's kill it and run again
+       kill -s 15 $(cat $PIDFILE) > /dev/null 2>&1
+       # should already be deleted by trap, but just to be sure
+       rm /tmp/choice || true
+       rm $PIDFILE
+fi
+
+# create PIDFILE
+echo $PID > $PIDFILE
+
+if [[ ! -z $1 ]]; then
+    run $1
+else
+    run
+fi
+
index 5d90e5faeb1f9b1eeb7c3efa2b2eb6b4d21c6074..e8d1a80bb56db469bfb701d2f7c134e3ae9dd72a 100644 (file)
@@ -1,12 +1,37 @@
 #!/bin/bash
 
-# Terminate already running bar instances
-killall -q polybar
-# If all your bars have ipc enabled, you can also use
-# polybar-msg cmd quit
+if [ ! -z $1 ]; then
+    case "$1" in
+        "off")
+            kill $(cat /tmp/hideIt-*.pid)
+            killall -q polybar
+            killall stalonetray
+            ;;
+        *)
+            false
+            ;;
+    esac
+else
+    # Terminate already running bar instances
+    killall -q polybar
+    # If all your bars have ipc enabled, you can also use
+    # polybar-msg cmd quit
 
-# Launch Polybar, using default config location ~/.config/polybar/config.ini
-polybar top -r --config=/home/danix/.config/polybar/config.ini 2>&1 | tee -a /tmp/polybar-top.log & disown
-polybar bottom -r --config=/home/danix/.config/polybar/config.ini 2>&1 | tee -a /tmp/polybar-bottom.log & disown
+    # Launch Polybar, using default config location ~/.config/polybar/config.ini
+    polybar top -r --config=/home/danix/.config/polybar/config 2>&1 | tee -a /tmp/polybar-top.log & disown
+    polybar bottom -r --config=/home/danix/.config/polybar/config 2>&1 | tee -a /tmp/polybar-bottom.log & disown
+    echo "Polybar launched..."
+
+    # running stalonetray
+    # terminate previous instances
+    killall stalonetray
+
+    # launch stalonetray
+    stalonetray & disown
+
+    if [ -x ~/bin/hidebars.sh ]; then
+        sleep 1
+        ~/bin/hidebars.sh
+    fi
+fi
 
-logger "Polybar launched..."
old mode 100755 (executable)
new mode 100644 (file)
index 65e7728b08f1b845374f1c7488aa90319e8d6d96..080dd2f42ac467c7337b8d2cf5a842fef451696e 100644 (file)
@@ -33,3 +33,4 @@ if [ $1 ]; then
                        ;;
        esac
 fi
+
diff --git a/bin/speedtest b/bin/speedtest
new file mode 100644 (file)
index 0000000..44c03da
Binary files /dev/null and b/bin/speedtest differ
diff --git a/bin/superenalotto.sh b/bin/superenalotto.sh
new file mode 100644 (file)
index 0000000..fe3af27
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+#declare -A numbers
+#declare -a sorted_numbers
+
+#for i in {1..6}
+#do
+#  while true
+#  do
+#    number=$((RANDOM % 90 + 1))
+#    if [[ ! -v numbers[$number] ]]; then
+#      numbers[$number]=1
+#      break
+#    fi
+#  done
+#done
+
+#for key in "${!numbers[@]}"
+#do
+#  sorted_numbers+=("$key")
+#done
+
+#IFS=$'\n' sorted_numbers=($(sort <<<"${sorted_numbers[*]}"))
+#unset IFS
+
+#for number in "${sorted_numbers[@]}"
+#do
+#  echo $number
+#done
+
+
+# Genera 6 numeri casuali compresi tra 1 e 90
+numbers=$(shuf -i 1-90 -n 6 | sort -n)
+
+# Stampa i numeri in ordine crescente
+echo "I numeri casuali sono: $numbers"
+
diff --git a/bin/symbols.sh b/bin/symbols.sh
new file mode 100644 (file)
index 0000000..d97e179
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/bin/env bash
+
+recently_used_file=~/.cache/recent-symbols
+symbols_folder=~/.config/rofi/rofi-symbols
+
+rofi_copy=false
+
+main() {
+    prompt="symbols"
+
+    if $rofi_copy
+    then
+        prompt="$prompt (copy)"
+    fi
+    echo -en "\0prompt\x1f$prompt\n"
+
+    recent=""
+    if [[ -f "$recently_used_file" ]]
+    then
+        recent=$(cat "$recently_used_file")
+    fi
+
+    if [[ "$*" ]]
+    then
+        output=$(echo "$*" | sed 's/ .*$//')
+
+        if $rofi_copy
+        then
+            coproc { sleep 0.1; \
+                printf "%s""$output" | xclip -selection clipboard; }
+        else
+            coproc { sleep 0.3; \
+                xdotool type "$output" > /dev/null; }
+        fi
+        
+        first=$(echo "$recent" | head -n 1 | sed 's/ .*$//')
+
+        if [[ "$first" != "$output" ]]
+        then
+            new_recent=""
+            if [[ "$recent" == *"$output"* ]]
+            then
+                new_recent=$(printf "%s\n" "$*"; echo "$recent")
+                new_recent=$(echo "$new_recent" | awk '! a[$0]++')
+            else
+                new_recent=$(printf "%s\n" "$*"; echo "$recent")
+            fi
+
+            echo "$new_recent" | head -n 5 > "$recently_used_file"
+        fi
+
+        exit 0
+    fi
+
+    display_recent=""
+    if [[ "$recent" ]]
+    then
+        display_recent=$(printf "%s\n" "$recent" | head -n 5; \
+            printf "%s" "\n ""\0""nonselectable\x1ftrue\n")
+    fi
+
+    display_symbols=$(cat "$symbols_folder"/*.symbols | grep "^[^#]")
+
+    if [[ "$display_symbols" ]]
+    then
+        echo -en "$display_recent""$display_symbols"\
+            | awk '! a[$0]++'
+    else
+        echo -en "\0message\x1fno symbols found in ""$symbols_folder"
+    fi
+}
+
+if [[ "$1" == "copy" ]]
+then
+    rofi_copy=true
+    main "${@:2}"
+else
+    rofi_copy=false
+    main "$@"
+fi
diff --git a/bin/wal.sh b/bin/wal.sh
new file mode 100644 (file)
index 0000000..079c88c
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# Symlink dunst config
+ln -sf ~/.cache/wal/dunstrc ~/.config/dunst/dunstrc
+# Restart dunst with the new color scheme
+pkill dunst
+dunst &
+
+# restart stalonetray
+pkill stalonetray
+stalonetray &
+
+# run walogram to update telegram theme
+~/bin/walogram &
+
+# update firefox theme
+pywalfox update
+
+# link background image to be used by firefox
+IMG=$(cat ~/.cache/wal/wal)
+FNAME=$(basename -- $IMG)
+EXT="${FNAME##*.}"
+ln -sf $IMG ~/.cache/wal/wpaper.${EXT}
+
+kill $(cat /tmp/hideIt-*.pid) || true
+sleep 1
+hideIt.sh --name "^polybar-top_VGA-1$" --hover --peek 3 --direction top --steps 25 & disown
+hideIt.sh --name "^polybar-bottom_VGA-1$" --hover --peek 3 --direction bottom --steps 25 & disown
+hideIt.sh --name "^stalonetray$" --region 0x120+0+300 --peek 3 --direction left --steps 25 & disown
+
diff --git a/bin/wallpaper.sh b/bin/wallpaper.sh
new file mode 100644 (file)
index 0000000..e3d293a
--- /dev/null
@@ -0,0 +1,127 @@
+#! /bin/bash
+
+# uncomment for debug
+# set -x
+
+PID=$$
+PIDFILE=${PIDFILE:-/tmp/wallpaper.pid}
+WAIT_CYCLE="5m"
+INPUT=$1
+
+trap "rm -f $PIDFILE" SIGTERM
+
+WP_SETTER="/usr/bin/feh"
+QARMA="/usr/bin/qarma"
+
+function set_wp() {
+       NEW_WP=$1
+       $WP_SETTER --bg-fill $NEW_WP
+}
+
+# set background function (requires input)
+function wpapers() {
+       if [[ -f $1 ]]; then
+               # We have a single file as input
+               set_wp $1
+               exit 0
+       elif [[ -d $1 ]]; then
+               # directory as input
+               while true; do
+                       BGIMG=$(find $1 -type f -print | shuf -n1)
+                       set_wp ${BGIMG}
+                       sleep $WAIT_CYCLE
+               done
+       fi
+}
+
+function file_or_dir() {
+       if [[ -f /tmp/choice ]]; then
+               rm /tmp/choice
+       fi
+
+       FOD=$($QARMA --list --text="single image or directory?" --hide-header "file" "directory" > /tmp/choice)
+       case $? in
+               0 )
+                       file_chooser $(cat /tmp/choice)
+                       ;;
+               1 )
+                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                       ;;
+               -1 )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function file_chooser() {
+       case $1 in
+               "file" )
+                       FILE="$($QARMA --file-selection --title='Choose your Wallpaper')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               "directory" )
+                       FILE="$($QARMA --file-selection --directory --title='Choose your Wallpaper directory')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               * )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function run() {
+       if [[ $(basename $0) == "wallpaper.sh" ]]; then
+               # we were called as wallpaper.sh, so simple wallpaper setter without qarma interaction
+               wpapers "$1"
+       elif [[ $(basename $0) == "change_wallpaper.sh" ]]; then
+               # we use qarma to set the wallpaper
+               $QARMA --question --title="Change Wallpaper" --text="Do you want to change the wallpaper?"
+               case $? in
+                       0 )
+                               file_or_dir
+                               ;;
+                       1 )
+                               $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                               ;;
+                       -1 )
+                               $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+               esac
+       fi
+}
+
+if [[ -r $PIDFILE ]]; then
+       # PIDFILE exists, so I guess there's already an instance running
+       # let's kill it and run again
+       kill -s 15 $(cat $PIDFILE) > /dev/null 2>&1
+       # should already be deleted by trap, but just to be sure
+       rm /tmp/choice || true
+       rm $PIDFILE
+fi
+
+# create PIDFILE
+echo $PID > $PIDFILE
+
+if [[ ! -z $1 ]]; then
+    run $1
+else
+    run
+fi
+
diff --git a/bin/walogram b/bin/walogram
new file mode 100644 (file)
index 0000000..0229630
--- /dev/null
@@ -0,0 +1,173 @@
+#!/usr/bin/env bash
+
+# walogram - generate telegram-desktop themes
+# based on generated by wal or user defined colors
+
+# originally written by Guillaume Boehm <guillaumeboehm@hotmail.fr> in 2021
+# rewritten by Zubarev Grigoriy <thirtysix@thirtysix.pw> in 2023
+# this program is provided free of charge and without warranty
+
+cachedir="${XDG_CACHE_HOME:-$HOME/.cache}/walogram"
+themename="wal.tdesktop-theme"
+constants="/usr/local/share/walogram/constants.tdesktop-theme"
+
+msg() {
+       printf "\e[1;34m ::\e[0m %s\\n" "$@"
+}
+
+error() {
+       printf "\e[1;31m ::\e[0m %s\\n" "$@" >&2
+       exit 1
+}
+
+gencolors() {
+       colors="0 1 2 3 4 5 7 8 9 10 11 12 13 14 15"
+       divisions="10 20 30 40 50 60 70 80 90"
+       alphas="00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee"
+
+       for i in $colors; do
+               color="color$i"
+               c_rgb_12d=$((0x"${!color:1:2}"))
+               c_rgb_34d=$((0x"${!color:3:2}"))
+               c_rgb_56d=$((0x"${!color:5:2}"))
+
+               for division in $divisions; do
+                       # lighter variants
+                       c_r=$((c_rgb_12d + (c_rgb_12d * (division / 10) / 10)))
+                       c_g=$((c_rgb_34d + (c_rgb_34d * (division / 10) / 10)))
+                       c_b=$((c_rgb_56d + (c_rgb_56d * (division / 10) / 10)))
+                       [ "$c_r" -ge 255 ] && c_r=255
+                       [ "$c_g" -ge 255 ] && c_g=255
+                       [ "$c_b" -ge 255 ] && c_b=255
+                       c_hex_r="$(printf "%x" "$c_r")"
+                       c_hex_g="$(printf "%x" "$c_g")"
+                       c_hex_b="$(printf "%x" "$c_b")"
+                       [ "${#c_hex_r}" -eq 1 ] && c_hex_r="0${c_hex_r}"
+                       [ "${#c_hex_g}" -eq 1 ] && c_hex_g="0${c_hex_g}"
+                       [ "${#c_hex_b}" -eq 1 ] && c_hex_b="0${c_hex_b}"
+                       c_hex="#${c_hex_r}${c_hex_g}${c_hex_b}"
+                       eval "color${i}_lighter_${division}=${c_hex}"
+
+                       # darker variants
+                       c_r=$((c_rgb_12d - (c_rgb_12d * (division / 10) / 10)))
+                       c_g=$((c_rgb_34d - (c_rgb_34d * (division / 10) / 10)))
+                       c_b=$((c_rgb_56d - (c_rgb_56d * (division / 10) / 10)))
+                       c_hex_r="$(printf "%x" "$c_r")"
+                       c_hex_g="$(printf "%x" "$c_g")"
+                       c_hex_b="$(printf "%x" "$c_b")"
+                       [ "${#c_hex_r}" -eq 1 ] && c_hex_r="0${c_hex_r}"
+                       [ "${#c_hex_g}" -eq 1 ] && c_hex_g="0${c_hex_g}"
+                       [ "${#c_hex_b}" -eq 1 ] && c_hex_b="0${c_hex_b}"
+                       c_hex="#${c_hex_r}${c_hex_g}${c_hex_b}"
+                       eval "color${i}_darker_${division}=${c_hex}"
+               done
+       done
+
+       for i in $colors; do
+               echo "// color$i: original"
+               echo "color$i: $(eval "echo \"\$color${i}\"");"
+
+               echo "// color$i: lighter and darker variants"
+               for division in $divisions; do
+                       echo "colorLighter${i}_${division}: $(eval "echo \"\$color${i}_lighter_${division}\"");"
+                       echo "colorDarker${i}_${division}: $(eval "echo \"\$color${i}_darker_${division}\"");"
+               done
+
+               echo "// color$i: alpha variants"
+               for alpha in $alphas; do
+                       echo "colorAlpha${i}_${alpha}: $(eval "echo \"\${color${i}}${alpha}\"");"
+               done
+               printf "\\n"
+       done
+}
+
+gentheme() {
+       walname="background.jpg"
+       tempdir="$(mktemp -d)"
+       trap 'rm -rf "$tempdir"; exit 0' INT TERM EXIT
+
+       gencolors | cat - "$constants" >"$tempdir/colors.tdesktop-theme"
+
+       if command -v zip >/dev/null 2>&1; then
+               if [ "$walmode" = "solid" ]; then
+                       # $background is set by wal in colors.sh template
+                       convert -size 256x256 "xc:${bgcolor:-${background:-$color0}}" "$tempdir/$walname"
+               else
+                       case "$(file -b --mime-type "$wal")" in
+                       image/*) convert ${blur:+-blur 0x16} -resize 1920x1080 "$wal" "$tempdir/$walname" ;;
+                       *) error "not an image: $wal" ;;
+                       esac
+               fi
+               # syncing files (with '-FS') in an existing archive is faster than creating new
+               zip -jq -FS "$cachedir/$themename" "$tempdir"/*
+       else
+               msg "'zip' not found. theme generated without background image"
+               cp -f "$tempdir/colors.tdesktop-theme" "$cachedir/$themename"
+       fi
+}
+
+main() {
+       walmode="background"
+       theme="${XDG_CACHE_HOME:-$HOME/.cache}/wal/colors.sh"
+       read -r wal <"${XDG_CACHE_HOME:-$HOME/.cache}/wal/wal"
+
+       while getopts ":vhi:f:b:Bcs" opt; do
+               case "$opt" in
+               v)
+                       printf "walogram-VERSION\\n"
+                       exit 0
+                       ;;
+               h)
+                       man walogram || error "could not open man page"
+                       exit 0
+                       ;;
+               b)
+                       printf "%s" "$OPTARG" | grep -Eq "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$" || error "not a valid color code: $OPTARG"
+                       bgcolor="$OPTARG"
+                       walmode="solid"
+                       ;;
+               i) wal="$OPTARG" ;;
+               f) theme="$OPTARG" ;;
+               B) blur="true" ;;
+               c) rm -f "$cachedir"/* && msg "cache cleared" ;;
+               s) walmode="solid" ;;
+               :) error "'-$OPTARG' requires argument" ;;
+               \?) error "invalid option: '-$OPTARG'" ;;
+               esac
+       done
+
+       [ ! -f "$theme" ] && error "theme not found: $theme"
+       [ ! -f "$wal" ] && error "background image not found: $wal"
+
+       # shellcheck source=/dev/null
+       . "$theme" >/dev/null 2>&1
+       msg "colors loaded: $theme"
+
+       # ensure all 16 colors are set
+       for i in 0 1 2 3 4 5 6 7; do
+               normal="color$i"
+               bright="color$((i + 8))"
+               [ -z "$(eval "echo \"\$$normal\"")" ] && error "$normal value is missing"
+               [ -z "$(eval "echo \"\$$bright\"")" ] && {
+                       msg "$normal value used for $bright, because it is unset"
+                       eval "$bright=\$$normal"
+               }
+       done
+
+       gentheme && msg "theme generated: $themename"
+}
+
+[ ! -f "$constants" ] && error "constants file not found: $constants"
+[ -e "$cachedir" ] && [ ! -d "$cachedir" ] && error "cache directory location already exists and is not a directory: $cachedir"
+mkdir -p "$cachedir" || error "unable to create cache directory: $cachedir"
+[ ! -d "${XDG_CACHE_HOME:-$HOME/.cache}/wal" ] && error "wal cache directory not found: ${XDG_CACHE_HOME:-$HOME/.cache}/wal"
+
+if command -v magick >/dev/null 2>&1; then
+       convert() { magick convert "$@"; }
+elif ! command -v convert >/dev/null 2>&1; then
+       error "'convert' from ImageMagick not found"
+fi
+
+main "$@"
+
+# vim: ts=4 sw=4 noet ft=sh
diff --git a/bin/walwal.sh b/bin/walwal.sh
new file mode 100644 (file)
index 0000000..d0bc3f8
--- /dev/null
@@ -0,0 +1,131 @@
+#! /bin/bash
+
+# walwal.sh - set wallpaper and global color theme using pywal
+
+# uncomment for debug
+# set -x
+
+PID=$$
+PIDFILE=${PIDFILE:-/tmp/walwal.pid}
+WAIT_CYCLE="15m"
+INPUT=$1
+
+trap "rm -f $PIDFILE" SIGTERM
+
+WP_SETTER="/usr/bin/wal"
+QARMA="/usr/bin/qarma"
+EXTRAS="/home/danix/bin/wal.sh"
+
+function set_wp() {
+       NEW_WP=$1
+       $WP_SETTER -i $NEW_WP -o $EXTRAS
+}
+
+# set background function (requires input)
+function wpapers() {
+       if [[ -f $1 ]]; then
+               # We have a single file as input
+               set_wp $1
+               exit 0
+       elif [[ -d $1 ]]; then
+               # directory as input
+               while true; do
+                       BGIMG=$(find $1 -type f -print | shuf -n1)
+                       set_wp ${BGIMG}
+                       sleep $WAIT_CYCLE
+               done
+               exit 0
+       fi
+}
+
+function file_or_dir() {
+       if [[ -f /tmp/choice ]]; then
+               rm /tmp/choice
+       fi
+
+       FOD=$($QARMA --list --text="single image or directory?" --hide-header "file" "directory" > /tmp/choice)
+       case $? in
+               0 )
+                       file_chooser $(cat /tmp/choice)
+                       ;;
+               1 )
+                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                       ;;
+               -1 )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function file_chooser() {
+       case $1 in
+               "file" )
+                       FILE="$($QARMA --file-selection --title='Choose your Wallpaper')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               "directory" )
+                       FILE="$($QARMA --file-selection --directory --title='Choose your Wallpaper directory')"
+                       case $? in
+                               0 )
+                                       wpapers $FILE
+                                       ;;
+                               1 )
+                                       $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                                       ;;
+                               -1 )
+                                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       esac
+                       ;;
+               * )
+                       $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+                       ;;
+       esac
+}
+
+function run() {
+       if [[ $(basename $0) == "walwal.sh" ]]; then
+               # we were called as walwal.sh, so simple wallpaper setter without qarma interaction
+               wpapers "$1"
+       elif [[ $(basename $0) == "qwalwal.sh" ]]; then
+               # we use qarma to set the wallpaper
+               $QARMA --question --title="Change Wallpaper" --text="Do you want to change the wallpaper?"
+               case $? in
+                       0 )
+                               file_or_dir
+                               ;;
+                       1 )
+                               $QARMA --info --title="Exiting!" --text="No wallpaper was changed."
+                               ;;
+                       -1 )
+                               $QARMA --error --title="Ooops!!" --text="Something unexpected happened."
+               esac
+       fi
+}
+
+if [[ -r $PIDFILE ]]; then
+       # PIDFILE exists, so I guess there's already an instance running
+       # let's kill it and run again
+       kill -s 15 $(cat $PIDFILE) > /dev/null 2>&1
+       # should already be deleted by trap, but just to be sure
+       rm /tmp/choice || true
+       rm $PIDFILE
+fi
+
+# create PIDFILE
+echo $PID > $PIDFILE
+
+if [[ ! -z $1 ]]; then
+    run $1
+else
+    run
+fi
+