Skip to content

Instantly share code, notes, and snippets.

@Telematica
Last active January 24, 2024 20:13
Show Gist options
  • Save Telematica/be25f0f97be7027bdab9fdc2670f60e6 to your computer and use it in GitHub Desktop.
Save Telematica/be25f0f97be7027bdab9fdc2670f60e6 to your computer and use it in GitHub Desktop.
POSIX Utility Scripts for Mac OSX, Linux & Unix-like. Terminal Profiles and Utilities (bash, vim...)

POSIX Utility Scripts for Mac OSX, Linux & Unix-like.

Features:

  • Terminal Profiles and Utilities (bash, vim...)
  • Personal Scripts
#Git
alias ga="git add"
alias gc="git commit"
alias gco="git checkout"
alias gd="git diff"
alias gfa="git fetch --all"
alias gl="git log"
alias glol="git log --oneline"
alias gpo="git push origin"
alias gpuo="git pull origin"
alias gs="git status"
alias gsh="git stash"
alias gshl="git stash list"
#Yarn
alias y="yarn --pure-lockfile"
#Misc
alias so="source $HOME/.zshrc"
alias mergepdf="/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/Resources/join.py -o merged.pdf *pdf"
alias k="utils::kill-processes-by-port"
alias ko="k 3000"
alias of="git::utils::open-all-status-files"
alias fbp="social::facebook::get-profile-url"
alias twp="social::twitter::get-user-id"
alias inp="social::instagram::get-profile-url"
alias saef=splitAndGpgEncryptFile
alias daj=decryptAndJoin
alias ds="utils::display-sleep-now"
alias usg="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security --disable-chromeTemp --user-data-dir=~/"
#!/usr/bin/env bash
#Target OS: [Mac]
# https://stuartdotson.com/blog/how-to-programmatically-open-a-new-terminal-tab-or-window/
# https://stackoverflow.com/questions/56037312/open-split-a-iterm2-window-and-execute-commands-inside-each-of-those-panes
function runbot() {
osascript -e "
tell application \"iTerm\"
activate
set W to current window
if W = missing value then set W to create window with default profile
tell W's current session
split vertically with default profile
split vertically with default profile
end tell
set T to W's current tab
write T's session 1 text \"cd ~/ebot && yarn dev-server\"
write T's session 2 text \"cd ~/ebot && yarn dev-bot\"
write T's session 3 text \"cd ~/ebot\"
end tell
"
}
#!/usr/bin/env bash
#Sources
#https://askubuntu.com/questions/302696/bash-script-source-no-such-file-or-directory
SCRIPTS_DIR="$HOME/be25f0f97be7027bdab9fdc2670f60e6"
# @todo : https://gulvi.com/serie/curso-programacion-bash/capitulo/arrays-bash
# @todo : https://atareao.es/tutorial/scripts-en-bash/arrays-en-bash/
FILES=(
".env-vars.sh"
".applescript.sh"
".encrypt-file.sh"
".social.sh"
".utils.sh"
".utils-os.sh"
".utils-filesystem.sh"
".utils-time.sh"
".aliases.sh"
".constants.sh"
".templates.sh"
".vimrc"
"pomodoro.sh"
)
#source $SCRIPTS_DIR/.aliases.sh
#source $SCRIPTS_DIR/.encrypt-file.sh
#source $SCRIPTS_DIR/.social.sh
#source $SCRIPTS_DIR/.utils.sh
for i in ${FILES[@]}
do
source $SCRIPTS_DIR/$i
done
openssl sha512 /full/path/to/your/file
shasum -a 512 /full/path/to/your/file
# Custom Directories
export CUSTOM_SCRIPTS="$HOME/be25f0f97be7027bdab9fdc2670f60e6"
# https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Underline
UBlack='\033[4;30m' # Black
URed='\033[4;31m' # Red
UGreen='\033[4;32m' # Green
UYellow='\033[4;33m' # Yellow
UBlue='\033[4;34m' # Blue
UPurple='\033[4;35m' # Purple
UCyan='\033[4;36m' # Cyan
UWhite='\033[4;37m' # White
# Background
On_Black='\033[40m' # Black
On_Red='\033[41m' # Red
On_Green='\033[42m' # Green
On_Yellow='\033[43m' # Yellow
On_Blue='\033[44m' # Blue
On_Purple='\033[45m' # Purple
On_Cyan='\033[46m' # Cyan
On_White='\033[47m' # White
# High Intensity
IBlack='\033[0;90m' # Black
IRed='\033[0;91m' # Red
IGreen='\033[0;92m' # Green
IYellow='\033[0;93m' # Yellow
IBlue='\033[0;94m' # Blue
IPurple='\033[0;95m' # Purple
ICyan='\033[0;96m' # Cyan
IWhite='\033[0;97m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
# High Intensity backgrounds
On_IBlack='\033[0;100m' # Black
On_IRed='\033[0;101m' # Red
On_IGreen='\033[0;102m' # Green
On_IYellow='\033[0;103m' # Yellow
On_IBlue='\033[0;104m' # Blue
On_IPurple='\033[0;105m' # Purple
On_ICyan='\033[0;106m' # Cyan
On_IWhite='\033[0;107m' # White
# TELEGRAM
# TELEGRAM_MAX_UPLOAD_FILE_SIZE=1500000000
# TELEGRAM_MAX_UPLOAD_FILE_SIZE=2147483648
TELEGRAM_MAX_UPLOAD_FILE_SIZE=2000000000
#!/usr/bin/env bash
#Target OS: [Mac, Linux, Unix-like]
: '
@func Split and GPG Encrypt a File
@param string require $1 FILE
@param string require $2 FILE_NAME
@param string optional $3 TEST_FILE
@return void
'
function splitAndGpgEncryptFile() {
if [ -z $1 ]
then
echo "${IRed}No Input File! ${Color_Off}Please type a filename as first argument."
return 1;
fi
if [ -z $2 ]
then
echo "${IRed}No New File name!"
return 1;
fi
if [ ! -f $1 ]
then
echo "${IRed}File does not exist!"
return 1;
fi
declare BAR RESOLUTION="0" DURATION="0"
SPLIT_SIZE=$TELEGRAM_MAX_UPLOAD_FILE_SIZE
FILE_SIZE=$(wc -c < $1)
STARTED_AT=$(date +%F" "%T)
DATE=$(date)
FILES=""
if [ $FILE_SIZE -gt $TELEGRAM_MAX_UPLOAD_FILE_SIZE ]
then
FILE_WILDCARD="$2."
CURRENT_DIRECTORY=$(pwd)
percentBar 10 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 10%" "Splitting file... \r"
split -b $SPLIT_SIZE $1 $FILE_WILDCARD 2> /dev/null
percentBar 20 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 20%" "Encrypting splitted files... \r"
find $CURRENT_DIRECTORY -name "$FILE_WILDCARD"'a*' -maxdepth 1 | \
while read i
do
FILE=$(echo $i | grep -Eo "(\w+)$")
FILES+="$FILE_WILDCARD$FILE.gpg,"
gpg -c --batch --passphrase-file ~/Downloads/passphrase.txt "$i" 2> /dev/null
rm $i
done
FILES="${FILES:0:-1}"
percentBar 40 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 40%" "Testing encrypted files... \r"
if [ ! -z $3 ] && [ $FILE_SIZE -gt $TELEGRAM_MAX_UPLOAD_FILE_SIZE ]
then
DECRYPT=$(decryptAndJoin $2 2>&1 /dev/null)
fi
else
percentBar 20 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 20%" "Encrypting file... \r"
gpg -c --batch --output "$2.gpg" --passphrase-file ~/Downloads/passphrase.txt "$1" 2> /dev/null
percentBar 40 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 40%" "Testing encrypted file... \r"
gpg --batch --passphrase-file ~/Downloads/passphrase.txt --output "$2" --decrypt "$2.gpg" 2> /dev/null
fi
percentBar 60 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 60%" "Creating stats... \r"
FILE_IS_VIDEO=$(utils::file-is-video $1)
if [ $FILE_IS_VIDEO -eq 1 ]
then
utils::file-video-metadata $1 DURATION RESOLUTION
DURATION=$(utils::secondsToHMS $DURATION)
fi
ENDS_AT=$(date +%F" "%T)
SCREEN=$(splitAndGpgEncryptFile::template $DATE $1 $FILE_SIZE 1 "Completed" $STARTED_AT $ENDS_AT $DURATION $RESOLUTION $2)
percentBar 80 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 80%" "Hashing file... "
HASH=$(shasum -a 512 $2)
percentBar 100 25 BAR
echo -ne "\rProgress: \e[44;33;1m$BAR\e[0m at 100%" "Done. " \\n
echo -ne "$SCREEN" \\n
echo $HASH
printnodeoutput "$2.gpg" $1 $DURATION $RESOLUTION $FILE_SIZE $HASH $FILES
return 0
}
: '
@func Decrypt and Join a GPG file
@param string require $1 FILE
@return void
'
function decryptAndJoin() {
if [ -z $1 ]
then
echo "${IRed}No Input File! ${Color_Off}Please type a filename as first argument."
return 1;
fi
FINAL_FILE_NAME="${1//\.gpg/}"
if [ -f $FINAL_FILE_NAME ]
then
echo "${IRed}File already exists! To avoid overwriting it, please remove it manually."
return 1;
fi
if test -e $1 && [[ $1 == *gpg ]]
then
echo "${IRed}Decrypting a single file: ${On_Red}$1"
echo "${IBlue}Starting at: " $(date) $(date +"%s") "${Color_Off}"
gpg --batch --passphrase-file ~/Downloads/passphrase.txt --output "$FINAL_FILE_NAME" --decrypt "$1"
echo "${IBlue}Finished at: " $(date) $(date +"%s") "${Color_Off}"
echo "Checksum: ${BRed}" $(shasum -a 512 $1) \\n
return 0;
elif ! test -e $1 && ! test -e "$1.aa.gpg"
then
echo "${IRed}Not a valid file."
return 1;
fi
# @todo detect gpg commands errors
echo "${IRed}Decrypting multiple files for: ${On_Red} $1"
CURRENT_DIRECTORY=$(pwd)
find $CURRENT_DIRECTORY -name "$1"'.a*.gpg' -maxdepth 1 | grep -Eo "$1"'.a\w' | \
while read i
do
echo "${IBlue}Starting at: " $(date) $(date +"%s") "${Color_Off}"
gpg --batch --passphrase-file ~/Downloads/passphrase.txt --output "$i" --decrypt "$i.gpg"
echo "${IBlue}Finished at: " $(date) $(date +"%s") "${Color_Off}"
done
echo "${IRed}Joining files for: ${On_Red}$1"
for file in $(find $CURRENT_DIRECTORY -name "$1"'.a*.gpg' -maxdepth 1 | sort | grep -Eo "$1"'.a\w'); do cat $file >> $1; done
echo "Checksum: ${BRed}" $(shasum -a 512 $1) \\n
}
: '
@func Print File Info to JSON output
@param string require $1 FILE
@param string require $2 NEW_FILE
@return void
'
function outputfileinfo() {
if [ -z $1 ]
then
echo "${IRed}No Input File! ${Color_Off}Please type a filename as first argument."
return 1;
fi
if [ -z $2 ]
then
echo "${IRed}No New File name!"
return 1;
fi
FILE=$1
FILE_IS_VIDEO=$(utils::file-is-video $FILE)
FILE_SIZE=$(wc -c < $FILE)
HASH=$(shasum -a 512 $FILE)
declare RESOLUTION="0" DURATION="0"
FILES="" # @todo calculate number of files based on file size
if [ $FILE_IS_VIDEO -eq 1 ]
then
utils::file-video-metadata $FILE DURATION RESOLUTION
DURATION=$(utils::secondsToHMS $DURATION)
fi
printnodeoutput "$2.gpg" $1 $DURATION $RESOLUTION $FILE_SIZE $HASH $FILES
return 0
}
function printnodeoutput() {
# @todo Implement: Node, Perl, Python, PHP, Ruby
# @todo Refactor $LANG and $EXT assignments
[ $(util::command-exists node) = "false" ] && { echo "Node.js not installed. No input json metadata."; return 1; } || LANG=node
# [ $(util::command-exists python) = "false" ] && { echo "Python not installed. No input json metadata."; return 1; } || BIN=python
# [ $(util::command-exists ruby) = "false" ] && { echo "Ruby not installed. No input json metadata."; return 1; } || BIN=ruby
LC_ALL=en_US.UTF-8
ID=$(echo $1 | grep -Eo "^(\w+)")
DATEADDED="$(date '+%m/%d/%Y') 00:00:00"
FILENAME=$(echo $1)
ORIGINAL=$2
EXTENSION=$(echo $2 | grep -Eo "(\w+)$")
DURATION=$3
DIMENSION=$4
FILESIZE=$(printf "%'.0f\n" $5)
FILESIZE_HUM=$(utils::human_print $5)
CHECKSUM=$(echo $6 | grep -Eo "^(\w+)")
FILES=$7
case $LANG in
"node")
EXT="js"
;;
"python")
EXT="py"
;;
"ruby")
EXT="rb"
;;
esac
$LANG $CUSTOM_SCRIPTS/filedatatojson.$EXT $ID \
$DATEADDED \
$FILENAME \
$ORIGINAL \
$EXTENSION \
$DURATION \
$DIMENSION \
$FILESIZE \
$FILESIZE_HUM \
$CHECKSUM \
$FILES
}
# Setting for the new UTF-8 terminal support in Lion
export LC_CTYPE="es_MX.UTF-8"
export LC_ALL="es_MX.UTF-8"
export LANG="es_MX.UTF-8"
# LANG = "en_US.UTF-8"
#!/usr/bin/env bash
#Target OS: [Mac, Linux, Unix-like]
function git::utils::open-all-status-files() {
#default_extension = 'css|flow|js|jsx'
#gs | grep -Eo 'modified.*(\S+\.(js))$' | grep -Eo '(\S+\.(js))$' | \
gs | grep -Eo '\S+\.(js|css)' | \
while read i
do
echo $i
code $i
done
}
#!/usr/bin/env bash
function siapa() {
START_ID=10000000
ID=$(tail -n 1 VARS | grep -iEo '[0-9]+$' || echo $START_ID)
NEW_ID=$((10#$ID+1))
LENGTH=$((12-${#ID}))
#LENGTH=$((12-$ID+0))
NEW_ID=$(printf %012d $NEW_ID)
echo $ID
echo $NEW_ID;
echo $LENGTH;
echo $_pid
#curl https://reciboenlinea.siapa.gob.mx/pbarec2003/default.aspx\?pcta=000011339333 --output ~/Downloads/SIAPA/a.pdf
curl https://reciboenlinea.siapa.gob.mx/pbarec2003/default.aspx\?pcta=$NEW_ID --output ~/Downloads/SIAPA/$NEW_ID.pdf && \
echo $(date) $NEW_ID >> VARS && siapa
}
#!/usr/bin/env bash
#Target OS: [Mac, Linux, Unix-like]
function social::twitter::get-user-id() {
if [ -z $1 ]
then
echo "Please input a Twitter username"
return 1;
fi
RESULT=$(curl 'https://tweeterid.com/ajax.php' \
-s \
-H 'Connection: keep-alive' \
-H 'Accept: */*' \
-H 'Sec-Fetch-Dest: empty' \
-H 'X-Requested-With: XMLHttpRequest' \
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36' \
-H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
-H 'Origin: https://tweeterid.com' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Referer: https://tweeterid.com/' \
-H 'Accept-Language: en-US,en;q=0.9' --data 'input='$1 --compressed);
if [ $RESULT = "error" ]
then
echo "This profile is probably not longer available. Also, check for any typo on the username.";
return 0;
fi
echo "https://twitter.com/i/user/$RESULT"
}
function social::facebook::get-profile-url() {
PUBLIC=$(curl -v --silent https://www.facebook.com/$1 2>&1 | grep -oEi 'fb://(profile|page)/([0-9]+)' | grep -oEi '[0-9]+' | tail -1)
PRIVATE=""
if [ -z $PUBLIC ]
then
PRIVATE=$(curl -v --silent https://www.facebook.com/$1 2>&1 | grep -oEi '"entity_id":"([0-9]+)"' | grep -oEi '[0-9]+' | tail -1)
fi
if [ -z $PUBLIC ] && [ -z $PRIVATE ]
then
echo "This profile is probably not Public, or check for any typo on the username."
return 0;
fi
ACTUAL=$([[ -z $PUBLIC ]] && echo $PRIVATE || echo $PUBLIC)
URL=https://facebook.com/profile.php?id=$ACTUAL
echo $URL
#open $URL
#for available Profiles (restricted, no way to get ID)
#document.querySelector('[property="al:ios:url"]').content.match('[0-9]+$')[0]
}
function social::instagram::get-profile-url() {
RESULT=$(curl 'https://www.instagram.com/'$1/ \
-H 'authority: www.instagram.com' \
-H 'cache-control: max-age=0' \
-H 'upgrade-insecure-requests: 1' \
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36' -H 'sec-fetch-dest: document' \
-H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9' \
-H 'sec-fetch-site: none' -H 'sec-fetch-mode: navigate' \
-H 'sec-fetch-user: ?1' -H 'accept-language: en-US,en;q=0.9' \
--compressed 2>&1 | grep -oEi 'profilePage_([0-9]+)' | grep -oEi '[0-9]+' | tail -1);
if [ -z $RESULT ]
then
echo "This profile is probably not longer available. Also, check for any typo on the username.";
return 0;
fi
URL=instagram://user?id=$RESULT
echo $URL
}
# https://linuxhint.com/length_of_string_bash/
# https://unix.stackexchange.com/questions/303960/index-a-string-in-bash
: '
@func Split and GPG Encrypt File Template Stats
@param string $1 DATA
@param string $2 FILE_NAME
@param string $3 FILE_SIZE
@param string $4 TOTAL_SPLIT_FILES
@param string $5 STATUS
@param string $6 STARTED_AT
@param string $7 ENDS_AT
@param string $8 DURATION
@param string $9 RESOLUTION
@param string $10 NEW_FILE_NAME
'
function splitAndGpgEncryptFile::template() {
LC_ALL=en_US.UTF-8
DATE=$1
FILE_NAME=$2
FILE_SIZE=$(printf "%'.0f\n" $3)
FILE_SIZE_HUMAN=$(utils::human_print $3)
TOTAL_SPLIT_FILES=$4
STATUS=$5
STARTED_AT=$6
ENDS_AT=$7
DURATION=$8
RESOLUTION=$9
NEW_FILE_NAME=$10
COLUMN_SIZE=$((83-4-9-3-${#FILE_NAME}-${#NEW_FILE_NAME}))
COLUMN_SIZE2=$((83-4-14-7-10-${#FILE_SIZE}-${#FILE_SIZE_HUMAN}))
COLUMN_SIZE3=$((9-${#STATUS}+1))
PADDING=$(printf %${COLUMN_SIZE}s ' ' | tr ' ' ' ')
PADDING2=$(printf %${COLUMN_SIZE2}s ' ' | tr ' ' ' ')
PADDING3=$(printf %${COLUMN_SIZE3}s ' ' | tr ' ' ' ')
NEW_FILENAME=$(echo ${FILE_NAME:0:6}...${FILE_NAME:(-10)})
TEMPLATE=$(cat << TEMPLATE
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Split And GPG Encrypt File (Executed at: ${DATE}) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ☑️ File: $FILE_NAME ${PADDING} ($NEW_FILE_NAME) │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ☑️ File Medata (Video Only) - Duration: $DURATION Dimensions: $RESOLUTION │
├─────────────────────────────────────────────────────────────────────────────────┤
│ ☑️ File Size: $FILE_SIZE bytes ($FILE_SIZE_HUMAN on disk) ${PADDING2} │
├───┬───────────┬─────────────────────┬─────────────────────┬─────────────────────┤
│ ☐ │ Status │ File Name │ Started at │ Ended at │
├───┼───────────┼─────────────────────┼─────────────────────┼─────────────────────┤
│ ✔️ │ $STATUS${PADDING3}│ $NEW_FILENAME │ $STARTED_AT │ $ENDS_AT │
└───┴───────────┴─────────────────────┴─────────────────────┴─────────────────────┘
TEMPLATE
)
echo $TEMPLATE
}
: '
@ref https://stackoverflow.com/questions/238073/how-to-add-a-progress-bar-to-a-shell-script
@funct Percent Bar (without animation)
@param string $1
@param number $2
@param string &$3 Variable to store percent bar string
'
function percentBar () {
local prct totlen=$((8*$2)) lastchar barstring blankstring;
printf -v prct %.2f "$1"
((prct=10#${prct/.}*totlen/10000, prct%8)) && printf -v lastchar '\\U258%X' $(( 16 - prct%8 )) || lastchar=''
printf -v barstring '%*s' $((prct/8)) ''
printf -v barstring '%b' "${barstring// /\\U2588}$lastchar"
printf -v blankstring '%*s' $(((totlen-prct)/8)) ''
printf -v "$3" '%s%s' "$barstring" "$blankstring"
}
: '
@func Retrieves file creation date with format: yy/mm/dd hh:mm:ss
@param string $1 FILE
@return void
'
function utils::file-creation-date() {
FILE=$1
stat -f "%SB" -t "Created at: %Y-%m-%d %H:%M:%S" "$FILE"
}
: '
@func Retrieves file size Mac0S Finder-like
@param string $1 FILE
@return void
'
function utils::file-size() {
FILE=$1
if [ -z $FILE ]
then
echo "${IRed}No Input File! ${Color_Off}Please type a filename as first argument."
return 1
fi
if [ ! -f $FILE ]
then
echo "${IRed}File does not exist!"
return 1
fi
FILE_SIZE_BYTES=$(stat -f "%z" $FILE)
FILE_SIZE_HUMAN=$(utils::human_print $FILE_SIZE_BYTES)
echo "$FILE_SIZE_BYTES bytes ($FILE_SIZE_HUMAN on disk)"
}
: '
@param string $1 FILE_PATH
@param string $2 DURATION (passed by reference variable) - optional
@param string $3 DIMENSIONS (passed by reference variable) - optional
@return void
'
# https://stackoverflow.com/questions/7362130/getting-video-dimension-resolution-width-x-height-from-ffmpeg
function utils::file-video-metadata() {
FILE_PATH=$1
TIME_IN_SECONDS=0
CMD_EXISTS=$(util::command-exists mdls)
FFPROBE_EXISTS=$(util::command-exists ffprobe)
# @todo test several video formats: mp4 (done), wmv (fails), mkv (?), etc...
if [ $FFPROBE_EXISTS = "true" ]
then
DIMENSIONS=$(ffprobe -i $1 -v error -select_streams v -show_entries stream=width,height -of csv=p=0:s=x)
DURATION=$(ffprobe -i $1 -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal)
TIME_IN_SECONDS=$(ffprobe -i $1 -show_entries format=duration -v quiet -of csv="p=0")
fi
if [ $CMD_EXISTS = "true" ] && [ $FFPROBE_EXISTS = "false" ]
then
mdls -name kMDItemDurationSeconds -name kMDItemPixelHeight -name kMDItemPixelWidth $1 | \
while read i
do
if [[ $i =~ (kMDItemDurationSeconds) ]]; then
TIME_IN_SECONDS=$(echo $i | grep -oEi '[0-9]{1,}.*')
fi
if [[ $i =~ (kMDItemPixelHeight) ]]; then
HEIGHT=$(echo $i | grep -oEi '[0-9]{1,}.*')
fi
if [[ $i =~ (kMDItemPixelWidth) ]]; then
WIDTH=$(echo $i | grep -oEi '[0-9]{1,}.*')
fi
done
DURATION=$(utils::secondsToHMS $DURATION)
DIMENSIONS=$(echo $WIDTH × $HEIGHT)
fi
if [ $CMD_EXISTS = "false" ] && [ $FFPROBE_EXISTS = "false" ]
then
echo "ffprobe & mdls commands not available."
return 1
fi
if [[ -z $2 || -z $3 ]]
then
echo "Duration:" $DURATION "("$(utils::secondsToHMS $TIME_IN_SECONDS)")"
echo "Dimensions" $DIMENSIONS
return 0;
fi
printf -v "$2" '%s' "$TIME_IN_SECONDS"
printf -v "$3" '%s' "$DIMENSIONS"
}
: '
@func Checks is file is a valid video file
@param string $1 FILE
@return void
'
# https://askubuntu.com/questions/844711/how-can-i-find-all-video-files-on-my-system
function utils::file-is-video() {
FILE=$1
FILE_EXTENSION=$(echo $FILE | grep -iEo "(\w+)$")
branches=("mkv webm flv vob ogg ogv drc gifv mng avi mov qt wmv yuv rm rmvb asf amv mp4 m4v mp svi 3gp flv f4v mpeg mpg")
[[ " ${branches[@]} " =~ " ${FILE_EXTENSION} " ]] && echo 1 || echo 0;
}
: '
@ref https://stackoverflow.com/questions/63972113/big-sur-clang-invalid-version-error-due-to-macosx-deployment-target
@func FORCE xcode update
@return void
'
function utils::update-xcode() {
# softwareupdate --all --install --force
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
}
: '
@ref https://stackoverflow.com/questions/394230/how-to-detect-the-os-from-a-bash-script
@func POSIX compatible OS detection
@return void
'
function utils::detect-os() {
OS="`uname`"
case $OS in
"Linux")
OS="Linux"
#alias ls='ls --color=auto'
;;
"FreeBSD")
OS="FreeBSD"
#alias ls='ls -G'
;;
"WindowsNT")
OS='Windows'
;;
"Darwin")
OS='Mac'
;;
"SunOS")
OS="Solaris"
;;
"AIX") ;;
*) ;;
esac
export OS
}
: '
@ref https://stackoverflow.com/questions/592620/how-can-i-check-if-a-program-exists-from-a-bash-script
@func POSIX compatible command lookup
@param string $1 COMMAND Command to look for
@return void
'
function util::command-exists() {
local COMMAND=$1
[ -z $COMMAND ] && { echo "Please enter a command."; return 1 ; }
[ ! $(command -v $COMMAND) ] && { echo "false"; return 0; } || echo "true"; return 1;
}
utils::detect-os
#!/usr/bin/env bash
#Target OS: [Mac, Linux, Unix-like]
# https://stackoverflow.com/questions/12199631/convert-seconds-to-hours-minutes-seconds
# https://stackoverflow.com/questions/32657065/how-to-document-shell-function
# https://stackoverflow.com/questions/12199631/convert-seconds-to-hours-minutes-seconds/66928998#66928998
: '
@func POSIX compatible Time conversion
@param $1 int|float|string Time in seconds
@returns void
'
function utils::secondsToHMS() {
SECONDS=$1
SECONDS_ROUND_UP=$(printf "%.${2:-0}f" "$1") # Round up a float num: 123.5 = 124
SECONDS_IN_A_DAY=86399 # 23:59:59
[ $SECONDS -gt $SECONDS_IN_A_DAY ] && echo "$1 exceeds 86,399s limit (23:59:59)" && return 0
case $OS in
"Mac")
echo $(date -ju -f "%s" $SECONDS_ROUND_UP "+%H:%M:%S")
;;
"Linux")
echo $(date -d@$SECONDS_ROUND_UP -u +%H:%M:%S)
;;
esac
return 0
}
#!/usr/bin/env bash
#Target OS: Only Mac OSX >= 10.15.3
function utils::join-pdf() {
DAY=$(date +%d)
PERIOD=$([[ $DAY -ge 16 ]] && echo 'P2' || echo 'P1')
TAG=$(date +%B_$PERIOD\_%Y)
FILE="Nerfos_Locos_Team_TimeSheets_DealerSocket_$TAG.pdf"
/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/Resources/join.py -o $FILE *pdf
}
function utils::display-sleep-now() {
pmset displaysleepnow
}
function utils::kill-processes-by-port {
if [ -z $1 ]
then
echo 'error: No Port'
return 0;
fi
re='^[0-9]+$'
if ! [[ $1 =~ $re ]] ; then
echo "error: Not a number" >&2; #exit 1
return 0;
fi
lsof -i :$1 | grep -iEo '^\w+\s{1,}.([0-9]{1,})' | grep -oEi '[0-9]{1,}' | \
while read i
do
kill -9 $i && echo 'Killed ID: ' $i
done
}
# @deprecated
function utils::kill-node-on-port-3000() {
#lsof -i :3000 | grep -iEo '^node+\s{1,}.([0-9]{1,})' | grep -oEi '[0-9]{1,}' | \
lsof -i :3000 | grep -iEo '^\w+\s{1,}.([0-9]{1,})' | grep -oEi '[0-9]{1,}' | \
while read i
do
kill -9 $i && echo 'Killed ID: ' $i
done
}
function utils::pdf-report() {
DAY=$(date +%d)
PERIOD=$([[ $DAY -ge 16 ]] && echo 'P2' || echo 'P1')
TAG=$(date +%B_$PERIOD\_%Y)
FILE="Nerfos_Locos_Team_TimeSheets_DealerSocket_$TAG.pdf"
/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/Resources/join.py -o $FILE *pdf
}
function utils::jc() {
if [ -z $1 ]
then
echo 'No File!'
return 0;
fi
echo $1 | grep -iEo '.*\.' | \
while read i
do
npx jest $i'spec.js' --collectCoverageFrom='["'$1'"]' --coverage
done
}
function utils::human_print () {
B=$1
bytes=1024
kilobytes=$((1024*1024))
megabytes=$((1024*1024*1024))
gigabytes=$((1024*1024*1024*1024))
terabytes=$((1024*1024*1024*1024*1024))
[ $B -lt $bytes ] && echo $(echo "scale=4; $B" | bc -l) "bytes" && return 0
[ $B -lt $kilobytes ] && echo $(echo "scale=2; $B/1000" | bc -l) "KB" && return 0
[ $B -lt $megabytes ] && echo $(echo "scale=2; $B/(1000*1000)" | bc -l) "MB" && return 0
[ $B -lt $gigabytes ] && echo $(echo "scale=2; $B/(1000*1000*1000)" | bc -l) "GB" && return 0
[ $B -lt $terabytes ] && echo $(echo "scale=2; $B/(1000*1000*1000*1000)" | bc -l) "TB" && return 0
}
bindkey -v
# syntax on
set number
# colorscheme torte
# set statusline=%f\ %l,%c
const [
bin,
file,
id,
dateAdded,
filename,
original,
extension,
duration,
dimensions,
size,
sizehuman,
checksum,
files,
] = process.argv;
const obj = {
id: parseInt(id), // 426,
dateAdded, // "09/15/2022 00:00:00",
data: {
filename: !files ? filename : files.split(','), // "426.mp4.gpg",
original, // "Blacked - Zoe Bloom - Open Relationship BBC.mp4",
extension, // "mp4",
url: "", // "https://www.blacked.com/videos/open-relationship-bbc",
title: "", // "Open Relationship BBC",
notes: [
"Duration: " + duration, // "⏰🕰️",
"Dimensions: " + dimensions, // "Dimensions: 1920 x 1080",
],
size: [
`${size} bytes (${sizehuman} on disk)`, //"271,549,243 bytes (271.54 MB on disk)"
],
},
isDraft: true, // false,
encrypted: true, // true,
checksum, //"6a48bcfed38f430671120ebdd93cf0cabc3fb31e256a9d69e0686b5a81b8b0b1b9328b19d9d2766dd8071affd1bd5ef1409391b83102015b9bd489019fc68fc3",
cloudService: "Telegram",
};
console.log(JSON.stringify(obj, null, 2));
import sys
import json
from tokenize import String
def output():
file, id, dateAdded, filename, original, extension, duration, dimensions, size, sizehuman, checksum, files = sys.argv
obj = {
"id": id,
"dateAdded": dateAdded,
"data": {
"filename": filename if not files else file.split(','),
"original": original,
"extension": extension,
"url": "",
"title": "",
"notes": [
"Duration: " + duration,
"Dimensions: " + dimensions
],
"size": [
'%s bytes (%s on disk)' % (size, sizehuman)
]
},
"isDraft": True,
"encrypted": True,
"checksum": checksum,
"cloudService": "Telegram"
}
# @todo sort JSON object keys: obj.sort(key=lambda x: x["brand"])
print(json.dumps(obj, indent=2, sort_keys=False, ensure_ascii=False))
return True
output()
require 'json'
file, id, dateAdded, filename, original, extension, duration, dimensions, size, sizehuman, checksum, files = ARGV
ruby = {
id: id,
dateAdded: dateAdded,
data: {
filename: !files ? filename : files.split(','),
original: original,
extension: extension,
url: "",
title: "",
notes: [
"Duration: " + duration,
"Dimensions: " + dimensions,
],
size: [
"#{size} bytes (#{sizehuman} on disk)",
],
},
isDraft: true,
encrypted: true,
checksum: checksum,
cloudService: "Telegram",
}
json = JSON.pretty_generate(ruby)
print json
#!/bin/zsh
function pomodoro() {
echo -n "Set Pomodoro minutes: "
read MINUTES
CONTROL=0
MINUTES=$MINUTES*60
while ((CONTROL <= MINUTES))
do
TIME=$(utils::secondsToHMS $CONTROL)
echo -n $TIME "\r"
((CONTROL++))
sleep 1
done
S=0
while ((S < 15))
do
osascript -e beep
((S++))
done
echo "Pomodoro Done: " $(utils::secondsToHMS $MINUTES)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment