diff --git a/bin-shared/pull_clone.sh b/bin-shared/pull_clone.sh new file mode 100755 index 0000000..9420325 --- /dev/null +++ b/bin-shared/pull_clone.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +# TBD: +# - merge into send-master script and use a variable to control push vs pull. + +## Variables ## + +PROG="$(basename -- "${BASH_SOURCE[0]}")" +loop=false + +DIR="`pwd`" +dir="`basename $DIR`" + +## Validations ## + +if [[ "$DIR" != *"-clone" && "$DIR" != *"-SYNC" ]]; then + echo "'$DIR' is not labeled as a CLONE or SYNC. Skipping download." + exit 0 +fi + +# Only pull the existing subdirectories rather than ALL content. +subdirs_only="false" +if [[ "$dir" == "music-clone" ]]; then + subdirs_only="true" +fi + +## Main ## + +echo "`date` - Pulling" \ + "'$PROD_DATA_USER@$PROD_DATA_HOST:$PROD_DATA_PORT$PROD_DATA_DIR/$dir'" \ + "to '$dir'." + +sleep=0 +while true; do + if (( $sleep > 0 )); then + echo "Sleeping for '$sleep' seconds..." + sleep $sleep + fi + + if [[ "$subdirs_only" == "true" ]]; then + ls $DIR | while read subdir; do + echo -e "\n`date` - Working subdirectory '$subdir'..." + clone -e "ssh -p $PROD_DATA_PORT" \ + $PROD_DATA_USER@$PROD_DATA_HOST:$PROD_DATA_DIR/$dir/$subdir/ \ + ./$subdir && + echo "`date` - Success!" || + echo "`date` - Failed!" + done + else + clone -e "ssh -p $PROD_DATA_PORT" \ + $PROD_DATA_USER@$PROD_DATA_HOST:$PROD_DATA_DIR/$dir/ \ + . && + echo "`date` - Success!" || + echo "`date` - Failed!" + fi + + sleep=30 + if [[ "$loop" == false ]]; then + break; + fi +done + +## Complete ## + +echo -e "\n`date` - $PROG complete." +exit 0 diff --git a/bin-shared/send_master.sh b/bin-shared/send_master.sh new file mode 100755 index 0000000..f03bcdd --- /dev/null +++ b/bin-shared/send_master.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash + +# TBD: +# - add parameter to set loop=true, and accept a value for sleep seconds +# - allow passing the script a variable for the dir, rather than assuming curr + +## Variables ## + +PROG="$(basename -- "${BASH_SOURCE[0]}")" +loop=false + +DIR="`pwd`" +dir="`basename $DIR`" + +## Validations ## + +if [[ "$DIR" != *"-MASTER" && "$DIR" != *"-SYNC" ]]; then + echo "'$DIR' is not labeled as a MASTER or SYNC. Skipping upload." + exit 0 +fi + +## Main ## + +new_dir="${dir//MASTER/clone}" + +echo "`date` - Sending '$dir' to" \ + "'$PROD_DATA_USER@$PROD_DATA_HOST:$PROD_DATA_PORT$PROD_DATA_DIR/$new_dir'" + +sleep=0 +while true; do + if (( $sleep > 0 )); then + echo "Sleeping for '$sleep' seconds..." + sleep $sleep + fi + clone -e "ssh -p $PROD_DATA_PORT" ./ \ + $PROD_DATA_USER@$PROD_DATA_HOST:$PROD_DATA_DIR/$new_dir && + echo "`date` - Success!" || + echo "`date` - Failed!" + sleep=30 + if [[ "$loop" == false ]]; then + break; + fi +done + +## Complete ## + +echo "`date` - $PROG complete." +exit 0 diff --git a/rc_shared.sh b/rc_shared.sh new file mode 100644 index 0000000..dd46b5e --- /dev/null +++ b/rc_shared.sh @@ -0,0 +1,954 @@ +# Notes: +# - Please keep this file working for both BASH and ZSH. :) + +## Variables ## + +# Environment Usability # + +export PATH="$PATH:~/bin-shared:~/.bin-shared" + +# PS1 Colors # + +colors=`tput colors` +if (( colors >= 256 )); then + export PURPLE="`tput setaf 55`" + export ORANGE="`tput setaf 208`" + export GREEN="`tput setaf 34`" + + export RED="`tput setaf 196`" + export SCARLET="`tput setaf 160`" + export YELLOW="`tput setaf 226`" + + export GRAY="`tput setaf 243`" +elif (( colors == 16 )); then + export PURPLE="`tput setaf 13`" + export ORANGE="`tput setaf 11`" + export GREEN="`tput setaf 02`" + + export RED="`tput setaf 09`" + export SCARLET="`tput setaf 01`" + export YELLOW="`tput setaf 11`" + + export GRAY="`tput setaf 08`" +else + export PURPLE="`tput setaf 05`" + export ORANGE="`tput setaf 03`" + export GREEN="`tput setaf 02`" + + export RED="`tput setaf 05`" + export SCARLET="`tput setaf 01`" + export YELLOW="`tput setaf 03`" + + export GRAY="`tput setaf 07`" +fi + + +export RESET="`tput sgr0`" +export BOLD="`tput bold`" + + +## Aliases ## + +# Quickies # + +alias reload-bash="source ~/.bashrc" +alias bash-reload="reload-bash" +alias shell-reload="reload-bash" +alias reload-shell="reload-bash" +alias reload="reload-bash" + +alias l='ls ' +alias ll='ls -alh ' +alias lh='ls -ash ' + +function clones { + export CLONES_PATH="$HOME/Clones" + if [[ -d /sdcard ]]; then + export CLONES_PATH="/sdcard/Library/Clones" + fi + mkdir -pv "$CLONES_PATH" + cd "$CLONES_PATH" +} +alias cl="clones" +alias cdl="cl" +alias cdc="cl" + +alias library="clones && cd .." +alias lib="library" + +# Networking # + +alias scan="nmap -A -p- --script=vuln " + +# Trash Related # + +export TRASH_ROOT="/" +if [[ -d "/sdcard" ]]; then + # Android / Termux + export TRASH_ROOT="/sdcard" +else + # Desktop + export TRASH_ROOT="$HOME" +fi +export TRASH="$TRASH_ROOT/TRASH" + +alias trash="cd $TRASH" + +alias clean-trash="bash -c 'rm -rfv "$TRASH"/*'; clean-trashed" +alias trash-clean="clean-trash" + +alias check-trash='du -h $TRASH | sort -h; find "$TRASH_ROOT" -name .Trash"*" -exec du -h {} \; -exec mv -v {} "$TRASH"/ \;' +alias trash-check="check-trash" + +alias check-trashed='find "$TRASH_ROOT" -name ".trashed*" -exec du -h {} \; -exec mv -v {} "$TRASH"/ \; | sort -h' +alias clean-trashed='find "$TRASH_ROOT" -name ".trashed*" -exec du -h {} \; -delete | sort -h' + + +## Functions ## + +# Related specifically to this project. # + +branch="$BRANCH" +if [[ -z "$branch" ]]; then + branch="$PROD_GIT_BRANCH" +fi +if [[ -z "$branch" ]]; then + branch="dev" +fi + +function update-shared-old { + log "`date` - Reloading the '~/.rc_shared' file from env-shared.\n" + + if [[ -n "$1" ]]; then + branch="$1" + fi + + dir="shared-rc-deleteme" + + git clone https://git.hyperling.com/me/env-shared \ + $dir --branch=$branch + + mv -v $dir/rc_shared.sh ~/.rc_shared + + local_bin="$HOME/bin" + remote_bin="shared-rc-deleteme/bin-shared" + if [[ -d "$local_bin" ]]; then + log "\n`date` - Found '$local_bin', adding scripts.\n" + mv -v $remote_bin/*.sh "$local_bin"/ + + refactor_script="refactor_music_library.sh" + wget -O "$refactor_script" \ + https://git.hyperling.com/me/shell-music-refactor-library/raw/branch/main/refactor_music_library.sh + mv -v $refactor_script "$local_bin"/ + + chmod 755 -Rc "$local_bin" + else + echo "Did not find '$local_bin', did not copy scripts." + fi + + log "\n`date` - Done! Removing git clone.\n" + mv -v $dir ~/TRASH/"$dir-`date "+%Y%m%d-%H%M%S"`" + + log "\n`date` - Complete!" +} + +export PROJECT_SHARED="$HOME/.git-env-shared" +function update-shared2 { + # Refresh the local env-shared repo. + if [[ -d $PROJECT_SHARED ]]; then + log "`date` - Updating '$PROJECT_SHARED'.\n" + git -C "$PROJECT_SHARED" switch "$branch" + git -C "$PROJECT_SHARED" pull --recurse-submodules || \ + ( echo "Failed to pull project, exiting." && return 1 ) + else + log "`date` - Downloading '$PROJECT_SHARED'.\n" + git clone https://git.hyperling.com/me/env-shared \ + "$PROJECT_SHARED" --branch=$branch + fi + + # Tha main piece! Reload the shared RC file. + cp -v "$PROJECT_SHARED"/rc_shared.sh ~/.rc_shared + cp -v "$PROJECT_SHARED"/vimrc.vim ~/.vimrc + + # Copy the scripts from the shared bin to the home bin. + local_bin="$HOME/bin" + remote_bin="$PROJECT_SHARED/bin-shared" + if [[ -d "$local_bin" ]]; then + log "\n`date` - Found '$local_bin', adding scripts.\n" + cp -v "$remote_bin"/*.sh "$local_bin"/ + + refactor_script="refactor_music_library.sh" + wget -O "$refactor_script" \ + https://git.hyperling.com/me/shell-music-refactor-library/raw/branch/main/refactor_music_library.sh + mv -v $refactor_script "$local_bin"/ + + chmod 755 -Rc "$local_bin" + else + echo "Did not find '$local_bin', did not copy scripts." + fi + + log "\n`date` - Complete!" +} +alias shared-update2="update-shared2" +alias reload-shared2="update-shared2" +alias shared-reload2="update-shared2" + +alias update-shared="update-shared2" +alias shared-update="update-shared" +alias reload-shared="update-shared" +alias shared-reload="update-shared" + +function reload-all { + log "`date` - Reloading BASH" + reload-bash + + log "\n`date` - Reloading Main (Termux/Ansible)" + if [[ -d /sdcard ]]; then + reload-termux + else + scm.sh + fi + reload-bash + + log "\n`date` - Reloading Shared" + reload-shared + reload-bash +} +alias all-reload="reload-all" + +function update-all { + log "`date` - Updating env projects..." + reload-all + + log "\n\n\n`date` - Running system updates..." + update -y + + if [[ $(type -t update-sdk 2>/dev/null 1>&2) ]]; then + log "\n\n\n`date` - Updating SDKs..." + update-sdk + fi + + log "\n\n\n`date` - Done with update-all!" +} +alias all-update="update-all" + +PROJECT_SHARED_OLD01="$HOME/.env-shared" +if [[ -d "$PROJECT_SHARED_OLD01" ]]; then + log "`date` - Removing old project name '$PROJECT_SHARED_OLD01'." + mv -v "$PROJECT_SHARED_OLD01" "$TRASH"/env-shared-deleteme | grep -v ".git" +fi + +# Shortcuts # + +function send-master { send_master.sh; } +alias push-master="send-master" +alias sync-master="send-master" + +function pull-clone { pull_clone.sh; } +alias get-clone="pull-clone" +alias sync-clone="pull-clone" + +alias send-sync="send-master" +alias push-sync="send-master" +alias pull-sync="pull-clone" +alias get-sync="pull-clone" +function sync-sync { + cat <<- EOF + Command not implemented, too dangerous guessing the state of the folder. + + Please use push-sync and pull-sync in the correct order for its current state. + EOF +} + +function goodbye { update -y; bye; } + +function clone { + rsync -auPhz --delete --exclude '.gradle' --exclude 'app/build' "$@" +} + +function now { date "+%Y%m%d-%H%M%S"; } +function today { date "+%Y%m%d"; } + +function log { echo -e "$1"; } +function blog { echo -e "\n\n$1\n\n"; } + +function pull { + if [[ -d .git ]]; then + echo "Recognized git project, pulling latest changes." + git pull --recurse-submodules + else + echo "Not a git repo, attempting to sync with SFTP server." + pull-clone + fi +} + +function push { + if [[ -d .git ]]; then + echo "Recognized git project, promoting branch to stage and prod." + git push && eval load-stage && eval load-prod + else + echo "Not a git repo, attempting to sync with SFTP server." + send-master + fi +} + +function set-variable { + var="$1" + val="$2" + echo -n "export $var=\"$val\" - " + + export $var="$val" + status="$?" + + if [[ "$val" == "${!var}" ]]; then + echo "Success!" + return 0 + fi + + echo "Failed with status '$status', $var is '${!var}'." + return $status +} +alias set-var="set-variable " + +# Enhance Bin Scripts # + +# MASTER and CLONE folders. + +function send-masters { + echo -e "`date` - Looping through MASTER directories." + ls | grep "\-MASTER" | while read dir; do + echo -e "\n`date` - Found '$dir'..." + cd $dir + send-master + cd .. + done + echo -e "\n`date` - Done checking for MASTER directories." +} +alias push-masters="send-masters" +alias sync-masters="send-masters" + +function pull-clones { + echo -e "`date` - Looping through clone directories." + ls | grep "\-clone" | while read dir; do + echo -e "\n`date` - Found '$dir'..." + cd $dir + pull-clone + cd .. + done + echo -e "\n`date` - Done checking for clone directories." +} +alias get-clones="pull-clones" +alias sync-clones="pull-clones" + +function sync-all { + push-masters + echo -e "\n" + pull-clones + + echo -e "\n`date` - Skipping SYNC folders! Please do their loads separately." + ls | grep "\-SYNC" | while read dir; do + echo "- $dir" + done + + echo -e "`date` - Done.\n" +} +function sync-all-loop { + typeset -i sleep_time count + if [[ "$1" ]]; then + sleep_time="$1" + fi + if [[ -z "$sleep_time" || "$sleep_time" == 0 ]]; then + sleep_time="300" + fi + log "`date` - Sleep timer set for '$sleep_time' seconds." + count=0 + while true; do + sync-all + count=$(( count + 1 )) + echo -e "\n\n*** Sleeping for '$sleep_time' after run# '$count'! ***\n\n" + sleep $sleep_time + done +} + +# SYNC folders. + +function send-syncs { + echo -e "`date` - Looping through SYNC directories." + ls | grep "\-SYNC" | while read dir; do + echo -e "\n`date` - Found '$dir'..." + cd $dir + send-master + cd .. + done + echo -e "\n`date` - Done checking for SYNC directories." +} +alias push-syncs="send-syncs" + +function pull-syncs { + echo -e "`date` - Looping through SYNC directories." + ls | grep "\-SYNC" | while read dir; do + echo -e "\n`date` - Found '$dir'..." + cd $dir + pull-clone + cd .. + done + echo -e "\n`date` - Done checking for SYNC directories." +} +alias get-syncs="pull-syncs" + +function sync-syncs { + cat <<- EOF + Command not implemented, too dangerous guessing the state of the folder. + + Please use push-syncs and pull-syncs in the correct order for its current state. + EOF +} + +# Audio # + +# Video # + +# Optimize the bitrate and audio levels for an edited video. +function process-video-usage { + echo "USAGE: process-video oldFile newFile [videoBitrate] [audioBitrate] [sizeRating] [numPasses] [forceBitrate]" + echo -n "Purpose: Call ffmpeg with preferred video posting settings. " + echo -n "Bitrates default to 2000k and 192k, size is 720, passes is 1, and force is N." + echo "These work well on Odysee and are fairly small as backups." + echo "Examples:" + echo "- Create a small file for quick streaming." + echo " process-video youcut.mp4 20240210.mp4 1200k 128k 480" + echo "- Create a larger file for something like YouTube." + echo " process-video youcut.mp4 20240210_1080p.mp4 5000k 256k 1080" +} +function process-video { + # Parameters + file="$1" + newfile="$2" + video="$3" + audio="$4" + size="$5" + passes="$6" + force="$7" + + # Validations + if [[ -z $file || ! -e $file ]]; then + echo "ERROR: Original file '$file' does not exist." >&2 + process-video-usage + return 1 + fi + + if [[ -z $newfile ]]; then + echo "ERROR: New file's name must be provided." >&2 + process-video-usage + return 1 + elif [[ -e $newfile ]]; then + echo "ERROR: New file '$newfile' already exists." >&2 + du -h "$newfile" + process-video-usage + return 1 + fi + + echo "`date` - Converting '$file' to '$newfile'." + + if [[ -z $video ]]; then + video="2000k" + fi + if [[ $force == "Y" ]]; then + video="-b:v $video" + else + video="-b:v $video -minrate 0 -maxrate $video -bufsize $video" + fi + + if [[ -z $audio ]]; then + audio="192k" + fi + audio="-b:a $audio" + + if [[ -z $size ]]; then + size="720" + fi + # Lanczos is good for upscaling, but this is usually used for downscaling. + if [[ ! -z "$PV_VERTICAL_ASPECT_RATIO" ]]; then + size="-filter:v scale=$size:-1" #:flags=lanczos" + else + size="-filter:v scale=-1:$size" #:flags=lanczos" + fi + + if [[ -z $passes ]]; then + passes=1 + fi + pass="" + if [[ $passes != 1 || ! -z "$PV_2PASS" ]]; then + passes=2 + pass="-pass 2" + fi + + v2="" + if [[ ! -z "$PV_V2" ]]; then + v2="-crf 18 -preset veryslow -c:a aac -ar 48000" + #-profile:v high - Letting ffmpeg use the default profile. + fi + + time="" + if [[ ! -z "$PV_TIME" ]]; then + time="`which time`" + fi + + quiet="-hide_banner -loglevel level+warning" + if [[ ! -z "$PV_PROGRESS" ]]; then + quiet="-hide_banner -loglevel level+info" + fi + if [[ ! -z "$PV_VERBOSE" ]]; then + quiet="-loglevel level+verbose" + fi + + ## Main ## + # More information on two-pass processing with ffmpeg + # https://cinelerra-gg.org/download/CinelerraGG_Manual/Two_pass_Encoding_with_FFmp.html + if [[ $passes == 2 ]]; then + set -x + $time ffmpeg -nostdin $quiet \ + -i "$file" $size $video $audio \ + -filter:a "dynaudnorm=f=33:g=65:p=0.66:m=33.3" \ + -vcodec libx264 -movflags +faststart \ + $v2 \ + -pass 1 -f mp4 /dev/null -y + status=$? + set +x + echo "`date` - Done with the first pass." + if [[ $status != 0 ]]; then + echo "Received unsuccessful status, exiting." + return 1 + fi + fi + + set -x && + $time ffmpeg -nostdin $quiet \ + -i "$file" $size $video $audio \ + -filter:a "dynaudnorm=f=33:g=65:p=0.66:m=33.3" \ + -vcodec libx264 -movflags +faststart \ + $v2 \ + $pass "$newfile" + status="$?" + set +x + echo "`date` - Done with the final pass." + + if [[ $passes == 2 && $status == 0 ]]; then + mv -v ffmpeg2pass*.log* ~/TRASH/ + fi + + echo "`date` - Syncing data." + sync + sleep 10 + sync + + if [[ -s $newfile ]]; then + echo "`date` - Getting file sizes." + du -h "$file" + du -h "$newfile" + else + echo "ERROR: New file not created or has a 0 size." >&2 + fi + + unset PV_VERTICAL_ASPECT_RATIO + unset PV_V2 + unset PV_TIME + unset PV_PROGRESS + unset PV_VERBOSE + unset PV_2PASS + + echo -e "\n`date` - Finished with status '$status'." + return $status +} +alias pv="process-video" +alias fn='basename `pwd`' # Folder Name +alias qpv='pv ./raw/YouCut*.mp4 `fn`.mp4' # Quick Process Video + +alias set-pv-vertical='set-var PV_VERTICAL_ASPECT_RATIO "y" ' +alias set-pv-time='set-var PV_TIME "y" ' +alias set-pv-progress='set-var PV_PROGRESS "y" ' +alias set-pv-verbose='set-var PV_VERBOSE "y" ' +alias set-pv-2pass='set-var PV_2PASS "y" ' +alias set-pv-v2='set-var PV_V2 "y" ' +alias set-pv-v2='set-var PV_YIFY "y" ' + +alias set-pv-vert='set-pv-vertical ' +alias set-pv2='set-pv-v2; set-pv-2pass; set-pv-progress ' + +alias pvs='set-pv-vert; pv ' +alias pv2='set-pv2; pv ' + +alias pv2s='set-pv2; set-pv-vert; pv ' +alias pvs2='pv2s ' + +alias qpv2='set-pv2; qpv ' + +# 20260713 - Attempt at compressing videos as well as done for torrented movies. +function pv-yify { + # ffmpeg -i input.mkv -c:v libx264 -crf 27 -x264-params cabac=1:ref=5:analyse=0x133:me=umh:subme=9:chroma-me=1:deadzone-inter=21:deadzone-intra=11:b-adapt=2:rc-lookahead=60:vbv-maxrate=10000:vbv-bufsize=10000:qpmax=69:bframes=5:direct=auto:crf-max=51:weightp=2:merange=24:chroma-qp-offset=-1:sync-lookahead=2:psy-rd=1.00,0.15:trellis=2:min-keyint=23:partitions=all -c:a aac -ar 44100 -b:a 128k -map 0 output.mp4 + input="$1" + output="$2" + ratio="$3" + audio="$4" + + if [[ -z "$input" ]]; then + cat <<- EOF + Usage: pv-yify INPUT_FILE [OUTPUT_FILE] [ASPECT_RATIO] + + Examples: + + - Create file raw.mp4.pv-yify.mp4 without changing aspect ratio: + $ pv-yify raw.mp4 + + - Compress a video and ensures it is 720p: + $ pv-yify raw.mp4 compressed.mp4 1280:720 + + - Compress a video ensuring that it is 720 pixels tall: + $ pv-yify raw.mp4 vertical.mp4 720:-1 + EOF + fi + + if [[ -z "$output" ]]; then + output="$input.pv-yify.mp4" + fi + + echo -e "\n`date` - Converting '$input' with YIFY-like compression to '$output'." + + if [[ -f "$output" ]]; then + echo -e "\n`date` - Moving '$output' to TRASH." + mv -v "$output" ~/TRASH/ + fi + + if [[ -n "$ratio" ]]; then + if [[ "$ratio" != *":"* ]]; then + echo "ERROR: Optional ratio parameter needs to be like '-1:720' (horizontal) or '720:-1' (vertical)". + return 1 + fi + size="-filter:v scale=$ratio" + fi + + if [[ -z "$audio" ]]; then + audio="128k" + fi + + echo -e "\n`date` - Starting FFMPEG...\n" + set -x + ffmpeg -i "$input" \ + -hide_banner -loglevel level+warning \ + -c:v libx264 -crf 27 -c:a aac -ar 44100 -b:a "$audio" -map 0 \ + -x264-params cabac=1:ref=5:analyse=0x133:me=umh:subme=9:chroma-me=1:deadzone-inter=21:deadzone-intra=11:b-adapt=2:rc-lookahead=60:vbv-maxrate=10000:vbv-bufsize=10000:qpmax=69:bframes=5:direct=auto:crf-max=51:weightp=2:merange=24:chroma-qp-offset=-1:sync-lookahead=2:psy-rd=1.00,0.15:trellis=2:min-keyint=23:partitions=all \ + $ratio \ + "$output" + set +x + echo -e "\n`date` - Finished FFMPEG." + + echo -e "\n`date` - Syncing and checking file sizes." + sync + sleep 5 + ls -lh "$input" "$output" + + echo -e "\n`date` - Done!" +} +alias yify="pv-yify " +alias yify-pv="pv-yify " + +function set-pv-all { + #set-var PV_VERTICAL_ASPECT_RATIO "y" + set-var PV_V2 "y" + set-var PV_TIME "y" + set-var PV_PROGRESS "y" + set-var PV_VERBOSE "y" + set-var PV_2PASS "y" +} +alias set-pv-everything='set-pv-all ' + +function unset-pv-all { + unset PV_VERTICAL_ASPECT_RATIO + unset PV_V2 + unset PV_TIME + unset PV_PROGRESS + unset PV_VERBOSE + unset PV_2PASS +} +alias unset-pv-everything='unset-pv-all ' + +# Allow converting video to audio and other smaller +# tasks than what process-video is intended to do. +function basic-process-usage { + echo "basic-process INPUT OUTPUT NORMALIZE [EXTRA]" + echo -n "Pass a file through ffmpeg with the option" + echo "to easily normalize the audio with a Y." + echo "Examples:" + echo "- Normalize audio on a video." + echo " basic-process video.mp4 normalized.mp4 Y" + echo "- Convert a video to audio at 192k." + echo " basic-process video.mp4 audio.mp3 N '-b:a 192k'" +} +function basic-process { + # Parameters + input="$1" + output="$2" + typeset -u normalize + normalize="$3" + extra="$4" + + echo "`date` - Starting basic-process" + + # Validations + if [[ -z $input || ! -e $input ]]; then + echo "ERROR: Input file '$input' does not exist." >&2 + basic-process-usage + return 1 + fi + + if [[ -z $output ]]; then + echo "ERROR: Output file's name must be provided." >&2 + basic-process-usage + return 1 + elif [[ -e $output ]]; then + echo "ERROR: Output file '$output' already exists." >&2 + du -h "$output" + basic-process-usage + return 1 + fi + + if [[ $normalize == "Y" ]]; then + echo "Normalize set to TRUE." + normal="-filter:a dynaudnorm=f=33:g=65:p=0.66:m=33.3" + else + echo "No audio normalization is being done." + fi + + # Main + echo "`date` - Converting '$input' to '$output'." + set -x + ffmpeg -nostdin -hide_banner -loglevel quiet \ + -i "$input" $extra $normal "$output" + status=$? + set +x + + if [[ $status != 0 ]]; then + echo "`date` - WARNING: ffmpeg exited with status '$status'." >&2 + fi + + # Finish + if [[ ! -s $output ]]; then + echo "`date` - ERROR: Output '$output' not created or has 0 size." >&2 + return 1 + fi + + sync + echo "`date` - '$output' has been created successfully." + sleep 3 + du -h "$input" + du -h "$output" + + echo "`date` - Finished basic-process" + return 0 +} +alias bp="basic-process" +alias bv="bp" + +# Function to automatically append the Y. +function fix-audio { basic-process "$1" "$2" Y; } +function eq { fix-audio "$1" "$2"; } + +# Function to easily turn a video to audio without typing the audio name. +function convert-to-audio { + video="$1" + audio="$2" + if [[ -z "$2" || "$2" == "Y" ]]; then + audio="${1//mp4/mp3}" + fi + volume="" + if [[ ( "$2" == "Y" && -z "$3" ) || "$3" == "Y" ]]; then + $volume="Y" + fi + basic-process "$video" "$audio" $volume +} +alias v2a="convert-to-audio" +alias vta="v2a" +alias pull-audio="v2a" +alias pa="v2a" + + +### Web ### + +function download-website { + website="$1" + if [[ -z "$website" ]]; then + echo "ERROR: Website not provided. $website" + return + fi + if [[ "$website" != "http"* ]]; then + website="http://$website" + fi + # https://simpleit.rocks/linux/how-to-download-a-website-with-wget-the-right-way/ + # Does not simplify the links for offline usage. + # wget --wait=2 \ + # --level=inf \ + # --limit-rate=20K \ + # --recursive \ + # --page-requisites \ + # --user-agent=Mozilla \ + # --no-parent \ + # --convert-links \ + # --adjust-extension \ + # --no-clobber \ + # -e robots=off \ + # $website && + + # https://www.digitalcitizen.life/how-to-download-entire-website-for-offline-viewing/ + # This one is supposed to work too and is much smaller. + # wget --mirror \ + # --convert-links \ + # --adjust-extension \ + # --page-requisites \ + # --no-parent \ + # $website && + + # Combine the two by using mirow and removing the rate limit. + wget --mirror \ + --wait=2 \ + --level=inf \ + --recursive \ + --page-requisites \ + --user-agent=Mozilla \ + --no-parent \ + --convert-links \ + --adjust-extension \ + --no-clobber \ + -e robots=off \ + --timeout=15 \ + --tries=0 \ + --continue \ + --waitretry=5 \ + --random-wait \ + $website && + { + echo -e "\nSuccess!" + } || { + echo -e "\nERROR: Command reported a failure. (Error code '$?')" + echo "This may mean that the URL was not converted to local links." + echo "Please check the error and contents and try again if needed." + } +} +alias website-download="download-website" +alias curl-site="download-website" +alias pull-site="download-website" +alias site-pull="download-website" +alias curl-www="download-website" +alias pull-www="download-website" +alias www-pull="download-website" + +function run-site { + python3 -m http.server +} +alias run-html="run-site" +alias exec-site="run-site" +alias exec-html="run-site" +alias site-host="run-site" +alias host-site="run-site" + +# TBD: Move this to a different section? +function git-check { + dir="`pwd`" + if [[ -n "$1" ]]; then + dir="$1" + fi + + echo "Checking '$dir' for git changes." + ls -d "$dir"/* | while read project; do + if [[ ! -d $project ]]; then + continue + fi + echo -e "\n*** `basename $project` ***" + cd $project + if [[ -d .git ]]; then + git ls-remote --exit-code --heads origin dev + dev_exists="$?" + if [[ "$dev_exists" == 0 ]]; then + git switch dev + elif [[ "$dev_exists" == 2 ]]; then + git switch main + else + echo "ERROR: Unknown status for dev_exists, '$dev_exists'." + continue + fi + git pull + git push + else + echo "Not a Git project, skipping!" + fi + done + echo -e "\nDone!" +} + +# TBD: Move this to a different section? +function check-colors { + min=0 + max=256 + unset i + echo "Current terminal supports '`tput colors`' colors." + echo "Displaying examples..." + for (( i = min; i <= max; i++ )); do + tput setaf $i + printf "%03d" "$i" + tput sgr0 + if (( i < max )); then + printf " " + fi + done + printf "\n" +} +alias color-check="check-colors" +alias show-colors="check-colors" +alias test-colors="check-colors" +alias colors="check-colors" +alias term-colors="check-colors" +alias display-colors="check-colors" + + +## Finalize ## + +# Export all functions! # +eval "$(declare -F | grep -v _ | sed 's/-f /-fx /')" + +# Run update checker in background. +if [[ "$USER" != "root" ]]; then + ( + if [[ -d "$PROJECT_SHARED" ]]; then + git -C "$PROJECT_SHARED" fetch >/dev/null 2>&1 \ + && git -C "$PROJECT_SHARED" status \ + | grep "is behind" \ + | while read status; do + title=TBD + message=TBD + success=0 + reload-shared || success=1 + if [[ "$success" == 0 ]]; then + title="env-shared Updated" + message="Reloaded automatically, please reload BASH. :)" + else + title="env-shared Updates Available" + message="Update with 'reload-shared'." + fi + if [[ -d /sdcard ]]; then + termux-notification \ + -t "$title" \ + -c "$message" + else + notify-send "$title" "$message" + fi + done + fi >> "$HOME"/Reports/env-shared.log.txt 2>&1 & + ) +fi + + +## Complete! ## + +[[ $(whoami) != "root" ]] && + echo "`date` - Shared RC Config - Complete!" + +export _LOADED_SHARED_RC=true diff --git a/vimrc.vim b/vimrc.vim new file mode 100644 index 0000000..745f841 --- /dev/null +++ b/vimrc.vim @@ -0,0 +1,11 @@ +" Turn off syntax, flashy lights, etc. Make VIM into a basic editor. +syntax off +set nohlsearch +set noautoindent noautowrite noshowmatch wrapmargin=0 report=1 ts=3 +set ignorecase + +" Turn off auto-commenting. +autocmd Filetype * set fo-=c fo-=r fo-=o + +" qq shortcut for immediately exiting all files without saving. +nnoremap qq :qa!