From e8a9befa8bf91db6bcf417ed29b90b2266af3a2d Mon Sep 17 00:00:00 2001 From: Taeyeon Mori Date: Thu, 4 Nov 2021 17:50:43 +0100 Subject: [PATCH] bin/*: Add accumulated code changes --- README.md | 15 ++- bin/cower | 48 ++++++++++ bin/pa | 200 +++++++++++++++++++++++++++++++++++++++ bin/remembersong | 6 +- bin/setcidir | 47 +++++++++ bin/unpack_shift | 9 +- install | 1 + lib/python/advancedav.py | 5 +- 8 files changed, 322 insertions(+), 9 deletions(-) create mode 100755 bin/cower create mode 100755 bin/pa create mode 100755 bin/setcidir diff --git a/README.md b/README.md index 0e0cd36..f758f85 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,15 @@ Contains utility applications I'd hate to miss #### (Z) Shell scripts - argshell : Run the same program multiple times with a common prefix of arguments - aur.sh : Quite sophisticated AUR helper +- cower : Cower stub that calls auracle instead - ffpsp(-batch) : Use HandBrakeCLI to encode videos to be compatible with Sony's PSP. - fix-steam-runtime.sh: Fix Steam runtime on Arch Linux (And others with "too new" libstdc++ and friends) - force-run-elf : Try to execute a non-executable ELF file by passing it to the appropriate interpreter +- pa : Utility for managing PulseAudio volume without DE support. - paloop : Loop a pulseaudio source to a sink. - remembersong : Save the currently playing song name and artist to a text file. - schedshut : Shutdown when a specific task/process finishes. +- setcidir : Set the +F attribute on an existing directory. - start : Start a (graphical) app in the background; Like windows command of same name. - syncfat : Copy files to a Windows volume while removing invalid characters from filenames. - unpack\_shift : Unpack archives with different filename encoding @@ -46,10 +49,13 @@ Contains utility applications I'd hate to miss - animelib : Manually organize a collection of tv series - animelib3 : Try to automagically organize tv series as best as possible - fileinterp.py : Play back a python script file as if it had been entered into a prompt. +- iio-rotated : Automatically rotate the screen according to iio-proxy data - mountpart : Mount a partition in a whole-disk raw image file. - nosaver : Try to inhibit the screensaver. -- patchdir : Patch a folder structure with files from an archive. +- patchdir : Patch a folder structure with files from an archive. (libarchive-c required) +- protontool : Interact with steam games and compatibility tool from the command line - sm-song-package : Try to automatically create a .smzip of songs for StepMania. +- sync\_savegames : Custom savegame synchronization using steamsync.py - transportlinks : Fixup symlinks after moving the target files. - videothumb : Create (PSP compatible) thumbnails for video files. - visualsleep : Sleep command with countdown timer. @@ -83,7 +89,10 @@ Contains support libraries #### Python - advancedav.py : A very overengineered way to construct complex ffmpeg commandlines -- animelib.py : Library version on animelib script +- animelib.py : Library version of animelib script +- propex.py : Assortment of property classes +- steamsync.py : Library for custom savegame synchronization with Steam support +- steamutil.py : Utilities for working with Steam's local database files - vdfparser.py : A simple parser for Valve's VDF Key/Value format - xconv/ : Supporting library for xconv media conversion utility - profiles/ : (Virtual) package containing xconv profiles @@ -119,6 +128,8 @@ XDG configuration directory - systemd/user : Systemd user units - ssh-agent : Service unit to keep a per-user ssh-agent instance - nvim : NeoVim configuration +- mpv : MPV +- youtube-dl : Youtube-DL .files/texmf diff --git a/bin/cower b/bin/cower new file mode 100755 index 0000000..d7ce383 --- /dev/null +++ b/bin/cower @@ -0,0 +1,48 @@ +#!/bin/zsh +# stub out cower -s + +echo -e '\033[31mCower is broken. Use auracle instead\033[0m' + +usage() { + echo "$0 -s " + echo "cower [-s] stub for muscle memory" + exit $1 +} + +MODE= +ARGS=() + +next= +for a in "$@"; do + if [ -z "$next" ]; then + case "$a" in + -s|--search) + MODE=search + next=args + ;; + -u|--updates) + MODE=outdated + next=args + ;; + -h|--help) + usage 0 + ;; + *) + echo "Unknown option $a" + usage 1 + ;; + esac + elif [ "$next" = args ]; then + ARGS+=("$a") + else + case "$next" in + esac + next= + fi +done + +if [ -n "$MODE" ]; then + echo -e "$ \033[32mauracle $MODE $ARGS[*]\033[0m" + exec auracle $MODE "$ARGS[@]" +fi + diff --git a/bin/pa b/bin/pa new file mode 100755 index 0000000..353874f --- /dev/null +++ b/bin/pa @@ -0,0 +1,200 @@ +#!/bin/bash -eu + +# --------------------------------------------------------- +# Lazy Variables +__save() { + local name=$1 + shift + declare -g $name="$*" +} + +require() { + for name in $@; do + if [ -z "${!name+x}" ]; then + get_$name "__save $name" "require_for $name" + fi + done +} + +shopt -s expand_aliases +alias greq='$2 ' +alias gsave='$1 ' + +typeset -gA require_depends=() + +invalidate() { + for name in $@; do + unset -v $name + if [ -n "${require_depends[$name]:-""}" ]; then + local tmp="${require_depends[$name]}" + unset -v require_depends[$name] + invalidate $tmp + fi + done +} + +require_for() { + local self_name=$1 + shift + require $@ + for name in $@; do + require_depends[$name]="${require_depends[$name]-""} $self_name" + done +} + +# --------------------------------------------------------- +# Lazy variables +get_ponymix_prog() { + gsave $(which ponymix 2>/dev/null) +} + +get_pacmd_prog() { + # May be unavailable if only pulse clients installed + gsave $(which pacmd 2>/dev/null) +} + +get_default_sink() { + gsave $(pactl info | grep 'Default Sink' | cut -d: -f2) +} + +# There doesn't seem to be a better way to get a sink volume right now +get_pacmd_dump() { + greq pacmd_prog + [ -n "$pacmd_prog" ] || { echo "ERROR: \$pacmd_dump requires available pacmd which is part of the pulseaudio server package"; exit 44; } + gsave "$(pacmd dump)" +} + +get_pacmd_default_sink_config() { + greq pacmd_dump default_sink + gsave "$(echo "$pacmd_dump" | grep "$default_sink")" +} + +get_pacmd_default_volume() { + greq pacmd_default_sink_config + gsave $[$(echo "$pacmd_default_sink_config" | grep "set-sink-volume" | cut -d' ' -f3)] +} + +get_default_volume_percent() { + greq ponymix_prog + if [ -n "$ponymix_prog" ]; then + gsave $($ponymix_prog get-volume) + else + greq pacmd_default_volume + gsave $[(100*$pacmd_default_volume+32768)/65535] + fi +} + +get_default_mute() { + greq ponymix_prog + if [ -n "$ponymix_prog" ]; then + $ponymix_prog is-muted && gsave yes || gsave no + else + greq pacmd_default_sink_config + gsave $(echo "$pacmd_default_sink_config" | grep "set-sink-mute" | cut -d' ' -f3) + fi +} + +# --------------------------------------------------------- +# Operations +do_vol() { + # Set default sink volume + require default_sink + local offset + case "$1" in + m|mute) + pactl set-sink-mute $default_sink true + ;; + u|unmute) + pactl set-sink-mute $default_sink false + ;; + t|toggle|toggle-mute) + pactl set-sink-mute $default_sink toggle + ;; + \+) : ${offset:=+5%};& + \-) : ${offset:=-5%};& + *) : ${offset:=$1} + pactl set-sink-mute $default_sink false + pactl set-sink-volume $default_sink $offset + ;; + esac + invalidate pacmd_dump default_volume_percent default_mute +} + +do_notify() { + # Notification + if which dunstify >/dev/null 2>&1 && [ -n "`pgrep --ns $$ -u $(id -u) dunst`" ]; then + require default_sink default_volume_percent default_mute + dunst_id=6533319 + if [ $default_mute = yes ]; then + icon=audio-volume-muted + text="Volume muted" + else + text="Volume $default_volume_percent%" + if [ $default_volume_percent -lt 35 ]; then + icon=audio-volume-low + elif [ $default_volume_percent -lt 75 ]; then + icon=audio-volume-medium + else + icon=audio-volume-high + fi + fi + if echo $default_sink | grep -q bluez; then + text="Bluetooth $text" + fi + bar_size=20 + filled=$[(($bar_size * $default_volume_percent) + (100 / (2 * $bar_size)))/100] + bar= + if [ $filled -gt 0 ]; then + bar="`printf %.s● $(seq $filled)`" + fi + if [ $filled -lt $bar_size ]; then + bar="$bar`printf %.s○ $(seq $[$bar_size-$filled])`" + fi + dunstify -a "PA Volume" -u low -i $icon -r $dunst_id "$text" "$bar" + fi +} + +do_print() { + require default_sink default_volume_percent default_mute + [ $default_mute = yes ] && muted=muted || muted=unmuted + echo "$default_sink $default_volume_percent% $muted" +} + +# --------------------------------------------------------- +# Main + +while [ $# -gt 0 ]; do + verb=$1; shift + + case $verb in + v|vol|volume) + do_vol "$1"; shift + do_notify + do_print + ;; + set-volume) + do_vol "$1"; shift + ;; + n|notify) + do_notify + ;; + p|print) + do_print + ;; + get-default-sink) + require default_sink + echo $default_sink + ;; + *) + echo "Available verbs:" + echo " set-volume <[+-]n%|mute|unmute|toggle> Change default sink volume" + echo " notify Display a notification with current default sink volume" + echo " print Print the default sink and it's volume" + echo " volume Short for \"set-volume <...> notify print\"" + echo " get-default-sink Print default sink name" + echo + echo " verbs can be chained by separating them with space. Note that some have additional arguments" + exit 1 + ;; + esac +done diff --git a/bin/remembersong b/bin/remembersong index 27ad1dc..b8e10d5 100755 --- a/bin/remembersong +++ b/bin/remembersong @@ -4,8 +4,10 @@ SongsFile="${1-$HOME/Documents/Songs.text}" -Artist="$(playerctl metadata artist)" -Title="$(playerctl metadata title)" +IGNORE=plasma-browser-integration + +Artist="$(playerctl metadata artist -i $IGNORE)" +Title="$(playerctl metadata title -i $IGNORE)" echo "$Artist -- $Title" >>$SongsFile diff --git a/bin/setcidir b/bin/setcidir new file mode 100755 index 0000000..5e83d7d --- /dev/null +++ b/bin/setcidir @@ -0,0 +1,47 @@ +#!/bin/bash -eu +# Make a directory with content case-insensitive using chattr +F + +NEWFLAGS="+F" + +usage() { + echo "Usage: $1 [-c] " + echo + echo " Make an existing directory case-folding (chattr +F)" + echo + echo "Options:" + echo " -c Clear the case-folding flag instead of setting it" + exit $2 +} + +while getopts hc opt; do + case "$opt" in + h) usage "$0" 0;; + c) NEWFLAGS="-F";; + ?) usage "$0" 255;; + esac +done + +shift $((OPTIND - 1)) + +if [ ! -d "$1" ]; then + echo -e "\e[31m'$1' is not a directory\e[0m" + exit 1 +fi + +# Make sure it doesn't end in / +d="${1%/}" + +set -x +# Create new directory with appropriate attributes +mkdir "$d.$$" +chattr $NEWFLAGS "$d.$$" +# Need to re-create the whole subtree, so the flag propagates +# Try to save space by making a recursive hardlink copy +cp -Tldr "$d" "$d.$$" +# Just to be on the safe side, fail if there are any files with a single reference left +find "$d" -type f,l -links +1 -delete +find "$d" -type d -empty -delete +[ ! -d "$d" ] +# Rename to old name +mv "$d.$$" "$d" + diff --git a/bin/unpack_shift b/bin/unpack_shift index 45dbebb..e524a8b 100755 --- a/bin/unpack_shift +++ b/bin/unpack_shift @@ -16,7 +16,7 @@ function usage { echo echo "Options:" echo " --help Show this help message and exit" - echo " --test Do a test-run" + echo " --dry Do a test-run" echo " -* Pass any other options to 7z" exit $2 } @@ -25,12 +25,15 @@ args=() sevenzip_args=() convmv_args=(-f shift-jis -t utf8) test_run=false +conv_force=true for cx in "$@"; do case "$cx" in --help) usage "$0" 0;; --test) + conv_force=false;; + --dry) test_run=true;; -*) sevenzip_args+=("$cx");; @@ -53,7 +56,7 @@ if [ -z "$args" ]; then usage "$0" 1 fi -$test_run || \ +$test_run || $conv_force && \ convmv_args+=("--notest") #destination="`realpath "$destination"`" @@ -69,7 +72,7 @@ cd "$tmp" msg "Unpacking Archive(s)..." for archive in "${args[@]}"; do msg " Unpacking $archive" - LANG=ja_JP 7z x "${sevenzip_args[@]}" "$archive" + LANG=ja_JP 7z x "${sevenzip_args[@]}" "$archive" || true done msg "Fixing Filename encodings..." diff --git a/install b/install index 9bb4836..2c062a5 100755 --- a/install +++ b/install @@ -59,6 +59,7 @@ function relink() { [[ ! -e "$1" ]] && err "No such file or directory: '$1'" && return 1 [[ -L "$2" ]] && rm -f "$2" [[ -e "$2" ]] && ! $OVERWRITE && err "File already exists and isn't a symbolic link: '$2'" && return 1 + [[ ! -d "`dirname "$2"`" ]] && mkdir -p "`dirname "$2"`" color 31 ln -sr "$1" "$2" } diff --git a/lib/python/advancedav.py b/lib/python/advancedav.py index 20790db..3e6ecb1 100644 --- a/lib/python/advancedav.py +++ b/lib/python/advancedav.py @@ -1205,8 +1205,9 @@ class SimpleTask(Task): container = _redir("output", "container") metadata = _redir("output", "metadata") options = _redir("output", "options") - name = _redir("output", "name") # Deprecated! use filename instead. 'name' will be reused in the future - filename = _redir("output", "name") + name = _redir("output", "name") + path = _redir("output", "path") + filename = _redir("output", "filename") del _redir