From ad0ecd05b0768d16be08f04593d0295a4eaf8e07 Mon Sep 17 00:00:00 2001 From: Steven Baltakatei Sandoval Date: Thu, 10 Nov 2022 17:40:21 +0000 Subject: [PATCH 1/1] feat(user):Script to get gpg fingerprints from git dir - chore(.):Move draft scripts to draft dirs --- unitproc/draft/bktemp-get_av_format | 50 ++++ user/draft/timelapse_from_videos.sh | 346 ++++++++++++++++++++++++++++ user/get_gpgkey_from_gitlog.sh | 41 ++++ 3 files changed, 437 insertions(+) create mode 100644 unitproc/draft/bktemp-get_av_format create mode 100644 user/draft/timelapse_from_videos.sh create mode 100755 user/get_gpgkey_from_gitlog.sh diff --git a/unitproc/draft/bktemp-get_av_format b/unitproc/draft/bktemp-get_av_format new file mode 100644 index 0000000..6634766 --- /dev/null +++ b/unitproc/draft/bktemp-get_av_format @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +get_av_format() { + # Desc: Gets audio/video format of file as string + # Usage: get_av_format arg1 + # Depends: ffprobe + # Version: 0.0.1 + # Input: arg1: input file path + # Output: stdout (if valid audio or video format) + # exit code 0 if av file; 1 otherwise + # Example: get_av_format myvideo.mp4 + # Note: Would return "opus" if full ffprobe report had 'Audio: opus, 48000 Hz, stereo, fltp' + # Note: Not tested with videos containing multiple video streams + # Ref/Attrib: [1] https://stackoverflow.com/questions/5618363/is-there-a-way-to-use-ffmpeg-to-determine-the-encoding-of-a-file-before-transcod + # [2] https://stackoverflow.com/questions/44123532/how-to-find-out-the-file-extension-for-extracting-audio-tracks-with-ffmpeg-and-p#comment88464070_50723126 + # TODO 2022-08-19: output path of validated file to stdout for gnu parallel use + local av_format file_in; + local return_state; + file_in="$1"; + + # Return error exit code if not audio file + ## Return error if ffprobe itself exited on error + if ! ffprobe -v error -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "$file_in" 1>/dev/null 2>&1; then + return_state="false"; + fi; + + # Get av format + av_format="$(ffprobe -v error -select_streams a -show_entries stream=codec_name -of default=nokey=1:noprint_wrappers=1 "$file_in")"; # see [1] + + ## Return error if audio av is incorrectly formatted (e.g. reject if contains spaces) + pattern="^[[:alnum:]]+$"; # alphanumeric string with no spaces + if [[ $av_format =~ $pattern ]]; then + return_state="true"; + # Report audio format + echo "$av_format"; + else + return_state="false"; + fi; + + # Report exit code + if [[ $return_state = "true" ]]; then + return 0; + # echo "$1" #TODO_______________ + else + return 1; + fi; +} # Get audio format as stdout + +# Author: Steven Baltakatei Sandoval +# License: GPLv3+ diff --git a/user/draft/timelapse_from_videos.sh b/user/draft/timelapse_from_videos.sh new file mode 100644 index 0000000..ccfe691 --- /dev/null +++ b/user/draft/timelapse_from_videos.sh @@ -0,0 +1,346 @@ +#!/usr/bin/env bash +# Desc: Combines video files into time lapse video. +# Usage: timelapse_from_videos.sh [FILES] +# Example: timelapse_from_videos.sh ./*.MP4 + +declare -ag arrayPosArgs +declare -Ag appRollCall # Associative array for storing app status +declare -Ag fileRollCall # Associative array for storing file status +declare -Ag dirRollCall # Associative array for storing dir status + +yell() { echo "$0: $*" >&2; } # print script path and all args to stderr +die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status +try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +vbm() { + # Description: Prints verbose message ("vbm") to stderr if opVerbose is set to "true". + # Usage: vbm "DEBUG :verbose message here" + # Version 0.2.0 + # Input: arg1: string + # vars: opVerbose + # Output: stderr + # Depends: bash 5.1.16, GNU-coreutils 8.30 (echo, date) + + if [ "$opVerbose" = "true" ]; then + functionTime="$(date --iso-8601=ns)"; # Save current time in nano seconds. + echo "[$functionTime]:$0:""$*" 1>&2; # Display argument text. + fi + + # End function + return 0; # Function finished. +} # Displays message if opVerbose true +checkapp() { + # Desc: If arg is a command, save result in assoc array 'appRollCall' + # Usage: checkapp arg1 arg2 arg3 ... + # Version: 0.1.1 + # Input: global assoc. array 'appRollCall' + # Output: adds/updates key(value) to global assoc array 'appRollCall' + # Depends: bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if command -v "$arg" 1>/dev/null 2>&1; then # Check if arg is a valid command + appRollCall[$arg]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi; + else + appRollCall[$arg]="false"; returnState="false"; + fi; + done; + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi; +} # Check that app exists +checkfile() { + # Desc: If arg is a file path, save result in assoc array 'fileRollCall' + # Usage: checkfile arg1 arg2 arg3 ... + # Version: 0.1.1 + # Input: global assoc. array 'fileRollCall' + # Output: adds/updates key(value) to global assoc array 'fileRollCall'; + # Output: returns 0 if app found, 1 otherwise + # Depends: bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if [ -f "$arg" ]; then + fileRollCall["$arg"]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi; + else + fileRollCall["$arg"]="false"; returnState="false"; + fi; + done; + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi; +} # Check that file exists +checkdir() { + # Desc: If arg is a dir path, save result in assoc array 'dirRollCall' + # Usage: checkdir arg1 arg2 arg3 ... + # Version 0.1.2 + # Input: global assoc. array 'dirRollCall' + # Output: adds/updates key(value) to global assoc array 'dirRollCall'; + # Output: returns 0 if all args are dirs; 1 otherwise + # Depends: Bash 5.0.3 + local returnState + + #===Process Args=== + for arg in "$@"; do + if [ -z "$arg" ]; then + dirRollCall["(Unspecified Dirname(s))"]="false"; returnState="false"; + elif [ -d "$arg" ]; then + dirRollCall["$arg"]="true"; + if ! [ "$returnState" = "false" ]; then returnState="true"; fi + else + dirRollCall["$arg"]="false"; returnState="false"; + fi + done + + #===Determine function return code=== + if [ "$returnState" = "true" ]; then + return 0; + else + return 1; + fi +} # Check that dir exists +displayMissing() { + # Desc: Displays missing apps, files, and dirs + # Usage: displayMissing + # Version 1.0.0 + # Input: associative arrays: appRollCall, fileRollCall, dirRollCall + # Output: stderr: messages indicating missing apps, file, or dirs + # Output: returns exit code 0 if nothing missing; 1 otherwise + # Depends: bash 5, checkAppFileDir() + local missingApps value appMissing missingFiles fileMissing + local missingDirs dirMissing + + #==BEGIN Display errors== + #===BEGIN Display Missing Apps=== + missingApps="Missing apps :"; + #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done + for key in "${!appRollCall[@]}"; do + value="${appRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG:Missing apps: $key => $value"; + missingApps="$missingApps""$key "; + appMissing="true"; + fi; + done; + if [ "$appMissing" = "true" ]; then # Only indicate if an app is missing. + echo "$missingApps" 1>&2; + fi; + unset value; + #===END Display Missing Apps=== + + #===BEGIN Display Missing Files=== + missingFiles="Missing files:"; + #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done + for key in "${!fileRollCall[@]}"; do + value="${fileRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG:Missing files: $key => $value"; + missingFiles="$missingFiles""$key "; + fileMissing="true"; + fi; + done; + if [ "$fileMissing" = "true" ]; then # Only indicate if an app is missing. + echo "$missingFiles" 1>&2; + fi; + unset value; + #===END Display Missing Files=== + + #===BEGIN Display Missing Directories=== + missingDirs="Missing dirs:"; + #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done + for key in "${!dirRollCall[@]}"; do + value="${dirRollCall[$key]}"; + if [ "$value" = "false" ]; then + #echo "DEBUG:Missing dirs: $key => $value"; + missingDirs="$missingDirs""$key "; + dirMissing="true"; + fi; + done; + if [ "$dirMissing" = "true" ]; then # Only indicate if an dir is missing. + echo "$missingDirs" 1>&2; + fi; + unset value; + #===END Display Missing Directories=== + + #==END Display errors== + #==BEGIN Determine function return code=== + if [ "$appMissing" == "true" ] || [ "$fileMissing" == "true" ] || [ "$dirMissing" == "true" ]; then + return 1; + else + return 0; + fi + #==END Determine function return code=== +} # Display missing apps, files, dirs +showUsage() { + # Desc: Display script usage information + # Usage: showUsage + # Version 0.0.2 + # Input: none + # Output: stdout + # Depends: GNU-coreutils 8.30 (cat) + cat <<'EOF' + USAGE: + timelapse_from_videos.sh [ options ] [FILE...] + + OPTIONS: + -h, --help + Display help information. + --version + Display script version. + -v, --verbose + Display debugging info. + -o, --output-file + Define output file path. + -- + Indicate end of options. + + EXAMPLE: + timelapse_from_videos.sh -o output.mp4 in1.mp4 in2.mp4 in3.mp4 + timelapse_from_videos.sh -o output.mp4 -- in1.mp4 in2.mp4 in3.mp4 +EOF +} # Display information on how to use this script. +showVersion() { + # Desc: Displays script version and license information. + # Usage: showVersion + # Version: 0.0.2 + # Input: scriptVersion var containing version string + # Output: stdout + # Depends: vbm(), yell, GNU-coreutils 8.30 + + # Initialize function + vbm "DEBUG:showVersion function called." + + cat <<'EOF' +timelapse_from_videos.sh 0.0.1 +Copyright (C) 2022 Steven Baltakatei Sandoval +License GPLv3: GNU GPL version 3 +This is free software; you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + + GNU Coreutils 8.32 + Copyright (C) 2020 Free Software Foundation, Inc. + License GPLv3+: GNU GPL version 3 or later . + This is free software: you are free to change and redistribute it. + There is NO WARRANTY, to the extent permitted by law. +EOF + + # End function + vbm "DEBUG:showVersion function ended." + return 0; # Function finished. +} # Display script version. +processArgs() { + # Desc: Processes arguments provided to script. + # Usage: processArgs "$@" + # Version: 1.0.0 + # Input: "$@" (list of arguments provided to the function) + # Output: Sets following variables used by other functions: + # opVerbose Indicates verbose mode enable status. (ex: "true", "false") + # pathFileOut1 Path to output file. + # opFileOut1_overwrite Indicates whether file pathFileOut1 should be overwritten (ex: "true", "false"). + # arrayPosArgs Array of remaining positional argments + # Depends: + # yell() Displays messages to stderr. + # vbm() Displays messsages to stderr if opVerbose set to "true". + # showUsage() Displays usage information about parent script. + # showVersion() Displays version about parent script. + # arrayPosArgs Global array for storing non-option positional arguments (i.e. arguments following the `--` option). + # External dependencies: bash (5.1.16), echo + # Ref./Attrib.: + # [1]: Marco Aurelio (2014-05-08). "echo that outputs to stderr". https://stackoverflow.com/a/23550347 + # [2]: "Handling positional parameters" (2018-05-12). https://wiki.bash-hackers.org/scripting/posparams + + # Initialize function + vbm "DEBUG:processArgs function called." + + # Perform work + while [ ! $# -eq 0 ]; do # While number of arguments ($#) is not (!) equal to (-eq) zero (0). + #yell "DEBUG:Starting processArgs while loop." # Debug stderr message. See [1]. + #yell "DEBUG:Provided arguments are:""$*" # Debug stderr message. See [1]. + case "$1" in + -h | --help) showUsage; exit 1;; # Display usage. + --version) showVersion; exit 1;; # Show version + -v | --verbose) opVerbose="true"; vbm "DEBUG:Verbose mode enabled.";; # Enable verbose mode. See [1]. + -o | --output-file) # Define output file path + if [ -f "$2" ]; then # If $2 is file that exists, prompt user to continue to overwrite, set pathFileOut1 to $2, pop $2. + yell "Specified output file $2 already exists. Overwrite? (y/n):" + read -r m; case $m in + y | Y | yes) opFileOut1_overwrite="true";; + n | N | no) opFileOut1_overwrite="false";; + *) yell "Invalid selection. Exiting."; exit 1;; + esac + if [ "$opFileOut1_overwrite" == "true" ]; then + pathFileOut1="$2"; + shift; + vbm "DEBUG:Output file pathFileOut1 set to:""$2"; + else + yell "ERORR:Exiting in order to not overwrite output file:""$pathFileOut1"; + exit 1; + fi + else + pathFileOut1="$2"; + shift; + vbm "DEBUG:Output file pathFileOut1 set to:""$2"; + fi ;; + --) # End of all options. See [2]. + shift; + for arg in "$@"; do + vbm "DEBUG:adding to arrayPosArgs:$arg"; + arrayPosArgs+=("$arg"); + done; + break;; + -*) showUsage; yell "ERROR: Unrecognized option."; exit 1;; # Display usage + *) # Handle all other arguments. See [1]. + ## Store in arrayPosArgs + for arg in "$@"; do + vbm "DEBUG:adding to arrayPosArgs:$arg"; + arrayPosArgs+=("$arg"); + done; + break;; + esac + shift + done + + # End function + vbm "DEBUG:processArgs function ended." + return 0; # Function finished. +} # Evaluate script options from positional arguments (ex: $1, $2, $3, etc.). +main() { + # Output: + # arrayPosArgs Array of remaining positional argments + # Depends: ffmpeg 4.4.2, ffprobe 4.4.2 + + # Check input + ## Check required commands + checkapp ffmpeg ffprobe; + + ## Process args + processArgs "$@"; + vbm "$(declare -p arrayPosArgs;)"; + ### Check non-option positional arguments are files + for arg in "${arrayPosArgs[@]}"; do + if [[ ! -f "$arg" ]]; then + die "FATAL:Not a file:$arg (at $(readlink -f "$arg") )"; fi; + done; + + # Check that files are video files + + + yell "Done."; + exit 0; +}; # main program + +main "$@"; + +# Author: Steven Baltakatei Sandoval +# License: GPLv3+ diff --git a/user/get_gpgkey_from_gitlog.sh b/user/get_gpgkey_from_gitlog.sh new file mode 100755 index 0000000..920e3dc --- /dev/null +++ b/user/get_gpgkey_from_gitlog.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Desc: A script that outputs a list of GPG signatures from git log output +# Usage: get_gpgkey_from_gitlog.sh [dir] +# Input: arg1: directory +# Output: stdout: newline-delimited list of 40-char GPG fingerprints + +declare -g buffer; + +yell() { echo "$0: $*" >&2; } # print script path and all args to stderr +die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status +try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails +check_args() { + # Desc: Check arguments + if [[ $# -ne 1 ]]; then die "FATAL:Incorrect number of arguments:$#"; fi; + if [[ ! -d $1 ]]; then die "Not a directory:$1"; fi; + return 0; +}; # check args +fill_buffer() { + # Input: arg1: git dir + # Output: var: $buffer: newline-delimited list of gpg fingerprints + pushd "$1" 1>/dev/random || die "FATAL:Failed to change directory:$1"; + buffer="$(git log --show-signature 2>&1)"; + yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines."; + buffer="$(grep -E -- "^gpg:" < <( printf "%s" "$buffer" ) )"; + yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines."; + buffer="$(grep -Eo "([0-9A-F]){40}" < <( printf "%s" "$buffer" ) )"; + yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines."; + buffer="$(sort -u < <( printf "%s" "$buffer" ))"; + yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines."; + popd 1>/dev/random || die "FATAL:Failed to popd."; +}; # fill buffer with git gpg lines +main() { + check_args "$@"; + fill_buffer "$1"; + printf "%s\n" "$buffer"; + return 0; +}; + +main "$@"; + +# git log --show-signature 2>&1 | grep -E -- "^gpg:" | grep -Eo "([0-9A-F]){40}" | sort -u -- 2.30.2