diff options
| author | filip <“filip.rabiega@gmail.com”> | 2026-01-18 11:44:26 +0100 |
|---|---|---|
| committer | filip <“filip.rabiega@gmail.com”> | 2026-01-18 11:44:26 +0100 |
| commit | 83954961af8b6337da100e038561f2fd975ac1fe (patch) | |
| tree | 33a45dbf91cc4c0b8975287b9537db8aa272505f | |
| parent | afd02bfcce54e3252d356f34c25a155c855f3612 (diff) | |
| download | chadscripts-83954961af8b6337da100e038561f2fd975ac1fe.tar.gz chadscripts-83954961af8b6337da100e038561f2fd975ac1fe.tar.bz2 chadscripts-83954961af8b6337da100e038561f2fd975ac1fe.zip | |
| -rwxr-xr-x | askpass | 6 | ||||
| -rwxr-xr-x | batterylow | 14 | ||||
| -rwxr-xr-x | bmks | 52 | ||||
| -rwxr-xr-x | brightness | 7 | ||||
| -rwxr-xr-x | cht.sh | 823 | ||||
| -rwxr-xr-x | dbdb | 2 | ||||
| -rwxr-xr-x | dictloop | 18 | ||||
| -rwxr-xr-x | dmenu-translate | 150 | ||||
| -rwxr-xr-x | dpass | 5 | ||||
| -rwxr-xr-x | dtrans | 146 | ||||
| -rwxr-xr-x | dz-feed | 7 | ||||
| -rwxr-xr-x | echovol | 10 | ||||
| -rwxr-xr-x | engadd | 3 | ||||
| -rwxr-xr-x | extract_pdfs | 33 | ||||
| -rwxr-xr-x | inpath | 50 | ||||
| -rwxr-xr-x | logrm | 8 | ||||
| -rwxr-xr-x | lsn | 4 | ||||
| -rwxr-xr-x | maimpick | 2 | ||||
| -rwxr-xr-x | mounter | 119 | ||||
| -rwxr-xr-x | newnote | 22 | ||||
| -rwxr-xr-x | newscript | 26 | ||||
| -rwxr-xr-x | remaps | 2 | ||||
| -rwxr-xr-x | rmw | 16 | ||||
| -rwxr-xr-x | rotdir | 12 | ||||
| -rwxr-xr-x | rssadd | 4 | ||||
| -rwxr-xr-x | rssget | 117 | ||||
| -rwxr-xr-x | saferm | 30 | ||||
| -rwxr-xr-x | scan | 6 | ||||
| -rwxr-xr-x | sysact | 36 | ||||
| -rwxr-xr-x | todo | 16 | ||||
| -rwxr-xr-x | tst | 3 | ||||
| -rwxr-xr-x | unix | 4 | ||||
| -rwxr-xr-x | via | 18 | ||||
| -rwxr-xr-x | via-feed | 15 | ||||
| -rwxr-xr-x | via-menu | 2 | ||||
| -rwxr-xr-x | via-open | 100 | ||||
| -rwxr-xr-x | viaup | 7 | ||||
| -rwxr-xr-x | volume | 8 | ||||
| -rwxr-xr-x | wrocwttr | 10 |
39 files changed, 1591 insertions, 322 deletions
@@ -0,0 +1,6 @@ +#!/bin/sh + +# This script is the SUDO_ASKPASS variable, meaning that it will be used as a +# password prompt if needed. + +dmenu -fn Monospace-18 -P -p "$1" <&- && echo diff --git a/batterylow b/batterylow new file mode 100755 index 0000000..cf081d1 --- /dev/null +++ b/batterylow @@ -0,0 +1,14 @@ +#!/bin/sh + +# those variables may be unnecessary +export DISPLAY=:0 +export HOME=/home/filipek + +percentage=$(upower -i "$(upower -e | grep BAT)" | + awk '/percentage/ {gsub(/%/, "", $2); print $2}') + +if [ "$percentage" -le 5 ]; then + notify-send "Battery very low." +elif [ "$percentage" -ge 14 ] && [ "$percentage" -le 15 ]; then + notify-send "Battery low." +fi @@ -10,7 +10,7 @@ URL_FILE_PATH="$HOME/.config/bmks" URL_FILE_NAME="urls" show_usage() { - printf "bmks: unix bookmark management that sucks less + printf "bmks: unix bookmark management that sucks less usage: bmks help @@ -32,47 +32,47 @@ If you would prefer to have your bookmarks stored in alternate location there ar } bmks_add() { - [ -z "$url" ] && printf "Error: url must be provided\n\n" && show_usage && exit 0 - printf "Description: " - read -r description - [ -z "$description" ] && echo "$url" >> $URL_FILE_PATH/$URL_FILE_NAME - [ -n "$description" ] && echo "$description - $url" >> $URL_FILE_PATH/$URL_FILE_NAME + [ -z "$url" ] && printf "Error: url must be provided\n\n" && show_usage && exit 0 + printf "Description: " + read -r description + [ -z "$description" ] && echo "$url" >> $URL_FILE_PATH/$URL_FILE_NAME + [ -n "$description" ] && echo "$description - $url" >> $URL_FILE_PATH/$URL_FILE_NAME } bmks_ls() { - bmks_check - cat $URL_FILE_PATH/$URL_FILE_NAME | sort + bmks_check + cat $URL_FILE_PATH/$URL_FILE_NAME | sort } bmks_del() { - bmks_check - case $PREFERED_LAUNCHER in - dmenu) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 )/d" $URL_FILE_PATH/$URL_FILE_NAME ;; - fzf) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf)/d" $URL_FILE_PATH/$URL_FILE_NAME ;; - esac + bmks_check + case $PREFERED_LAUNCHER in + dmenu) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 )/d" $URL_FILE_PATH/$URL_FILE_NAME ;; + fzf) sed -i "/$(cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf)/d" $URL_FILE_PATH/$URL_FILE_NAME ;; + esac } bmks_display() { - bmks_check - case $PREFERED_LAUNCHER in - dmenu) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;; - fzf) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;; - esac + bmks_check + case $PREFERED_LAUNCHER in + dmenu) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | dmenu -i -l 15 | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;; + fzf) cat $URL_FILE_PATH/$URL_FILE_NAME | sort | fzf | awk '{print $(NF)}' | xargs -I '{}' $BROWSER {} ;; + esac } bmks_check() { - [ ! -s $URL_FILE_PATH/$URL_FILE_NAME ] && printf "Error: No bookmarks found to display. Try adding some!\n\n" && show_usage && exit 0 + [ ! -s $URL_FILE_PATH/$URL_FILE_NAME ] && printf "Error: No bookmarks found to display. Try adding some!\n\n" && show_usage && exit 0 } [ ! -d $URL_FILE_PATH ] && mkdir $URL_FILE_PATH [ ! -f $URL_FILE_PATH/$URL_FILE_NAME ] && touch $URL_FILE_PATH/$URL_FILE_NAME case "$1" in - "help") show_usage ;; - "add") url=$2; bmks_add ;; - "del") bmks_del ;; - "ls") bmks_ls ;; - "dmenu") PREFERED_LAUNCHER=$1; bmks_display ;; - "fzf") PREFERED_LAUNCHER=$1; bmks_display ;; - *) bmks_display ;; + "help") show_usage ;; +"add") url=$2; bmks_add ;; +"del") bmks_del ;; +"ls") bmks_ls ;; +"dmenu") PREFERED_LAUNCHER=$1; bmks_display ;; +"fzf") PREFERED_LAUNCHER=$1; bmks_display ;; +*) bmks_display ;; esac @@ -1,5 +1,6 @@ #!/bin/sh -monitor="eDP-1" - -xrandr --output $monitor --brightness "$1" +case "$1" in + up) sudo brightnessctl s "10%+" ;; + down) sudo brightnessctl s "10%-" ;; +esac @@ -0,0 +1,823 @@ +#!/bin/bash +# shellcheck disable=SC1117,SC2001 +# +# [X] open section +# [X] one shot mode +# [X] usage info +# [X] dependencies check +# [X] help +# [X] yank/y/copy/c +# [X] Y/C +# [X] eof problem +# [X] more +# [X] stealth mode +# +# here are several examples for the stealth mode: +# +# zip lists +# list permutation +# random list element +# reverse a list +# read json from file +# append string to a file +# run process in background +# count words in text counter +# group elements list + +__CHTSH_VERSION=0.0.4 +__CHTSH_DATETIME="2021-04-25 12:30:30 +0200" + +# cht.sh configuration loading +# +# configuration is stored in ~/.cht.sh/ (can be overridden with CHTSH env var.) +# +CHTSH_HOME=${CHTSH:-"$HOME"/.cht.sh} +[ -z "$CHTSH_CONF" ] && CHTSH_CONF=$CHTSH_HOME/cht.sh.conf +# shellcheck disable=SC1090,SC2002 +[ -e "$CHTSH_CONF" ] && source "$CHTSH_CONF" +[ -z "$CHTSH_URL" ] && CHTSH_URL=https://cht.sh + +# currently we support only two modes: +# * lite = access the server using curl +# * auto = try standalone usage first +CHTSH_MODE="$(cat "$CHTSH_HOME"/mode 2>/dev/null)" +[ "$CHTSH_MODE" != lite ] && CHTSH_MODE=auto +CHEATSH_INSTALLATION="$(cat "$CHTSH_HOME/standalone" 2>/dev/null)" + +export LESSSECURE=1 +STEALTH_MAX_SELECTION_LENGTH=5 + +case "$(uname -s)" in + Darwin) is_macos=yes ;; + *) is_macos=no ;; +esac + +# for KSH93 +# shellcheck disable=SC2034,SC2039,SC2168 +if echo "$KSH_VERSION" | grep -q ' 93' && ! local foo 2>/dev/null; then + alias local=typeset +fi + +fatal() { + echo "ERROR: $*" >&2 + exit 1 +} + +_say_what_i_do() { + [ -n "$LOG" ] && echo "$(date '+[%Y-%m-%d %H:%M%S]') $*" >>"$LOG" + + local this_prompt="\033[0;1;4;32m>>\033[0m" + printf "\n${this_prompt}%s\033[0m\n" " $* " +} + +cheatsh_standalone_install() { + # the function installs cheat.sh with the upstream repositories + # in the standalone mode + local installdir + installdir="$1" + local default_installdir="$HOME/.cheat.sh" + + [ -z "$installdir" ] && installdir=${default_installdir} + + if [ "$installdir" = help ]; then + cat <<EOF +Install cheat.sh in the standalone mode. + +After the installation, cheat.sh can be used locally, without accessing +the public cheat.sh service, or it can be used in the server mode, +where the newly installed server could be accessed by external clients +in the same fashion as the public cheat.sh server. + +During the installation, cheat.sh code as well as the cheat.sh upstream +cheat sheets repositories will be fetched. + +It takes approximately 1G of the disk space. + +Default installation location: ~/.cheat.sh/ +It can be overridden by a command line parameter to this script: + + ${0##*/} --standalone-install DIR + +See cheat.sh/:standalone or https://github.com/chubin/cheat.sh/README.md +for more information: + + cht.sh :standalone + curl cheat.sh/:standalone + +After the installation is finished, the cht.sh shell client is switched +to the auto mode, where it uses the local cheat.sh installation if possible. +You can switch the mode with the --mode switch: + + cht.sh --mode lite # use https://cheat.sh/ only + cht.sh --mode auto # use local installation + +For intallation and standalone usage, you need \`git\`, \`python\`, +and \`virtualenv\` to be installed locally. +EOF + return + fi + + local _exit_code=0 + + local dependencies=(python git virtualenv) + for dep in "${dependencies[@]}"; do + command -v "$dep" >/dev/null || + { + echo "DEPENDENCY: \"$dep\" is needed to install cheat.sh in the standalone mode" >&2 + _exit_code=1 + } + done + [ "$_exit_code" -ne 0 ] && return "$_exit_code" + + while true; do + local _installdir + echo -n "Where should cheat.sh be installed [$installdir]? " + read -r _installdir + [ -n "$_installdir" ] && installdir=$_installdir + + if [ "$installdir" = y ] || + [ "$installdir" = Y ] || + [ "$(echo "$installdir" | tr "[:upper:]" "[:lower:]")" = yes ]; then + echo Please enter the directory name + echo If it was the directory name already, please prepend it with \"./\": "./$installdir" + else + break + fi + done + + if [ -e "$installdir" ]; then + echo "ERROR: Installation directory [$installdir] exists already" + echo "Please remove it first before continuing" + return 1 + fi + + if ! mkdir -p "$installdir"; then + echo "ERROR: Could not create the installation directory \"$installdir\"" + echo "ERROR: Please check the permissions and start the script again" + return 1 + fi + + local space_needed=700 + local space_available + space_available=$(($(df -k "$installdir" | awk '{print $4}' | tail -1) / 1024)) + + if [ "$space_available" -lt "$space_needed" ]; then + echo "ERROR: Installation directory has no enough space (needed: ${space_needed}M, available: ${space_available}M" + echo "ERROR: Please clean up and start the script again" + rmdir "$installdir" + return 1 + fi + + _say_what_i_do Cloning cheat.sh locally + local url=https://github.com/chubin/cheat.sh + rmdir "$installdir" + git clone "$url" "$installdir" || fatal Could not clone "$url" with git into "$installdir" + cd "$installdir" || fatal "Cannot cd into $installdir" + + # after the repository cloned, we may have the log directory + # and we can write our installation log into it + mkdir -p "log/" + LOG="$PWD/log/install.log" + + # we use tee everywhere so we should set -o pipefail + set -o pipefail + + # currently the script uses python 2, + # but cheat.sh supports python 3 too + # if you want to switch it to python 3 + # set PYTHON2 to NO: + # PYTHON2=NO + # + PYTHON2=NO + if [[ $PYTHON2 == YES ]]; then + python="python2" + pip="pip" + virtualenv_python3_option=() + else + python="python3" + pip="pip3" + virtualenv_python3_option=(-p python3) + fi + + _say_what_i_do Creating virtual environment + virtualenv "${virtualenv_python3_option[@]}" ve || + fatal "Could not create virtual environment with 'virtualenv ve'" + + export CHEATSH_PATH_WORKDIR=$PWD + + # rapidfuzz does not support Python 2, + # so if we are using Python 2, install fuzzywuzzy instead + if [[ $PYTHON2 == YES ]]; then + sed -i s/rapidfuzz/fuzzywuzzy/ requirements.txt + echo "python-Levenshtein" >>requirements.txt + fi + + _say_what_i_do Installing python requirements into the virtual environment + ve/bin/"$pip" install -r requirements.txt >"$LOG" || + { + + echo "ERROR:" + echo "---" + tail -n 10 "$LOG" + echo "---" + echo "See $LOG for more" + fatal Could not install python dependencies into the virtual environment + } + echo "$(ve/bin/"$pip" freeze | wc -l) dependencies were successfully installed" + + _say_what_i_do Fetching the upstream cheat sheets repositories + ve/bin/python lib/fetch.py fetch-all | tee -a "$LOG" + + _say_what_i_do Running self-tests + ( + cd tests || exit + + if CHEATSH_TEST_STANDALONE=YES \ + CHEATSH_TEST_SKIP_ONLINE=NO \ + CHEATSH_TEST_SHOW_DETAILS=NO \ + PYTHON=../ve/bin/python bash run-tests.sh | tee -a "$LOG"; then + printf "\033[0;32m%s\033[0m\n" "SUCCESS" + else + printf "\033[0;31m%s\033[0m\n" "FAILED" + echo "Some tests were failed. Run the tests manually for further investigation:" + echo " cd $PWD; bash run-tests.sh)" + fi + ) + + mkdir -p "$CHTSH_HOME" + echo "$installdir" >"$CHTSH_HOME/standalone" + echo auto >"$CHTSH_HOME/mode" + + _say_what_i_do Done + + local v1 + v1=$(printf "\033[0;1;32m") + local v2 + v2=$(printf "\033[0m") + + cat <<EOF | sed "s/{/$v1/; s/}/$v2/" + +{ _ } +{ \\ \\ } The installation is successfully finished. +{ \\ \\ } +{ / / } Now you can use cheat.sh in the standalone mode, +{ /_/ } or you can start your own cheat.sh server. + + +Now the cht.sh shell client is switched to the auto mode, where it uses +the local cheat.sh installation if possible. +You can switch the mode with the --mode switch: + + cht.sh --mode lite # use https://cheat.sh/ only + cht.sh --mode auto # use local installation + +You can add your own cheat sheets repository (config is in \`etc/config.yaml\`), +or create new cheat sheets adapters (in \`lib/adapters\`). + +To update local copies of cheat sheets repositores on a regular basis, +add the following line to your user crontab (crontab -e): + + 10 * * * * $installdir/ve/bin/python $installdir/lib/fetch.py update-all + +All cheat sheets will be automatically actualized each hour. + +If you are running a server reachable from the Internet, it can be instantly +notified via a HTTP request about any cheat sheets changes. For that, please +open an issue on the cheat.sh project repository [github.com/chubin/cheat.sh] +with the ENTRY-POINT from the URL https://ENTRY-POINT/:actualize specified +EOF +} + +chtsh_mode() { + local mode="$1" + + local text + text=$( + echo " auto use the standalone installation first" + echo " lite use the cheat sheets server directly" + ) + + if [ -z "$mode" ]; then + echo "current mode: $CHTSH_MODE ($(printf "%s" "$text" | grep "$CHTSH_MODE" | sed "s/$CHTSH_MODE//; s/^ *//; s/ \+/ /"))" + if [ -d "$CHEATSH_INSTALLATION" ]; then + echo "cheat.sh standalone installation: $CHEATSH_INSTALLATION" + else + echo 'cheat.sh standalone installation not found; falling back to the "lite" mode' + fi + elif [ "$mode" = auto ] || [ "$mode" = lite ]; then + if [ "$mode" = "$CHTSH_MODE" ]; then + echo "The configured mode was \"$CHTSH_MODE\"; nothing changed" + else + mkdir -p "$CHTSH_HOME" + echo "$mode" >"$CHTSH_HOME/mode" + echo "Configured mode: $mode" + fi + else + echo "Unknown mode: $mode" + echo Supported modes: + echo " auto use the standalone installation first" + echo " lite use the cheat sheets server directly" + fi +} + +get_query_options() { + local query="$*" + if [ -n "$CHTSH_QUERY_OPTIONS" ]; then + case $query in + *\?*) query="$query&${CHTSH_QUERY_OPTIONS}" ;; + *) query="$query?${CHTSH_QUERY_OPTIONS}" ;; + esac + fi + printf "%s" "$query" +} + +do_query() { + local query="$*" + local b_opts= + local uri="${CHTSH_URL}/\"\$(get_query_options $query)\"" + + if [ -e "$CHTSH_HOME/id" ]; then + b_opts='-b "$CHTSH_HOME/id"' + fi + + eval curl "$b_opts" -s "$uri" >"$TMP1" + + if [ -z "$lines" ] || [ "$(wc -l "$TMP1" | awk '{print $1}')" -lt "$lines" ]; then + cat "$TMP1" + else + ${PAGER:-$defpager} "$TMP1" + fi +} + +prepare_query() { + local section="$1" + shift + local input="$1" + shift + local arguments="$1" + + local query + if [ -z "$section" ] || [ x"${input}" != x"${input#/}" ]; then + query=$(printf %s "$input" | sed 's@ @/@; s@ @+@g') + else + query=$(printf %s "$section/$input" | sed 's@ @+@g') + fi + + [ -n "$arguments" ] && arguments="?$arguments" + printf %s "$query$arguments" +} + +get_list_of_sections() { + curl -s "${CHTSH_URL}"/:list | grep -v '/.*/' | grep '/$' | xargs +} + +gen_random_str() ( + len=$1 + if command -v openssl >/dev/null; then + openssl rand -base64 $((len * 3 / 4)) | awk -v ORS='' // + else + rdev=/dev/urandom + for d in /dev/{srandom,random,arandom}; do + test -r "$d" && rdev=$d + done + if command -v hexdump >/dev/null; then + hexdump -vn $((len / 2)) -e '1/1 "%02X" 1 ""' "$rdev" + elif command -v xxd >/dev/null; then + xxd -l $((len / 2)) -ps "$rdev" | awk -v ORS='' // + else + cd /tmp || { + echo Cannot cd into /tmp >&2 + exit 1 + } + s= + # shellcheck disable=SC2000 + while [ "$(echo "$s" | wc -c)" -lt "$len" ]; do + s="$s$(mktemp -u XXXXXXXXXX)" + done + printf "%.${len}s" "$s" + fi + fi +) + +if [ "$CHTSH_MODE" = auto ] && [ -d "$CHEATSH_INSTALLATION" ]; then + curl() { + # ignoring all options + # currently the standalone.py does not support them anyway + local opt + while getopts "b:s" opt; do + : + done + shift $((OPTIND - 1)) + + local url + url="$1" + shift + PYTHONIOENCODING=UTF-8 "$CHEATSH_INSTALLATION/ve/bin/python" "$CHEATSH_INSTALLATION/lib/standalone.py" "${url#"$CHTSH_URL"}" "$@" + } +elif [ "$(uname -s)" = OpenBSD ] && [ -x /usr/bin/ftp ]; then + # any better test not involving either OS matching or actual query? + curl() { + local opt args="-o -" + while getopts "b:s" opt; do + case $opt in + b) args="$args -c $OPTARG" ;; + s) args="$args -M -V" ;; + *) + echo "internal error: unsupported cURL option '$opt'" >&2 + exit 1 + ;; + esac + done + shift $((OPTIND - 1)) + /usr/bin/ftp "$args" "$@" + } +else + command -v curl >/dev/null || { + echo 'DEPENDENCY: install "curl" to use cht.sh' >&2 + exit 1 + } + _CURL=$(command -v curl) + if [ x"$CHTSH_CURL_OPTIONS" != x ]; then + curl() { + $_CURL "${CHTSH_CURL_OPTIONS}" "$@" + } + fi +fi + +if [ "$1" = --read ]; then + read -r a || a="exit" + printf "%s\n" "$a" + exit 0 +elif [ x"$1" = x--help ] || [ -z "$1" ]; then + + n=${0##*/} + s=$(echo "$n" | sed "s/./ /"g) + + cat <<EOF +Usage: + + $n [OPTIONS|QUERY] + +Options: + + QUERY process QUERY and exit + + --help show this help + --shell [LANG] shell mode (open LANG if specified) + + --standalone-install [DIR|help] + install cheat.sh in the standalone mode + (by default, into ~/.cheat.sh/) + + --mode [auto|lite] set (or display) mode of operation + * auto - prefer the local installation + * lite - use the cheat sheet server + +EOF + exit 0 +elif [ x"$1" = x--shell ]; then + shell_mode=yes + shift +elif [ x"$1" = x--standalone-install ]; then + shift + cheatsh_standalone_install "$@" + exit "$?" +elif [ x"$1" = x--mode ]; then + shift + chtsh_mode "$@" + exit "$?" +fi + +prompt="cht.sh" +opts="" +input="" +for o; do + if [ x"$o" != x"${o#-}" ]; then + opts="${opts}${o#-}" + else + input="$input $o" + fi +done +query=$(echo "$input" | sed 's@ *$@@; s@^ *@@; s@ @/@; s@ @+@g') + +if [ "$shell_mode" != yes ]; then + curl -s "${CHTSH_URL}"/"$(get_query_options "$query")" + exit 0 +else + new_section="$1" + valid_sections=$(get_list_of_sections) + valid=no + for q in $valid_sections; do [ "$q" = "$new_section/" ] && { + valid=yes + break + }; done + + if [ "$valid" = yes ]; then + section="$new_section" + # shellcheck disable=SC2001 + this_query="$(echo "$input" | sed 's@ *[^ ]* *@@')" + this_prompt="\033[0;32mcht.sh/$section>\033[0m " + else + this_query="$input" + this_prompt="\033[0;32mcht.sh>\033[0m " + fi + if [ -n "$this_query" ] && [ -z "$CHEATSH_RESTART" ]; then + printf "$this_prompt$this_query\n" + curl -s "${CHTSH_URL}"/"$(get_query_options "$query")" + fi +fi + +if [ "$is_macos" != yes ]; then + if [ "$XDG_SESSION_TYPE" = wayland ]; then + command -v wl-copy >/dev/null || echo 'DEPENDENCY: please install "wl-copy" for "copy"' >&2 + else + command -v xsel >/dev/null || echo 'DEPENDENCY: please install "xsel" for "copy"' >&2 + fi +fi +command -v rlwrap >/dev/null || { + echo 'DEPENDENCY: install "rlwrap" to use cht.sh in the shell mode' >&2 + exit 1 +} + +mkdir -p "$CHTSH_HOME/" +lines=$(tput lines) + +if command -v less >/dev/null; then + defpager="less -R" +elif command -v more >/dev/null; then + defpager="more" +else + defpager="cat" +fi + +cmd_cd() { + if [ $# -eq 0 ]; then + section="" + else + new_section=$(echo "$input" | sed 's/cd *//; s@/*$@@; s@^/*@@') + if [ -z "$new_section" ] || [ ".." = "$new_section" ]; then + section="" + else + valid_sections=$(get_list_of_sections) + valid=no + for q in $valid_sections; do [ "$q" = "$new_section/" ] && { + valid=yes + break + }; done + if [ "$valid" = no ]; then + echo "Invalid section: $new_section" + echo "Valid sections:" + echo "$valid_sections" | + xargs printf "%-10s\n" | + tr ' ' . | + xargs -n 10 | + sed 's/\./ /g; s/^/ /' + else + section="$new_section" + fi + fi + fi +} + +cmd_copy() { + if [ -z "$DISPLAY" ]; then + echo copy: supported only in the Desktop version + elif [ -z "$input" ]; then + echo copy: Make at least one query first. + else + curl -s "${CHTSH_URL}"/"$(get_query_options "$query"?T)" >"$TMP1" + if [ "$is_macos" != yes ]; then + if [ "$XDG_SESSION_TYPE" = wayland ]; then + wl-copy <"$TMP1" + else + xsel -bi <"$TMP1" + fi + else + pbcopy <"$TMP1" + fi + echo "copy: $(wc -l "$TMP1" | awk '{print $1}') lines copied to the selection" + fi +} + +cmd_ccopy() { + if [ -z "$DISPLAY" ]; then + echo copy: supported only in the Desktop version + elif [ -z "$input" ]; then + echo copy: Make at least one query first. + else + curl -s "${CHTSH_URL}"/"$(get_query_options "$query"?TQ)" >"$TMP1" + if [ "$is_macos" != yes ]; then + if [ "$XDG_SESSION_TYPE" = wayland ]; then + wl-copy <"$TMP1" + else + xsel -bi <"$TMP1" + fi + else + pbcopy <"$TMP1" + fi + echo "copy: $(wc -l "$TMP1" | awk '{print $1}') lines copied to the selection" + fi +} + +cmd_exit() { + exit 0 +} + +cmd_help() { + cat <<EOF +help - show this help +hush - do not show the 'help' string at start anymore +cd LANG - change the language context +copy - copy the last answer in the clipboard (aliases: yank, y, c) +ccopy - copy the last answer w/o comments (cut comments; aliases: cc, Y, C) +exit - exit the cheat shell (aliases: quit, ^D) +id [ID] - set/show an unique session id ("reset" to reset, "remove" to remove) +stealth - stealth mode (automatic queries for selected text) +update - self update (only if the scriptfile is writeable) +version - show current cht.sh version +/:help - service help +QUERY - space separated query staring (examples are below) + cht.sh> python zip list + cht.sh/python> zip list + cht.sh/go> /python zip list +EOF +} + +cmd_hush() { + mkdir -p "$CHTSH_HOME/" && touch "$CHTSH_HOME/.hushlogin" && echo "Initial 'use help' message was disabled" +} + +cmd_id() { + id_file="$CHTSH_HOME/id" + + if [ id = "$input" ]; then + new_id="" + else + new_id=$(echo "$input" | sed 's/id *//; s/ *$//; s/ /+/g') + fi + if [ "$new_id" = remove ]; then + if [ -e "$id_file" ]; then + rm -f -- "$id_file" && echo "id is removed" + else + echo "id was not set, so you can't remove it" + fi + return + fi + if [ -n "$new_id" ] && [ reset != "$new_id" ] && [ "$(/bin/echo -n "$new_id" | wc -c)" -lt 16 ]; then + echo "ERROR: $new_id: Too short id. Minimal id length is 16. Use 'id reset' for a random id" + return + fi + if [ -z "$new_id" ]; then + # if new_id is not specified check if we have some id already + # if yes, just show it + # if not, generate a new id + if [ -e "$id_file" ]; then + awk '$6 == "id" {print $NF}' <"$id_file" | tail -n 1 + return + else + new_id=reset + fi + fi + if [ "$new_id" = reset ]; then + new_id=$(gen_random_str 12) + else + echo WARNING: if someone gueses your id, he can read your cht.sh search history + fi + if [ -e "$id_file" ] && grep -q '\tid\t[^\t][^\t]*$' "$id_file" 2>/dev/null; then + sed -i 's/\tid\t[^\t][^\t]*$/ id '"$new_id"'/' "$id_file" + else + if ! [ -e "$id_file" ]; then + printf '#\n\n' >"$id_file" + fi + printf ".cht.sh\tTRUE\t/\tTRUE\t0\tid\t$new_id\n" >>"$id_file" + fi + echo "$new_id" +} + +cmd_query() { + query=$(prepare_query "$section" "$input") + do_query "$query" +} + +cmd_stealth() { + if [ "$input" != stealth ]; then + arguments=$(echo "$input" | sed 's/stealth //; s/ /\&/') + fi + trap break INT + if [ "$is_macos" = yes ]; then + past=$(pbpaste) + else + if [ "$XDG_SESSION_TYPE" = wayland ]; then + past=$(wl-paste -p) + else + past=$(xsel -o) + fi + fi + printf "\033[0;31mstealth:\033[0m you are in the stealth mode; select any text in any window for a query\n" + printf "\033[0;31mstealth:\033[0m selections longer than $STEALTH_MAX_SELECTION_LENGTH words are ignored\n" + if [ -n "$arguments" ]; then + printf "\033[0;31mstealth:\033[0m query arguments: ?$arguments\n" + fi + printf "\033[0;31mstealth:\033[0m use ^C to leave this mode\n" + while true; do + if [ "$is_macos" = yes ]; then + current=$(pbpaste) + else + if [ "$XDG_SESSION_TYPE" = wayland ]; then + current=$(wl-paste -p) + else + current=$(xsel -o) + fi + fi + if [ "$past" != "$current" ]; then + past=$current + current_text="$(echo $current | tr -c '[a-zA-Z0-9]' ' ')" + if [ "$(echo "$current_text" | wc -w)" -gt "$STEALTH_MAX_SELECTION_LENGTH" ]; then + printf "\033[0;31mstealth:\033[0m selection length is longer than $STEALTH_MAX_SELECTION_LENGTH words; ignoring\n" + continue + else + printf "\n\033[0;31mstealth: \033[7m $current_text\033[0m\n" + query=$(prepare_query "$section" "$current_text" "$arguments") + do_query "$query" + fi + fi + sleep 1 + done + trap - INT +} + +cmd_update() { + [ -w "$0" ] || { + echo "The script is readonly; please update manually: curl -s ${CHTSH_URL}/:cht.sh | sudo tee $0" + return + } + TMP2=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX) + curl -s "${CHTSH_URL}"/:cht.sh >"$TMP2" + if ! cmp "$0" "$TMP2" >/dev/null 2>&1; then + if grep -q ^__CHTSH_VERSION= "$TMP2"; then + # section was vaildated by us already + args=(--shell "$section") + cp "$TMP2" "$0" && echo "Updated. Restarting..." && rm "$TMP2" && CHEATSH_RESTART=1 exec "$0" "${args[@]}" + else + echo "Something went wrong. Please update manually" + fi + else + echo "cht.sh is up to date. No update needed" + fi + rm -f "$TMP2" >/dev/null 2>&1 +} + +cmd_version() { + insttime=$(ls -l -- "$0" | sed 's/ */ /g' | cut -d ' ' -f 6-8) + echo "cht.sh version $__CHTSH_VERSION of $__CHTSH_DATETIME; installed at: $insttime" + TMP2=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX) + if curl -s "${CHTSH_URL}"/:cht.sh >"$TMP2"; then + if ! cmp "$0" "$TMP2" >/dev/null 2>&1; then + echo "Update needed (type 'update' for that)". + else + echo "Up to date. No update needed" + fi + fi + rm -f "$TMP2" >/dev/null 2>&1 +} + +TMP1=$(mktemp /tmp/cht.sh.XXXXXXXXXXXXX) +trap 'rm -f $TMP1 $TMP2' EXIT +trap 'true' INT + +if ! [ -e "$CHTSH_HOME/.hushlogin" ] && [ -z "$this_query" ]; then + echo "type 'help' for the cht.sh shell help" +fi + +while true; do + if [ "$section" != "" ]; then + full_prompt="$prompt/$section> " + else + full_prompt="$prompt> " + fi + + input=$( + rlwrap -H "$CHTSH_HOME/history" -pgreen -C cht.sh -S "$full_prompt" bash "$0" --read | sed 's/ *#.*//' + ) + + cmd_name=${input%% *} + cmd_args=${input#* } + case $cmd_name in + "") continue ;; # skip empty input lines + '?' | h | help) cmd_name=help ;; + hush) cmd_name=hush ;; + cd) cmd_name="cd" ;; + exit | quit) cmd_name="exit" ;; + copy | yank | c | y) cmd_name=copy ;; + ccopy | cc | C | Y) cmd_name=ccopy ;; + id) cmd_name=id ;; + stealth) cmd_name=stealth ;; + update) cmd_name=update ;; + version) cmd_name=version ;; + *) + cmd_name="query" + cmd_args="$input" + ;; +esac +"cmd_$cmd_name" $cmd_args +done @@ -14,5 +14,5 @@ while [ ! -z "$chosen" ]; do DOTFs=$( ls -a1p | grep -P '^\.[^\$/]+$' | awk -vRS="\n" -vORS=" \t" '1') clear && printf "\e[1;7;33m $(pwd) \e[0m\n$FILEs\n\e[0;38;5;238m$DOTFs\e[0m\n" chosen=`( ( echo -e "$DIRs$DOTDs" | awk -vRS="\t" -vORS="\n" '1' ) | dmenu -i )` - cd "$chosen" + cd "$chosen" done @@ -4,21 +4,21 @@ setopt aliases source "$ZDOTDIR/aliasrc" [ "$#" -ne 1 ] && { - echo "Usage: dictloop <dict>" >&2 - exit 1 + echo "Usage: dictloop <dict>" >&2 + exit 1 } dict="$1" # a command-line dictionary while true; do - echo "Enter a word: " - read -r word + echo "Enter a word: " + read -r word - if [ -z "$word" ] || [ "$word" = "exit" ]; then - echo "Exiting..." - exit 0 - fi + if [ -z "$word" ] || [ "$word" = "exit" ]; then + echo "Exiting..." + exit 0 + fi - "$dict" "$word" + "$dict" "$word" done exit 0 diff --git a/dmenu-translate b/dmenu-translate new file mode 100755 index 0000000..766ad51 --- /dev/null +++ b/dmenu-translate @@ -0,0 +1,150 @@ +#!/bin/sh + +echo_err() { + notify-send -u critical "$0 error" "$1" +} + +err() { + echo_err "$1" + exit 1 +} + +check_dep() { + command -v "$1" > /dev/null || err "$1 is required: $2" +} + +# We don't check if dmenu is installed because someone +# may want to replace it via DMENU vars +check_dep trans https://github.com/soimort/translate-shell +check_dep notify-send + +load_config() { + config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate" + [ -d "$config_dir" ] || mkdir -p "$config_dir" + + config_file="$config_dir/config.sh" + [ -f "$config_file" ] || touch "$config_file" + + old_config_file="$config_dir/config.conf" + [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one." + + . "$config_file" + + # Check others + if [ -n "$WAYLAND_DISPLAY" ]; then + : "${CLIP_COPY:=wl-copy -n}" + : "${CLIP_PASTE_CLIP:=wl-paste}" + : "${CLIP_PASTE_PRIM:=wl-paste -p}" + : "${DMENU:=wmenu}" + : "${TERMINAL=foot}" + else + : "${CLIP_COPY:=xclip -i -r -selection clipboard}" + : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}" + : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}" + : "${DMENU:=dmenu}" + : "${TERMINAL=xterm}" + fi + + # Default values + : "${TRANS_LANGS:=:ru :en}" + : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}" + : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}" + : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}" +} + +formatmenu() { + echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/' +} + +get_selection() { + [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM" +} + +clip_menu() { + { formatmenu "$1"; formatmenu "$2"; } | + sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' | + sed '/^$/d' +} + +lang_menu() { + echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/' + echo '[Define]' +} + +choose_next() { + t="$1" + shift + if [ -n "$ALWAYS_COPY" ]; then + echo 'Copy' + else + eval "$DMENU_NEXT" "$@" <<-EOF + Copy: $(formatmenu "$t") + Copy temp file name + View + EOF + fi +} + +save_file() ( + tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')" + echo "$1" > "$tmp" + echo "$tmp" +) + +open_term() { + ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")" +} + +get_text() { + echo "$2" | while IFS= read -r clip; do + [ "$1" = "$clip" ] && { + type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')" + case "$type" in + Primary) echo "$primary" ;; + Clipboard) echo "$clipboard" ;; + esac + exit 10 + } + done + + # If not found, just echo text + [ $? -ne 10 ] && echo "$1" +} + +# Config +load_config + +# Get selections +clipboard="$(get_selection clip)" +primary="$(get_selection)" + +clip_menu="$(clip_menu "$primary" "$clipboard")" + +# Enter text +text="$(printf '%s' "$clip_menu" | eval "$DMENU_TEXT" "$@")" || exit 0 +text="$(get_text "$text" "$clip_menu")" + +# Choose target language +target="$(lang_menu | eval "$DMENU_LANG" "$@")" || exit 0 + +# If Define chosen, define term and exit +[ "$target" = '[Define]' ] && { + dict="$(trans -dictionary "$text")" + open_term "$(trans -dictionary "$text")" + exit 0 +} + +# Translate text +translation="$(trans -b "$target" "$text")" +[ -z "$translation" ] && err 'Failed to translate' + +case "$(choose_next "$translation" "$@")" in + 'View') open_term "$translation"; exit 0 ;; +'Copy temp file name') output="$(save_file "$translation")" ;; +'Copy'*) output="$translation" ;; +*) exit 0 ;; +esac + +echo "$output" | eval "$CLIP_COPY" || err 'Failed to copy! Is CLIP_COPY setting set properly?' + +notify-send 'dmenu-translate' 'Translation copied to clipboard!' @@ -1,5 +1,6 @@ #!/bin/sh -password=$(find ~/.password-store/ -type f -name '*.gpg' | - sed 's/.*\/\(.*\)\.gpg$/\1/' | dmenu -i -p "Pass:") +dir="${PASSWORD_STORE_DIR:-$HOME/.password-store}" +password=$(find "$dir" -type f -name '*.gpg' | +sed 's/.*\/\(.*\)\.gpg$/\1/' | dmenu -i -p "Pass:") [ -n "$password" ] && pass show -c "$password" @@ -1,16 +1,16 @@ #!/bin/sh echo_err() { - notify-send -u critical "$0 error" "$1" + notify-send -u critical "$0 error" "$1" } err() { - echo_err "$1" - exit 1 + echo_err "$1" + exit 1 } check_dep() { - command -v "$1" > /dev/null || err "$1 is required: $2" + command -v "$1" > /dev/null || err "$1 is required: $2" } # We don't check if dmenu is installed because someone @@ -19,96 +19,96 @@ check_dep trans https://github.com/soimort/translate-shell check_dep notify-send load_config() { - config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate" - [ -d "$config_dir" ] || mkdir -p "$config_dir" - - config_file="$config_dir/config.sh" - [ -f "$config_file" ] || touch "$config_file" - - old_config_file="$config_dir/config.conf" - [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one." - - . "$config_file" - - # Check others - if [ -n "$WAYLAND_DISPLAY" ]; then - : "${CLIP_COPY:=wl-copy -n}" - : "${CLIP_PASTE_CLIP:=wl-paste}" - : "${CLIP_PASTE_PRIM:=wl-paste -p}" - : "${DMENU:=wmenu}" - : "${TERMINAL=foot}" - else - : "${CLIP_COPY:=xclip -i -r -selection clipboard}" - : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}" - : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}" - : "${DMENU:=dmenu}" - : "${TERMINAL=xterm}" - fi - - # Default values - : "${TRANS_LANGS:=:ru :en}" - : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}" - : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}" - : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}" + config_dir="${XDG_CONFIG_HOME:-$HOME/.config}/dmenu-translate" + [ -d "$config_dir" ] || mkdir -p "$config_dir" + + config_file="$config_dir/config.sh" + [ -f "$config_file" ] || touch "$config_file" + + old_config_file="$config_dir/config.conf" + [ -f "$old_config_file" ] && notify-send "dmenu-translate warning" "Found old configuration file at <code>$old_config_file</code>, which is no longer supported. Please move your settings to a new file at <code>$config_file</code> and delete the old one." + + . "$config_file" + + # Check others + if [ -n "$WAYLAND_DISPLAY" ]; then + : "${CLIP_COPY:=wl-copy -n}" + : "${CLIP_PASTE_CLIP:=wl-paste}" + : "${CLIP_PASTE_PRIM:=wl-paste -p}" + : "${DMENU:=wmenu}" + : "${TERMINAL=foot}" + else + : "${CLIP_COPY:=xclip -i -r -selection clipboard}" + : "${CLIP_PASTE_CLIP:=xclip -o -selection clipboard}" + : "${CLIP_PASTE_PRIM:=xclip -o -selection primary}" + : "${DMENU:=dmenu}" + : "${TERMINAL=xterm}" + fi + + # Default values + : "${TRANS_LANGS:=:ru :en}" + : "${DMENU_TEXT:=${DMENU} -i -p 'Translate: Text'}" + : "${DMENU_LANG:=${DMENU} -i -p 'Translate: Into'}" + : "${DMENU_NEXT:=${DMENU} -i -p 'Translate: Next?'}" } formatmenu() { - echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/' + echo "$1" | tr '\n' ' ' | sed 's/\s\{3,\}//g; s/^\(.\{30\}\).\+/\1.../; s/$/\n/' } get_selection() { - [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM" + [ -n "$1" ] && eval "$CLIP_PASTE_CLIP" || eval "$CLIP_PASTE_PRIM" } clip_menu() { - { formatmenu "$1"; formatmenu "$2"; } | - sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' | - sed '/^$/d' + { formatmenu "$1"; formatmenu "$2"; } | + sed 's/^\s*$//; 1s/^./Primary: &/; 2s/^./Clipboard: &/' | + sed '/^$/d' } lang_menu() { - echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/' - echo '[Define]' + echo "$TRANS_LANGS" | sed 's/\s\+/\n/g' | sed '/:/!s/^/:/' + echo '[Define]' } choose_next() { - t="$1" - shift - if [ -n "$ALWAYS_COPY" ]; then - echo 'Copy' - else - eval "$DMENU_NEXT" "$@" <<-EOF + t="$1" + shift + if [ -n "$ALWAYS_COPY" ]; then + echo 'Copy' + else + eval "$DMENU_NEXT" "$@" <<-EOF Copy: $(formatmenu "$t") Copy temp file name View EOF - fi + fi } save_file() ( - tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')" - echo "$1" > "$tmp" - echo "$tmp" + tmp="$(mktemp --tmpdir 'dmenu-translate.XXXXXX')" + echo "$1" > "$tmp" + echo "$tmp" ) open_term() { - ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")" + ${TERMINAL} -e ${PAGER:-'less'} "$(save_file "$1")" } get_text() { - echo "$2" | while IFS= read -r clip; do - [ "$1" = "$clip" ] && { - type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')" - case "$type" in - Primary) echo "$primary" ;; - Clipboard) echo "$clipboard" ;; - esac - exit 10 - } - done - - # If not found, just echo text - [ $? -ne 10 ] && echo "$1" + echo "$2" | while IFS= read -r clip; do + [ "$1" = "$clip" ] && { + type="$(echo "$clip" | sed 's/^\(\w\+\):.*/\1/')" + case "$type" in + Primary) echo "$primary" ;; + Clipboard) echo "$clipboard" ;; + esac + exit 10 + } + done + + # If not found, just echo text + [ $? -ne 10 ] && echo "$1" } # Config @@ -129,9 +129,9 @@ target="$(lang_menu | eval "$DMENU_LANG" "$@")" || exit 0 # If Define chosen, define term and exit [ "$target" = '[Define]' ] && { - dict="$(trans -dictionary "$text")" - open_term "$(trans -dictionary "$text")" - exit 0 + dict="$(trans -dictionary "$text")" + open_term "$(trans -dictionary "$text")" + exit 0 } # Translate text @@ -139,10 +139,10 @@ translation="$(trans -b "$target" "$text")" [ -z "$translation" ] && err 'Failed to translate' case "$(choose_next "$translation" "$@")" in - 'View') open_term "$translation"; exit 0 ;; - 'Copy temp file name') output="$(save_file "$translation")" ;; - 'Copy'*) output="$translation" ;; - *) exit 0 ;; + 'View') open_term "$translation"; exit 0 ;; +'Copy temp file name') output="$(save_file "$translation")" ;; +'Copy'*) output="$translation" ;; +*) exit 0 ;; esac echo "$output" | eval "$CLIP_COPY" || err 'Failed to copy! Is CLIP_COPY setting set properly?' @@ -3,10 +3,9 @@ cache="$HOME/.cache/dz" if [ "$1" = "-r" ] || [ ! -e "$cache" ]; then - find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | \ - sed '/\.pdf$/!d' | sort > "$cache" - - notify-send "dz cache updated." + find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | \ + sed '/\.pdf$/!d' | sort > "$cache" + # notify-send "dz cache updated." fi cat "$cache" @@ -0,0 +1,10 @@ +#!/bin/sh + +volume=$(pactl list sinks | grep -A 15 'Sink #0' | grep 'Volume:' | awk '{print $5}' | tr -d '%' | head -1) +mute=$(pactl list sinks | grep -A 15 'Sink #0' | grep 'Mute' | awk '{print $2}') + +if [ "$mute" = "yes" ]; then + echo "mute" +else + echo "$volume%" +fi @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "$1" >> "$HOME"/langs/english/obscure_words diff --git a/extract_pdfs b/extract_pdfs deleted file mode 100755 index 2fb0d49..0000000 --- a/extract_pdfs +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/zsh - -if [ "$#" -ne 2 ]; then - echo "Usage: extract_pdfs /path/to/source /path/to/destination" - exit 1 -fi - -SOURCE_DIR="$1" -DEST_DIR="$2" - -if [ ! -d "$SOURCE_DIR" ]; then - notify-send "Source directory does not exist: $SOURCE_DIR" - exit 1 -fi - -mkdir -p "$DEST_DIR" - -find "$SOURCE_DIR" -type f -iname "*.pdf" | while read -r pdf; do - filename=$(basename "$pdf") - - dest_file="$DEST_DIR/$filename" - if [ -e "$dest_file" ]; then - i=1 - while [ -e "$DEST_DIR/${filename%.*}_$i.pdf" ]; do - ((i++)) - done - dest_file="$DEST_DIR/${filename%.*}_$i.pdf" - fi - - cp "$pdf" "$dest_file" -done - -notify-send "PDF extraction complete. Files copied to: $DEST_DIR" @@ -1,43 +1,43 @@ #!/bin/sh in_path() { - cmd=$1 path=$2 res=1 - IFS=":" + cmd=$1 path=$2 res=1 + IFS=":" - for dir in $path; do - if [ -x "$dir/$cmd" ]; then - res=0 - break - fi - done + for dir in $path; do + if [ -x "$dir/$cmd" ]; then + res=0 + break + fi + done - return $res + return $res } cmd_in_path() { - var=$1 - - if [ -n "$var" ]; then - if [ "$(echo "$var" | cut -c 1)" = "/" ]; then - if [ ! -x "$var" ]; then - return 1 - fi - elif ! in_path "$var" "$PATH"; then - return 2 - fi - fi + var=$1 + + if [ -n "$var" ]; then + if [ "$(echo "$var" | cut -c 1)" = "/" ]; then + if [ ! -x "$var" ]; then + return 1 + fi + elif ! in_path "$var" "$PATH"; then + return 2 + fi + fi } if [ $# -ne 1 ]; then - echo "Usage: $0 <command>" >&2 - exit 1 + echo "Usage: $0 <command>" >&2 + exit 1 fi cmd_in_path "$1" case $? in -0) echo "$1 found in PATH" ;; -1) echo "$1 not found or not executable" ;; -2) echo "$1 not found in PATH" ;; + 0) echo "$1 found in PATH" ;; + 1) echo "$1 not found or not executable" ;; + 2) echo "$1 not found in PATH" ;; esac exit 0 @@ -3,14 +3,14 @@ removelog="/var/log/remove.log" if [ $# -eq 0 ]; then - echo "Usage: $0 [-s] list of files or directories" >&2 - exit 1 + echo "Usage: $0 [-s] list of files or directories" >&2 + exit 1 fi if [ "$1" = "-s" ]; then - shift + shift else - echo "$(date): ${USER}: $*" >>$removelog + echo "$(date): ${USER}: $*" >>$removelog fi rm -i "$@" @@ -1,9 +1,9 @@ #!/bin/sh # New and better ls -# TODO: fix simlinks, flags break them for some reason +# TODO: fix simlinks, flags break them for some reason, maybe switch to eza ls_new() { - LC_ALL=C $(which ls) -lAFh --color=always "$1" | awk '{ + LC_ALL=C $(which ls) -lAFh --color=always "$1" | awk '{ name = $9; for (i = 10; i <= NF; i++) name = name " " $i; print $1, $5, name @@ -8,7 +8,7 @@ xclip_cmd="xclip -sel clip -t image/png" ocr_cmd="xclip -sel clip" case "$(printf 'a selected area\ncurrent window\nfull screen\na selected area (copy)\ncurrent window (copy)\nfull screen (copy)\ncopy selected image to text' | dmenu -l 7 -i -p "Screenshot which area?")" in -"a selected area") maim -u -s pic-selected-"${output}" ;; + "a selected area") maim -u -s pic-selected-"${output}" ;; "current window") maim -B -q -d 0.2 -i "$(xdotool getactivewindow)" pic-window-"${output}" ;; "full screen") maim -q -d 0.2 pic-full-"${output}" ;; "a selected area (copy)") maim -u -s | ${xclip_cmd} ;; @@ -0,0 +1,119 @@ +#!/bin/bash + +# Mounts Android Phones and USB drives (encrypted or not). This script will +# replace the older `dmenumount` which had extra steps and couldn't handle +# encrypted drives. +# TODO: Try decrypt for drives in crtypttab +# TODO: Add some support for connecting iPhones (although they are annoying). + +IFS=' +' +# Function for escaping cell-phone names. +escape(){ echo "$@" | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g" ;} + +# Check for phones. +phones="$(simple-mtpfs -l 2>/dev/null | sed "s/^/📱/")" +mountedphones="$(grep "simple-mtpfs" /etc/mtab)" +# If there are already mounted phones, remove them from the list of mountables. +[ -n "$mountedphones" ] && phones="$(for phone in $phones; do + for mounted in $mountedphones; do + escphone="$(escape "$phone")" + [[ "$mounted" =~ "$escphone" ]] && break 1 + done && continue 1 + echo "$phone" +done)" + +# Check for drives. +lsblkoutput="$(lsblk -rpo "uuid,name,type,size,label,mountpoint,fstype")" +# Get all LUKS drives +allluks="$(echo "$lsblkoutput" | grep crypto_LUKS)" +# Get a list of the LUKS drive UUIDs already decrypted. +decrypted="$(find /dev/disk/by-id/dm-uuid-CRYPT-LUKS2-* | sed "s|.*LUKS2-||;s|-.*||")" +# Functioning for formatting drives correctly for dmenu: +filter() { sed "s/ /:/g" | awk -F':' '$7==""{printf "%s%s (%s) %s\n",$1,$3,$5,$6}' ; } + +# Get only LUKS drives that are not decrypted. +unopenedluks="$(for drive in $allluks; do + uuid="${drive%% *}" + uuid="${uuid//-}" # This is a bashism. + [ -n "$decrypted" ] && for open in $decrypted; do + [ "$uuid" = "$open" ] && break 1 + done && continue 1 + echo "🔒 $drive" +done | filter)" + +# Get all normal, non-encrypted or decrypted partitions that are not mounted. +normalparts="$(echo "$lsblkoutput"| grep -v crypto_LUKS | grep 'part\|rom\|crypt' | sed "s/^/💾 /" | filter )" + +# Add all to one variable. If no mountable drives found, exit. +alldrives="$(echo "$phones +$unopenedluks +$normalparts" | sed "/^$/d;s/ *$//")" + +# Quit the script if a sequential command fails. +set -e + +test -n "$alldrives" + +# Feed all found drives to dmenu and get user choice. +chosen="$(echo "$alldrives" | dmenu -p "Mount which drive?" -i)" + +# Function for prompting user for a mountpoint. +getmount(){ + mp="$(find /mnt /media /mount /home -maxdepth 1 -type d 2>/dev/null | dmenu -i -p "Mount this drive where?")" + test -n "$mp" + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") + fi +} + +attemptmount(){ + # Attempt to mount without a mountpoint, to see if drive is in fstab. + sudo -A mount "$chosen" || return 1 + notify-send "💾Drive Mounted." "$chosen mounted." + exit +} + +case "$chosen" in + 💾*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + parttype="$(echo "$lsblkoutput" | grep "$chosen")" + attemptmount || getmount + case "${parttype##* }" in + vfat) sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000 ;; + btrfs) sudo -A mount "$chosen" "$mp" ;; + *) sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)" ;; + esac + notify-send "💾Drive Mounted." "$chosen mounted to $mp." + ;; + + 🔒*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + # Number the drive. + while true; do + [ -f "/dev/mapper/usb$num" ] || break + num="$(printf "%02d" "$((num +1))")" + done + + # Decrypt in a terminal window + ${TERMINAL:-st} -n floatterm -g 60x1 -e sudo cryptsetup open "$chosen" "usb$num" + # Check if now decrypted. + test -b "/dev/mapper/usb$num" + + attemptmount || getmount + sudo -A mount "/dev/mapper/usb$num" "$mp" -o uid="$(id -u)",gid="$(id -g)" + notify-send "🔓Decrypted drive Mounted." "$chosen decrypted and mounted to $mp." + ;; + + 📱*) + notify-send "❗Note" "Remember to allow file access on your phone now." + getmount + number="${chosen%%:*}" + number="${chosen:1}" # This is a bashism. + sudo -A simple-mtpfs -o allow_other -o fsname="simple-mtpfs-$(escape "$chosen")" --device "$number" "$mp" + notify-send "🤖 Android Mounted." "Android device mounted to $mp." + ;; +esac @@ -3,20 +3,20 @@ dir="$OBSIDIAN_HOME" newnote() { - file="$dir/$1.md" - [ -f "$file" ] && { - echo "Note with the same name already exists, exiting" >&2 - exit 1 - } - touch "$file" && "$EDITOR" +2 "$file" - if [ "$(wc -l "$file" | awk '{print $1}')" -lt 2 ]; then - rm -f "$file" - fi + file="$dir/$1.md" + [ -f "$file" ] && { + echo "Note with the same name already exists, exiting" >&2 + exit 1 + } + touch "$file" && "$EDITOR" +2 "$file" + if [ "$(wc -l "$file" | awk '{print $1}')" -lt 2 ]; then + rm -f "$file" + fi } [ "$#" -ne 1 ] && { - echo "Usage: newnote <note-name>" >&2 - exit 1 + echo "Usage: newnote <note-name>" >&2 + exit 1 } newnote "$1" @@ -1,22 +1,22 @@ #!/bin/sh newscript() { - file="$HOME/.scripts/$1" - [ -f "$file" ] && { - echo "Script with the same name already exists, exiting" >&2 - exit 1 - } - touch "$file" && printf "#!/bin/sh\n\n" >"$file" && "$EDITOR" +2 "$file" - if [ "$(wc -l "$file" | awk '{print $1}')" -lt 3 ]; then - rm -f "$file" - else - chmod +x "$file" - fi + file="$HOME/.scripts/$1" + [ -f "$file" ] && { + echo "Script with the same name already exists, exiting" >&2 + exit 1 + } + touch "$file" && printf "#!/bin/sh\n\n" >"$file" && "$EDITOR" +2 "$file" + if [ "$(wc -l "$file" | awk '{print $1}')" -lt 3 ]; then + rm -f "$file" + else + chmod +x "$file" + fi } [ "$#" -ne 1 ] && { - echo "Usage: newscript <script-name>" >&2 - exit 1 + echo "Usage: newscript <script-name>" >&2 + exit 1 } newscript "$1" @@ -1,7 +1,7 @@ #!/bin/sh # Increase key speed -xset r rate 200 50 +xset r rate 200 80 # Switch caps and esc setxkbmap us -option caps:swapescape @@ -1,24 +1,24 @@ #!/bin/sh if [ "$#" -gt 1 ]; then - echo "Usage: rm_whitespaces <dir>" >&2 - exit 1 + echo "Usage: rm_whitespaces <dir>" >&2 + exit 1 fi if [ "$#" -eq 0 ]; then - dir="$(pwd)" + dir="$(pwd)" else - dir="$1" + dir="$1" fi cd "$dir" || { - echo "Couldn't cd to directory. Exiting..." >&2 - exit 1 + echo "Couldn't cd to directory. Exiting..." >&2 + exit 1 } for file in "$dir"/*; do - newname="$(echo "$file" | sed -e 's/["`”“-]*//g' -e 's/[ \t]+/\_/g')" - mv "$file" "$newname" + newname="$(echo "$file" | sed -e 's/["`”“-]*//g' -e 's/[ \t]+/\_/g')" + mv "$file" "$newname" done exit 0 @@ -0,0 +1,12 @@ +#!/bin/sh + +# When I open an image from the file manager in nsxiv (the image viewer), I want +# to be able to press the next/previous keys to key through the rest of the +# images in the same directory. This script "rotates" the content of a +# directory based on the first chosen file, so that if I open the 15th image, +# if I press next, it will go to the 16th etc. Autistic, I know, but this is +# one of the reasons that nsxiv is great for being able to read standard input. + +[ -z "$1" ] && echo "usage: rotdir regex 2>&1" && exit 1 +base="$(basename "$1")" +ls "$PWD" | awk -v BASE="$base" 'BEGIN { lines = ""; m = 0; } { if ($0 == BASE) { m = 1; } } { if (!m) { if (lines) { lines = lines"\n"; } lines = lines""$0; } else { print $0; } } END { print lines; }' @@ -1,9 +1,9 @@ #!/bin/sh if echo "$1" | grep -q "https*://\S\+\.[A-Za-z]\+\S*"; then - url="$1" + url="$1" else - url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" | + url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" | grep -o 'https?://[^" ]')" echo "$url" | grep -q "https*://\S\+\.[A-Za-z]\+\S*" || @@ -0,0 +1,117 @@ +#!/bin/bash + +# Searches the website for RSS feeds and adds them to newsboat url list. Can +# also find hidden RSS feeds on various websites, namely Youtube, Reddit, +# Vimeo, Github, Gitlab and Medium. Gets site url as $1 or (if not present) +# from X clipboard. Gets tags as $2. If it finds more than one feed, calls +# dmenu for the user to choose which one to add. I have bound it to a keyboard +# shortcut so i copy a site link and easily add its feed to the reader. + +# Inspired by and based on the logic of this extension: +# https://github.com/shevabam/get-rss-feed-url-extension + +# This script requires rssadd to add feeds to the list. + +getlink () { + local url="$1" + feeds="$(curl -s "$url" | grep -Ex '.*type=.*(rss|rdf|atom).*' | sed 's/ //g')" + url="$(echo $url | sed 's|^\(https://[^/]*/\).*|\1|')" + + for rsspath in $feeds; do + rsspath="$(echo $rsspath | sed -n "s|.*href=['\"]\([^'\"]*\)['\"].*|\1|p")" + if echo "$rsspath" | grep "http" > /dev/null; then + link="$rsspath" + elif echo "$rsspath" | grep -E "^/" > /dev/null; then + link="$url$(echo $rsspath | sed 's|^/||')" + else + link="$url$rsspath" + fi + echo $link + done +} + +getRedditRss() { + echo "${1%/}.rss" +} + +getYoutubeRss() { + local url="$1" + path=$(echo "$url" | sed -e 's|^http[s]*://||') + case "$path" in + *"/channel/"*) channel_id="$(echo $path | sed -r 's|.*channel/([^/]*).*|\1|')" && feed="https://www.youtube.com/feeds/videos.xml?channel_id=${channel_id}" ;; + *"/c/"*|*"/user/"*) + feed=$(wget -q "$url" -O tmp_rssget_yt \ + && sed -n 's|.*\("rssUrl":"[^"]*\).*|\1|; p' tmp_rssget_yt \ + | grep rssUrl \ + | sed 's|"rssUrl":"||') ;; + esac + echo "$feed" +} + +getVimeoRss() { + local url="$1" + if echo "$url" | grep -q "/videos$"; then + feed_url=$(echo "$url" | sed 's/\/videos$//' | sed 's/\/$/\/rss/') + else + feed_url="${url}/videos/rss" + fi + echo "$feed_url" +} + +getGithubRss () { + local url="${1%/}" + if echo $url | grep -E "github.com/[^/]*/[a-zA-Z0-9].*" >/dev/null ; then + echo "${url}/commits.atom" + echo "${url}/releases.atom" + echo "${url}/tags.atom" + elif echo $url | grep -E "github.com/[^/]*(/)" >/dev/null ; then + echo "${url}.atom" + fi +} + +getGitlabRss () { + local url="${1%/}" + echo "${url}.atom" +} + +getMediumRss () { + echo $1 | sed 's|/tag/|/feed/|' +} + + +if [ -n "$1" ] ; then + url="$1" +else + url="$(xclip -selection clipboard -o)" + [ -z "$url" ] && echo "usage: $0 url 'tag1 tag2 tag3'" && exit 1 +fi + +declare -a list=() + +yt_regex="^(http(s)?://)?((w){3}\.)?(youtube\.com|invidio\.us|invidious\.flokinet\.to|invidious\.materialio\.us|iv\.datura\.network|invidious\.perennialte\.ch|invidious\.fdn\.fr|invidious\.private\.coffee|invidious\.protokolla\.fi|invidious\.privacyredirect\.com|yt\.artemislena\.eu|yt\.drgnz\.club|invidious\.incogniweb\.net|yewtu\.be|inv\.tux\.pizza|invidious\.reallyaweso\.me|iv\.melmac\.space|inv\.us\.projectsegfau\.lt|inv\.nadeko\.net|invidious\.darkness\.services|invidious\.jing\.rocks|invidious\.privacydev\.net|inv\.in\.projectsegfau\.lt|invidious\.drgns\.space)/(channel|user|c).+" +reddit_regex="^(http(s)?://)?((w){3}\.)?reddit\.com.*" +vimeo_regex="^(http(s)?://)?((w){3}.)?vimeo\.com.*" +if echo $url | grep -Ex "$yt_regex" >/dev/null ; then + list="$(getYoutubeRss "$url")" +elif echo $url | grep -Ex "$reddit_regex" >/dev/null ; then + list="$(getRedditRss "$url")" +# vimeo actually works with getlink +elif echo $url | grep -E "$vimeo_regex" >/dev/null ; then + list="$(getVimeoRss "$url")" +elif echo $url | grep -E "github.com" >/dev/null ; then + list="$(getGithubRss "$url")" +# gitlab also works with getlink +elif echo $url | grep -E "gitlab.com/[a-zA-Z0-9].*" >/dev/null ; then + list="$(getGitlabRss "$url")" +elif echo $url | grep -E "medium.com/tag" >/dev/null ; then + list="$(getMediumRss "$url")" +else + list="$(getlink "$url")" +fi + +[ "$(echo "$list" | wc -l)" -eq 1 ] && chosen_link="$list" || chosen_link=$(printf '%s\n' "${list[@]}" | dmenu -p "Choose a feed:") +tags="$2" +if which rssadd; + then rssadd "$chosen_link" "$tags" +fi +echo "$chosen_link" "$tags" @@ -5,33 +5,33 @@ realrm="$(which rm)" copy="$(which cp) -R" if [ $# -eq 0 ]; then - exec $realrm + exec $realrm fi flags="" while getopts "dfiPRrvW" opt; do - case $opt in - f) exec $realrm "$@" ;; - *) flags="$flags -$opt" ;; - esac + case $opt in + f) exec $realrm "$@" ;; + *) flags="$flags -$opt" ;; + esac done shift $((OPTIND - 1)) if [ ! -d "$archive" ]; then - if [ ! -w "$HOME" ]; then - echo "$0 failed: can't create $archive in $HOME" >&2 - exit 1 - fi - mkdir "$archive" - chmod 700 "$archive" + if [ ! -w "$HOME" ]; then + echo "$0 failed: can't create $archive in $HOME" >&2 + exit 1 + fi + mkdir "$archive" + chmod 700 "$archive" fi for arg; do - newname="$archive/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")" - if [ -f "$arg" ] || [ -d "$arg" ]; then - $copy "$arg" "$newname" - fi + newname="$archive/$(date "+%S.%M.%H.%d.%m").$(basename "$arg")" + if [ -f "$arg" ] || [ -d "$arg" ]; then + $copy "$arg" "$newname" + fi done exec $realrm "$flags" "$@" @@ -5,7 +5,7 @@ file=$(find . -mindepth 2 -type f 2>/dev/null | sed 's|^\./||' | sort | dmenu -i # If a file was selected if [ -n "$file" ]; then - echo "You selected: $file" - # Do something with the selected file here, like open it: - # xdg-open "$file" # Uncomment if desired + echo "You selected: $file" + # Do something with the selected file here, like open it: + # xdg-open "$file" # Uncomment if desired fi @@ -0,0 +1,36 @@ +#!/bin/sh + +# A dmenu wrapper script for system functions. +export WM="dwm" +case "$(readlink -f /sbin/init)" in + *systemd*) ctl='systemctl' ;; + *) ctl='loginctl' ;; +esac + +wmpid(){ # This function is needed if there are multiple instances of the window manager. + tree="$(pstree -ps $$)" + tree="${tree#*$WM(}" + echo "${tree%%)*}" +} + +lock(){ + mpc pause + pauseallmpv + wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle + kill -44 $(pidof dwmblocks) + slock + wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle + kill -44 $(pidof dwmblocks) +} + +case "$(printf "🔒 lock\n🚪 leave $WM\n♻️ renew $WM\n🐻 hibernate\n🔃 reboot\n🖥️shutdown\n💤 sleep\n📺 display off" | dmenu -i -p 'Action: ')" in + '🔒 lock') lock ;; +"🚪 leave $WM") kill -TERM "$(wmpid)" ;; +"♻️ renew $WM") kill -HUP "$(wmpid)" ;; +'🐻 hibernate') slock $ctl hibernate -i ;; +'💤 sleep') slock $ctl suspend -i ;; +'🔃 reboot') $ctl reboot -i ;; +'🖥️shutdown') $ctl poweroff -i ;; +'📺 display off') xset dpms force off ;; +*) exit 1 ;; +esac @@ -13,16 +13,16 @@ prompt="Add/delete a task: " cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file") while [ -n "$cmd" ]; do - if grep -q "^$cmd\$" "$file"; then - grep -v "^$cmd\$" "$file" > "$file.$$" - mv "$file.$$" "$file" + if grep -q "^$cmd\$" "$file"; then + grep -v "^$cmd\$" "$file" > "$file.$$" + mv "$file.$$" "$file" height=$(( height - 1 )) - else - echo "$cmd" >> "$file" - height=$(( height + 1 )) - fi + else + echo "$cmd" >> "$file" + height=$(( height + 1 )) + fi - cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file") + cmd=$(dmenu -l "$height" -p "$prompt" "$@" < "$file") done exit 0 @@ -1,3 +0,0 @@ -#!/bin/sh - -tabbed -c st -w @@ -6,12 +6,12 @@ cat <<'eof' [38;5;255m,_ ,_==▄▂[0m [38;5;255m, ▂▃▄▄▅▅[48;5;240m▅[48;5;20m▂[48;5;240m▅¾[0m. [38;5;199m/ [38;5;20m/[0m - [38;5;255m[48;5;20m▄[0m[38;5;255m[48;5;199m▆[38;5;16m[48;5;255m<´ [38;5;32m"[38;5;34m»[38;5;255m▓▓[48;5;32m▓[48;5;240m%[0m\ [38;5;199m/ [38;5;20m/ [38;5;45m/ [38;5;118m/[0m +[38;5;255m[48;5;20m▄[0m[38;5;255m[48;5;199m▆[38;5;16m[48;5;255m<´ [38;5;32m"[38;5;34m»[38;5;255m▓▓[48;5;32m▓[48;5;240m%[0m\ [38;5;199m/ [38;5;20m/ [38;5;45m/ [38;5;118m/[0m [38;5;255m,[38;5;255m[48;5;240m▅[38;5;16m[48;5;255m7" [38;5;160m´[38;5;34m>[38;5;255m[48;5;39m▓▓[38;5;199m[48;5;255m▓[0m[38;5;255m% [38;5;20m/ [38;5;118m/ [38;5;199m> [38;5;118m/ [38;5;199m>[38;5;255m/[38;5;45m%[0m [38;5;255m▐[48;5;240m[38;5;255m¶[48;5;240m[38;5;255m▓[48;5;255m [38;5;196m,[38;5;34m»[48;5;201m[38;5;255m▓▓[0m[38;5;255m¾´[0m [38;5;199m/[38;5;255m> %[38;5;199m/[38;5;118m%[38;5;255m/[38;5;199m/ [38;5;45m/ [38;5;199m/[0m [38;5;255m[48;5;240m▓[48;5;255m[38;5;16m▃[48;5;16m[38;5;255m▅▅[38;5;16m[48;5;255m▅▃,,[38;5;32m▄[38;5;16m▅[38;5;255m[48;5;16m▅▅[38;5;255m[48;5;20mÆ[0m[38;5;255m\[0m[38;5;20m/[38;5;118m/[38;5;255m /[38;5;118m/[38;5;199m/[38;5;255m>[38;5;45m// [38;5;255m/[38;5;118m>[38;5;199m/ [38;5;20m/[0m [48;5;20m[38;5;255mV[48;5;255m[38;5;16m║[48;5;20m[38;5;255m«[0m[38;5;255m¼.;[48;5;240m[38;5;255m→[48;5;255m[38;5;16m ║[0m[38;5;255m<«.,[48;5;25m[38;5;255m`[48;5;240m=[0m[38;5;20m/[38;5;199m/ [38;5;255m/>[38;5;45m/[38;5;118m/[38;5;255m%/[38;5;199m% / [38;5;20m/[0m - [38;5;20m//[48;5;255m[38;5;16m╠<´ -²,)[48;5;16m[38;5;255m(▓[48;5;255m[38;5;16m~"-[38;5;199m╝/[0m[38;5;255m¾[0m[38;5;199m/ [38;5;118m%[38;5;255m/[38;5;118m>[38;5;45m/ [38;5;118m/[38;5;199m>[0m +[38;5;20m//[48;5;255m[38;5;16m╠<´ -²,)[48;5;16m[38;5;255m(▓[48;5;255m[38;5;16m~"-[38;5;199m╝/[0m[38;5;255m¾[0m[38;5;199m/ [38;5;118m%[38;5;255m/[38;5;118m>[38;5;45m/ [38;5;118m/[38;5;199m>[0m [38;5;20m/ / [38;5;118m/ [48;5;20m[38;5;255m▐[48;5;240m[38;5;16m%[48;5;255m -./▄▃▄[48;5;16m[38;5;255m▅[48;5;255m[38;5;16m▐[48;5;255m[38;5;16m, [38;5;199m/[48;5;199m[38;5;255m7[0m[38;5;20m/[38;5;199m/[38;5;255m;/[38;5;199m/[38;5;118m% [38;5;20m/ /[0m [38;5;20m/ [38;5;199m/[38;5;255m/[38;5;45m/[38;5;118m/[38;5;255m[48;5;240m`[48;5;20m[38;5;255m▌[48;5;20m[38;5;255m▐[48;5;255m[38;5;16m %z[0m[38;5;255mWv xX[48;5;20m[38;5;255m▓[48;5;34m[38;5;255m▇[48;5;199m[38;255m▌[0m[38;5;20m/[38;5;199m/[38;5;255m&;[38;5;20m% [38;5;199m/ [38;5;20m/[0m [38;5;20m/ / [38;5;255m/ [38;5;118m%[38;5;199m/[38;5;255m/%/[48;5;240m[38;5;255m¾[48;5;255m[38;5;16m½´[38;5;255m[48;5;16m▌[0m[38;5;246m▃▄[38;5;255m▄▄[38;5;246m▄▃▃[0m[48;5;16m[38;5;255m▐[38;5;255m[48;5;199m¶[48;5;20m[38;5;255m\[0m[38;5;20m/[0m[48;5;255m[38;5;240m&[0m [38;5;20m/[0m @@ -3,13 +3,13 @@ PATH="$HOME/.config/via:$PATH" case "$1" in - -r) # rebuild cache first - via-feed -r | via-menu | via-open - ;; - -ro) # rebuild cache only - via-feed -r >/dev/null - ;; - *) - via-feed | via-menu | via-open - ;; + -r) # rebuild cache first + via-feed -r | via-menu | via-open + ;; + -ro) # rebuild cache only + via-feed -r >/dev/null + ;; + *) + via-feed | via-menu | via-open + ;; esac @@ -3,10 +3,15 @@ cache="$HOME/.cache/via" if [[ "$1" == "-r" ]] || [[ ! -e "$cache" ]]; then - cat "$HOME/.config/via/shortcuts" > "$cache" - cat "$HOME/.config/via/websites" >> "$cache" - find "$HOME" -mindepth 1 \( -name ".*" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | sort >> "$cache" + cat "$HOME/.config/via/shortcuts" > "$cache" + cat "$HOME/.config/via/websites" >> "$cache" + find "$HOME" -mindepth 1 \( -type d -name ".*" ! -path "$HOME/.scripts" -o -path "$HOME/cell" -o -path "$HOME/phone/*" \) -prune -o -print | sort >> "$cache" + # notify-send "via cache updated." fi -wmctrl -xl | sed "s/^[^.]*\.//;s/ \+\S\+ \+/ /;s/^/w /;s/ \+/ /g" -cat "$cache" +if [ "$CRON" = "1" ]; then + exit 0 +else + wmctrl -xl | sed "s/^[^.]*\.//;s/ \+\S\+ \+/ /;s/^/w /;s/ \+/ /g" + cat "$cache" +fi @@ -1,3 +1,3 @@ #!/bin/bash -dmenu -p "via" -i -l 15 +dmenu -p "via" -i -l 30 @@ -3,54 +3,54 @@ exec &> /dev/null while read -r arg; do - # first try matching by filename or pathname - case "${arg,,}" in - w\ *) - target=$(echo "$arg"|cut -d ' ' -f 3-) - wmctrl -a "$target" - ;; - http*) - $BROWSER "$arg" & - ;; - [^/]*) # doesn't start with '/' - sh -c "$arg" - ;; - *.txt) - tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" & - # $TERMINAL $EDITOR "$arg" & - ;; - *.pdf | *.epub) - zathura "$arg" & - ;; - *.mp3) - $TERMINAL mpg123 -opulse "$arg" & - ;; - *.od[tsp]|*.doc|*.docx|*.ppt|*.pptx|*.xls|*.xlsx) - libreoffice "$arg" & - ;; - *) - # then try matching by mimetype - mimetype=$(file -Lb --mime-type "$arg") - case "$mimetype" in - text/html) - $BROWSER "$arg" & - ;; - text/* | inode/x-empty | message/rfc822) - tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" & - # $TERMINAL $EDITOR "$arg" & - ;; - inode/directory) - cd "$arg" || exit - $TERMINAL & - cd - || exit - ;; - image/*) - sxiv "$arg" & - ;; - *) - exit 1 - ;; - esac - ;; - esac + # first try matching by filename or pathname + case "${arg,,}" in + w\ *) + target=$(echo "$arg"|cut -d ' ' -f 3-) + wmctrl -a "$target" + ;; + http*) + $BROWSER "$arg" & + ;; + [^/]*) # doesn't start with '/' + sh -c "$arg" + ;; + *.txt) + # tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" & + $TERMINAL $EDITOR "$arg" & + ;; + *.pdf | *.epub) + zathura "$arg" & + ;; + *.mp3) + $TERMINAL mpg123 -opulse "$arg" & + ;; + *.od[tsp]|*.doc|*.docx|*.ppt|*.pptx|*.xls|*.xlsx) + libreoffice "$arg" & + ;; + *) + # then try matching by mimetype + mimetype=$(file -Lb --mime-type "$arg") + case "$mimetype" in + text/html) + $BROWSER "$arg" & + ;; + text/* | inode/x-empty | message/rfc822) + # tabbed -c -r 2 $TERMINAL -w '' -e $EDITOR "$arg" & + $TERMINAL $EDITOR "$arg" & + ;; + inode/directory) + cd "$arg" || exit + $TERMINAL & + cd - || exit + ;; + image/*) + sxiv "$arg" & + ;; + *) + exit 1 + ;; + esac + ;; + esac done @@ -0,0 +1,7 @@ +#!/bin/sh + +export HOME=/home/filipek + +via-feed -r > /dev/null + +notify-send "via cache updated." @@ -2,8 +2,8 @@ # TODO: see if pulseaudio is running case "$1" in - up) pactl set-sink-volume @DEFAULT_SINK@ "+5%" ;; - down) pactl set-sink-volume @DEFAULT_SINK@ "-5%" ;; - mute) pactl set-sink-mute @DEFAULT_SINK@ toggle ;; - *) pactl set-sink-volume @DEFAULT_SINK@ "$1" ;; + up) pactl set-sink-volume @DEFAULT_SINK@ "+5%" && notify-send "Volume increased by 5%" ;; + down) pactl set-sink-volume @DEFAULT_SINK@ "-5%" && notify-send "Volume decreased by 5%" ;; + mute) pactl set-sink-mute @DEFAULT_SINK@ toggle && notify-send "Volume muted/unmuted" ;; + *) pactl set-sink-volume @DEFAULT_SINK@ "$1" && notify-send "Volume increased by $1%" ;; esac @@ -1,10 +1,12 @@ #!/bin/sh -export DISPLAY=:0.0 -export HOME=/home/filipek +# export DISPLAY=:0.0 +# export HOME=/home/filipek -temp=$(curl wttr.in/Wrocław?format=1 | awk '{print $2}') +# ł is URL-encoded +temp=$(curl "wttr.in/Wroc%C5%82aw?format=1" | awk '{print $2}') file="$HOME/.cache/weather/wroc.txt" +[ -z "$temp" ] && exit 1 echo "$temp" > "$file" -notify-send "Temperature updated." +# notify-send "Temperature updated." |
