mirror of
https://github.com/Lissy93/dotfiles.git
synced 2024-11-21 23:13:09 +01:00
work in progress
This commit is contained in:
parent
6238ae207e
commit
15225ea137
16
Dockerfile
16
Dockerfile
@ -37,6 +37,8 @@ RUN \
|
||||
neovim \
|
||||
git git-doc \
|
||||
zsh \
|
||||
vim \
|
||||
tmux \
|
||||
docker \
|
||||
docker-compose
|
||||
|
||||
@ -46,16 +48,18 @@ RUN \
|
||||
addgroup ${user} docker
|
||||
|
||||
COPY ./ /home/${user}/.userspace/
|
||||
|
||||
RUN \
|
||||
git clone --recursive https://${vcsprovider}/${vcsowner}/${dotfiles} /home/${user}/.dotfiles && \
|
||||
chown -R ${user}:${group} /home/${user}/.dotfiles && \
|
||||
chown -R ${user}:${group} /home/${user}/.userspace
|
||||
# For advanced configuration where you would do ssh-agent and gpg-agent passthrough
|
||||
# cd /home/${user}/.userspace && \
|
||||
# git remote set-url origin git@${vcsprovider}:${vcsowner}/${userspace} && \
|
||||
# cd /home/${user}/.dotfiles && \
|
||||
# git remote set-url origin git@${vcsprovider}:${vcsowner}/${dotfiles}
|
||||
|
||||
ENV HISTFILE=/config/.history
|
||||
RUN chmod u+x /home/${user}/.dotfiles/install.sh
|
||||
|
||||
USER ${user}
|
||||
|
||||
RUN cd $HOME/.dotfiles && ./install.sh
|
||||
|
||||
ENV HISTFILE=/home/${user}/.cache/.zsh_history
|
||||
|
||||
CMD []
|
||||
|
71
utils/death-to-dotfiles.sh
Normal file
71
utils/death-to-dotfiles.sh
Normal file
@ -0,0 +1,71 @@
|
||||
#!/bin/sh -
|
||||
# Quick utility to aid in keeping clutter down in the $HOME directory
|
||||
# Lists statistics about number of files, auto-cleans certain files,
|
||||
# and prompts user wheather they'd like to each remaining dotfile in turn
|
||||
|
||||
set -u
|
||||
|
||||
readonly HOME=${HOME:-$(getent passwd "$(id -un)" | cut -d : -f 6)}
|
||||
|
||||
inlist() {
|
||||
for e in $2; do
|
||||
case "$1" in ($e)
|
||||
return
|
||||
esac
|
||||
done
|
||||
false
|
||||
}
|
||||
|
||||
die() {
|
||||
retval=$(($1)); shift
|
||||
{ printf "$@"; echo; } >&2
|
||||
exit $retval
|
||||
}
|
||||
|
||||
prompt_delete() {
|
||||
printf '\nDelete %s? [Y/n] ' "$1"
|
||||
read -r a
|
||||
test -t 0 || printf '\033[1;32m%s\033[0m\n' "$a"
|
||||
case "$a" in
|
||||
(''|Y*|y*) rm -rv "$1" ;;
|
||||
(N*|n*) ;;
|
||||
(*) prompt_delete "$1" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# gather and show statistics:
|
||||
n_nondots=$(find "$HOME" -maxdepth 1 -mindepth 1 -name '[^.]*' | wc -l)
|
||||
n_dots=$(find "$HOME" -maxdepth 1 -mindepth 1 -name '.*' | wc -l)
|
||||
n_all=$((n_nondots + n_dots))
|
||||
cat <<- EOF
|
||||
total: $n_all
|
||||
normal files: $n_nondots
|
||||
$(printf '\033[1m')dotfiles: $n_dots$(printf '\033[0m')
|
||||
|
||||
EOF
|
||||
|
||||
# List dotfiles:
|
||||
cd "$HOME" || die 1 'Could not cd into home directory (%s)' "$HOME"
|
||||
if ! ls -1d --color=auto .[!.]*; then
|
||||
die 1 'Could not list files in home directory (%s)' "$HOME"
|
||||
fi
|
||||
|
||||
# Automatic decisions for specific files/directories:
|
||||
keeplist='.anthy .local .pam_environment .pki .ssh'
|
||||
deletelist='.ansible .ansible_galaxy .mozilla .w3m .*_history'
|
||||
|
||||
# delete:
|
||||
for d in .*; do
|
||||
case "$d" in (.|..) continue ;; esac
|
||||
if inlist "$d" "$keeplist"; then
|
||||
# Do not delete this file
|
||||
continue
|
||||
elif inlist "$d" "$deletelist"; then
|
||||
# Delete this file without asking
|
||||
echo y | prompt_delete "$d"
|
||||
continue
|
||||
else
|
||||
# Ask the user if should delete or not
|
||||
prompt_delete "$d"
|
||||
fi
|
||||
done
|
20
utils/print-color-map.sh
Normal file
20
utils/print-color-map.sh
Normal file
@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Prints each foreground and background color using standard 16-bit pallete
|
||||
# Based on: https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
|
||||
|
||||
T='Hi!' # The test text
|
||||
|
||||
echo -e "\n \t\t40m\t 41m\t 42m\t 43m\t 44m\t 45m\t 46m\t 47m";
|
||||
|
||||
for FGs in ' m' ' 1m' ' 30m' '1;30m' ' 31m' '1;31m' ' 32m' \
|
||||
'1;32m' ' 33m' '1;33m' ' 34m' '1;34m' ' 35m' '1;35m' \
|
||||
' 36m' '1;36m' ' 37m' '1;37m';
|
||||
do FG=${FGs// /}
|
||||
echo -en " $FGs \033[$FG $T "
|
||||
for BG in 40m 41m 42m 43m 44m 45m 46m 47m;
|
||||
do echo -en "$EINS \033[$FG\033[$BG $T \033[0m";
|
||||
done
|
||||
echo;
|
||||
done
|
||||
echo
|
200
utils/qr-code.sh
Normal file
200
utils/qr-code.sh
Normal file
@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env bash
|
||||
# Based on similar script by Linyos Torovoltos and Alex Epstein
|
||||
|
||||
multiline="0" # flag that indicates multiline option
|
||||
fileoutput="0" # flag indicating the -f option
|
||||
|
||||
|
||||
# Determine which HTTP GET tool installed
|
||||
getConfiguredClient () {
|
||||
if command -v curl &>/dev/null; then
|
||||
configuredClient="curl"
|
||||
elif command -v wget &>/dev/null; then
|
||||
configuredClient="wget"
|
||||
elif command -v http &>/dev/null; then
|
||||
configuredClient="httpie"
|
||||
elif command -v fetch &>/dev/null; then
|
||||
configuredClient="fetch"
|
||||
else
|
||||
echo "Error: This tool requires either curl, wget, httpie or fetch to be installed." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Call appropriate http get method
|
||||
httpGet() {
|
||||
case "$configuredClient" in
|
||||
curl) curl -A curl -s "$@" ;;
|
||||
wget) wget -qO- "$@" ;;
|
||||
httpie) http -b GET "$@" ;;
|
||||
fetch) fetch -q "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Get installed version of Python / show error if none
|
||||
getConfiguredPython() {
|
||||
if command -v python3 &>/dev/null; then
|
||||
configuredPython="python3"
|
||||
elif command -v python2 &>/dev/null; then
|
||||
configuredPython="python2"
|
||||
elif command -v python &>/dev/null; then
|
||||
configuredPython="python"
|
||||
else
|
||||
echo "Error: This tool requires python to be installed."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ $(uname) != "Darwin" ]]; then
|
||||
python() {
|
||||
case "$configuredPython" in
|
||||
python3) python3 "$@" ;;
|
||||
python2) python2 "$@" ;;
|
||||
python) python "$@" ;;
|
||||
esac
|
||||
}
|
||||
fi
|
||||
|
||||
# Encode input, and call to qrenco.de to get response
|
||||
makeqr() {
|
||||
input=$(echo "$input" | sed s/" "/%20/g ) ## replace all spaces in the sentence with HTML-encoded space %20
|
||||
httpGet qrenco.de/"$input" ## get a response for the qrcode
|
||||
}
|
||||
|
||||
# Redirects returned QR impage into a png file
|
||||
makeQRFile() {
|
||||
input=$(echo "$input" | sed -e s/" "/%20/g -e s/'\\n'/%0A/g ) ##same as in the makeqr function
|
||||
addFileExt
|
||||
httpGet "api.qrserver.com/v1/create-qr-code/?size=150x150&data=$input" > "$fileName"
|
||||
}
|
||||
|
||||
# If filename doesn't already have .png extension, append it
|
||||
addFileExt() {
|
||||
if ! echo "$fileName" | grep -E -q ".*\.png$|.*\.PNG$"
|
||||
then
|
||||
fileName="$fileName.png"
|
||||
fi
|
||||
}
|
||||
|
||||
makeMultiLineQr() {
|
||||
if [[ ${configuredClient} != "curl" ]]; then ## prevent usage without curl it is unreliable
|
||||
echo "Multiline currently only supports curl!"
|
||||
return 1
|
||||
else
|
||||
input=$(echo "$input" | sed -e s/" "/%20/g -e s/'\\n'/%0A/g ) ##same as in the makeqr function
|
||||
printf "%s" "$input" | curl -F-=\<- qrenco.de
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to get the json response from POST request
|
||||
decodeQR() {
|
||||
local qrFile="$1"
|
||||
if ! echo "$fileName" | grep -E -q ".*\.png$|.*\.PNG$|.*\.gif$|.*\.jpg$|.*\.jpeg$|.*\.GIF$|.*\.JPG$|.*\.JPEG$"
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# only uses curl
|
||||
# Cannot use wget because it does not support multipart/form-data (as per the man page)]
|
||||
|
||||
case "$configuredClient" in
|
||||
curl) JSONresponse=$(curl -s -F "file=@$qrFile" http://api.qrserver.com/v1/read-qr-code/) || exit 1;;
|
||||
wget) echo "Error:-Not supported with wget" >&2 && exit 1;;
|
||||
httpie) JSONresponse=$(http -b --form POST http://api.qrserver.com/v1/read-qr-code/ file@"$qrFile") || exit 1;;
|
||||
fetch) echo "Error:-Not supported with wget" >&2 && exit 1;;
|
||||
esac
|
||||
|
||||
error="$(echo "$JSONresponse" | python -c "from __future__ import print_function; import sys, json; print(json.load(sys.stdin)[0]['symbol'][0]['error'])")"
|
||||
|
||||
if [[ "$error" == "None" ]]
|
||||
then
|
||||
data="$(echo "$JSONresponse" | python -c "from __future__ import print_function; import sys, json; print(json.load(sys.stdin)[0]['symbol'][0]['data'])")"
|
||||
else
|
||||
echo "Error:-$error" >&2 && exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
checkInternet()
|
||||
{
|
||||
httpGet github.com > /dev/null 2>&1 || { echo "Error: no active internet connection" >&2; return 1; } # query github with a get request
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Qrify
|
||||
Description: Converts strings or URLs into a QR code.
|
||||
Usage: qrify [stringtoturnintoqrcode]
|
||||
-m Enable multiline support (feature not working yet)
|
||||
-h Show the help
|
||||
-v Get the tool version
|
||||
-f Store the QR code as a PNG file
|
||||
-d Decode the QR code from a PNG/GIF/JP(E)G file
|
||||
Examples:
|
||||
qrify this is a test string
|
||||
qrify -m two\\\\nlines
|
||||
qrify github.com (no http:// or https://)
|
||||
qrify -f fileoutputName google.com
|
||||
qrify -d fileName.png
|
||||
|
||||
[31mPlease pay attention:[0m
|
||||
This script needs access to an external API.
|
||||
[5m[1mDo not use it to encode sensitive data.[0m
|
||||
EOF
|
||||
}
|
||||
|
||||
getConfiguredClient || exit 1
|
||||
|
||||
|
||||
while getopts "d:f:m:hvu*:" option
|
||||
do
|
||||
case "${option}" in
|
||||
h) usage && exit 0 ;;
|
||||
m) multiline="1" && echo "Error this is not a supported feature yet" && exit 1 ;;
|
||||
f)
|
||||
fileName=$OPTARG
|
||||
#file name is the first argument of the option -f
|
||||
fileoutput="1";;
|
||||
d)
|
||||
fileName=$OPTARG
|
||||
decode="1";;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# == "0" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
elif [[ $# == "1" ]];then
|
||||
if [[ $1 == "help" || $1 == ":help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
else
|
||||
getConfiguredPython || exit 1
|
||||
checkInternet || exit 1
|
||||
input=$(printf '%s ' "$@")
|
||||
makeqr || exit 1
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
getConfiguredPython || exit 1
|
||||
checkInternet || exit 1
|
||||
if [[ $fileoutput == "1" ]]
|
||||
then
|
||||
input=$(printf '%s ' "${@:3}") # first arg is -f, second is the file name, third onwards is the rest of the argument
|
||||
# will have to be changed when implementing multiline QR code
|
||||
makeQRFile || exit 1
|
||||
exit 0
|
||||
elif [[ $decode == "1" ]]
|
||||
then
|
||||
( decodeQR "$fileName" && echo "$data" ) || exit 1
|
||||
exit 0
|
||||
elif [[ $multiline == "0" ]]; then
|
||||
input=$(printf '%s ' "$@")
|
||||
makeqr || exit 1
|
||||
exit 0
|
||||
else
|
||||
input=$(printf '%s ' "${@:2}")
|
||||
makeMultiLineQr || exit 1 ## if multiline that means a flag existed so start from the second argument
|
||||
exit 0
|
||||
fi
|
||||
fi
|
315
utils/test.sh
Normal file
315
utils/test.sh
Normal file
@ -0,0 +1,315 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPTNAME="$0"
|
||||
VERSION="0.0.1"
|
||||
SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
|
||||
|
||||
source "$SCRIPTS_DIR/util/base.sh"
|
||||
source "$SCRIPTS_DIR/util/logging.sh"
|
||||
source "$SCRIPTS_DIR/util/config.sh"
|
||||
source "$SCRIPTS_DIR/util/api.sh"
|
||||
source "$SCRIPTS_DIR/util/dns.sh"
|
||||
|
||||
REQUIRES_FUNCS \
|
||||
debug info warn error log_start \
|
||||
config_load_all config_validate \
|
||||
merge_arrays repeated
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
HELP_TEXT="
|
||||
$SCRIPTNAME v$VERSION
|
||||
|
||||
Helper script to update a DNS record on multiple providers.
|
||||
|
||||
Usage:
|
||||
$SCRIPTNAME --domain=domain.example.com [--get|--set=value] [...options]
|
||||
|
||||
Options:
|
||||
[domain] The DNS domain you want to get or set (required)
|
||||
|
||||
--domain=example.com Same as passing [domain] directly as an argument
|
||||
-t=|--type=A The DNS record type, e.g. A, CNAME, etc. (A default)
|
||||
|
||||
-g|--get Get the record value (the default)
|
||||
-s=|--set=value Set the record value, e.g. 123.235.324.234 or the
|
||||
special value 'pubip' to use current public ip
|
||||
|
||||
|
||||
-l=|--ttl=n Set the record TTL to n seconds (overrides api default)
|
||||
-p=|--proxied Set the record to be proxied through CDN (Cloudflare only)
|
||||
-a=|--api=cf,do List of DNS providers to use, e.g. all (default) or cf,do
|
||||
-r=|--refresh=n Run continusouly every n seconds in a loop
|
||||
-w=|--timeout=n Wait n seconds before aborting and retrying
|
||||
|
||||
-c=|--config=file Path to a dotenv-formatted config file to load
|
||||
-e=|--config-prefix=X Load config vars with prefix X e.g. X_VERBOSE=1
|
||||
|
||||
-h|--help Show this help message
|
||||
-v|--verbose Show more verbose output
|
||||
-q|--quiet Supress all output except for errors and warnings
|
||||
--color Force showing of colors in the stderr output
|
||||
--nocolor Force hiding of colors in the stderr output
|
||||
--notimestamps Force hiding of timestamps in stderr output
|
||||
--nologlevels Force hiding of log levels in stderr output
|
||||
|
||||
Config: (passed via --config=file or environment variables)
|
||||
DOMAIN=a.example.com Same as --domain option
|
||||
|
||||
|
||||
CF_API_KEY=12345 Clouflare API token: https://dash.cloudflare.com/<account_id>/profile/api-tokens
|
||||
DO_API_KEY=12345 DigitalOcean API token: https://cloud.digitalocean.com/account/api/tokens
|
||||
|
||||
VEBOSE=1 Show debug output [0]/1
|
||||
QUIET=0 Hide info output: [0]/1
|
||||
COLOR=1 Colorize stderr output: [1]/0
|
||||
TIMEOUT=15 Seconds to wait before aborting and retrying
|
||||
|
||||
Examples:
|
||||
$SCRIPTNAME abc.example.com
|
||||
$SCRIPTNAME abc.example.com --get --refresh=30
|
||||
$SCRIPTNAME abc.example.com --type=A --set=pubip --ttl=300 --api=digitalocean --config=~/.digitalocean.env
|
||||
$SCRIPTNAME --domain=abc.example.com --type=A --set=1.2.3.4 --api=digitalocean,cloudflare --refresh=30 --config=./secrets.env
|
||||
|
||||
|
||||
"
|
||||
|
||||
### Default Config
|
||||
API_KEY_PLACEHOLDER="set-this-value-in-your-config-file"
|
||||
ALLOWED_APIS='cf,do'
|
||||
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -A DNS_CLI_ARGS=(
|
||||
# Flag Arguments
|
||||
[GET]='-g|--get'
|
||||
[PROXIED]='-p|--proxied'
|
||||
|
||||
# Named Arguments
|
||||
[DOMAIN]='-d|--domain|-d=*|--domain=*'
|
||||
[TYPE]='-t|--type|-t=*|--type=*'
|
||||
[SET]='-s|--set|-s=*|--set=*'
|
||||
[TTL]='-l|-l=*|--ttl|--ttl=*'
|
||||
[API]='-a|-a=*|--api|--api=*'
|
||||
|
||||
# Positional Arguments
|
||||
# [DOMAIN]='*'
|
||||
# [TYPE]='*'
|
||||
# [SET]='*'
|
||||
)
|
||||
merge_arrays CLI_ARGS BASE_CLI_ARGS DNS_CLI_ARGS
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
declare -A DNS_CONFIG_DEFAULTS=(
|
||||
[DOMAIN]=''
|
||||
[TYPE]='A'
|
||||
[GET]=''
|
||||
[SET]=''
|
||||
|
||||
[API]='all'
|
||||
[TTL]='default'
|
||||
[PROXIED]='false'
|
||||
|
||||
[CF_API_KEY]="$API_KEY_PLACEHOLDER"
|
||||
[CF_DEFAULT_TTL]=1
|
||||
|
||||
[DO_API_KEY]="$API_KEY_PLACEHOLDER"
|
||||
[DO_DEFAULT_TTL]=300
|
||||
)
|
||||
merge_arrays CONFIG_DEFAULTS BASE_CONFIG_DEFAULTS DNS_CONFIG_DEFAULTS
|
||||
declare -A CONFIG
|
||||
|
||||
# shellcheck disable=SC2016 disable=SC2034
|
||||
declare -A CONFIG_VALIDATORS=(
|
||||
[DOMAIN]='[[ "${CONFIG[DOMAIN]}" ]]'
|
||||
[TYPE]='[[ "${CONFIG[TYPE]}" ]]'
|
||||
[SET]='validate_set_config'
|
||||
[API]='validate_api_config'
|
||||
)
|
||||
merge_arrays CONFIG_VALIDATORS BASE_CONFIG_VALIDATORS DNS_CONFIG_VALIDATORS
|
||||
|
||||
|
||||
function validate_set_config {
|
||||
if [[ ! "${CONFIG[GET]}" && ! "${CONFIG[SET]}" ]]; then
|
||||
fatal "Missing --get or --set=value argument (pass --help for usage and examples)."
|
||||
fi
|
||||
|
||||
if [[ "${CONFIG[SET]}" && "${CONFIG[TYPE]}" == 'A' ]]; then
|
||||
if ! [[ "${CONFIG[SET]}" == 'pubip' ]] || echo "${CONFIG[SET]}" | grep -q "$IPV4_REGEX"; then
|
||||
error "Invalid value --set=${CONFIG[SET]} must be pubip or an ip address"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function validate_api_config {
|
||||
local APIS="${CONFIG[API]}"
|
||||
|
||||
for API in ${APIS//,/ }; do
|
||||
case "$API" in
|
||||
'digitalocean'|'do')
|
||||
[[ "${CONFIG[DO_API_KEY]}" == "$API_KEY_PLACEHOLDER" ]] && {
|
||||
error "You must pass your DO_API_KEY via environment variable or --config=file.env (pass --help for more info)."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
'cloudflare'|'cf')
|
||||
[[ "${CONFIG[CF_API_KEY]}" == "$API_KEY_PLACEHOLDER" ]] && {
|
||||
error "You must pass your CF_API_KEY via environment variable or --config=file.env (pass --help for more info)."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
'all')
|
||||
CONFIG[API]="$ALLOWED_APIS"
|
||||
;;
|
||||
*)
|
||||
error "Unrecognized API type '$API'. (must be one or more of: $ALLOWED_APIS)"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
### Main Functions
|
||||
|
||||
function get_record {
|
||||
local API="$1" DOMAIN="$2" TYPE="$3"
|
||||
|
||||
|
||||
if [[ "$API" == "do" ]]; then
|
||||
. ./lib/digitalocean.sh
|
||||
elif [[ "$API" == "cf" ]]; then
|
||||
. ./lib/cloudflare.sh
|
||||
fi
|
||||
|
||||
dns_get_record "$DOMAIN" "$TYPE"
|
||||
}
|
||||
|
||||
function update_record {
|
||||
local API="$1" DOMAIN="$2" TYPE="$3" VALUE="$4" TTL="$5" PROXIED="$6"
|
||||
|
||||
local VALUE_BEFORE VALUE_AFTER STATUS
|
||||
|
||||
[[ "$VALUE" == "pubip" ]] && VALUE="$(get_public_ip)" # replace pubip with actual ip
|
||||
|
||||
if [[ "$TYPE" == "TXT" ]]; then
|
||||
VALUE="$(echo "$VALUE" | perl -pe 's/\n/\\\n/gm')"
|
||||
fi
|
||||
|
||||
if [[ "$API" == "do" ]]; then
|
||||
. ./lib/digitalocean.sh
|
||||
elif [[ "$API" == "cf" ]]; then
|
||||
. ./lib/cloudflare.sh
|
||||
fi
|
||||
|
||||
VALUE_BEFORE="$(
|
||||
dns_get_record \
|
||||
"$DOMAIN" \
|
||||
"$TYPE"
|
||||
)" && STATUS="$?" || STATUS="$?"
|
||||
|
||||
if [[ "$STATUS" == "8" ]]; then
|
||||
warn "$API/$DOMAIN/$TYPE=$VALUE creating new record..."
|
||||
VALUE_AFTER="$(
|
||||
dns_create_record \
|
||||
"$DOMAIN" \
|
||||
"$TYPE" \
|
||||
"$VALUE" \
|
||||
"$TTL" \
|
||||
"$PROXIED"
|
||||
)"
|
||||
elif ((STATUS>0)); then
|
||||
fatal --status=$STATUS "dns_get_record return an invalid exit status $STATUS"
|
||||
elif [[ "$VALUE_BEFORE" == "$VALUE" ]]; then
|
||||
info "$API/$DOMAIN/$TYPE=$VALUE_BEFORE is up-to-date."
|
||||
return 0
|
||||
else
|
||||
info "$API/$DOMAIN/$TYPE=$VALUE_BEFORE updating to $VALUE..."
|
||||
|
||||
VALUE_AFTER="$(
|
||||
dns_set_record \
|
||||
"$DOMAIN" \
|
||||
"$TYPE" \
|
||||
"$VALUE" \
|
||||
"$TTL" \
|
||||
"$PROXIED"
|
||||
)"
|
||||
fi
|
||||
|
||||
if ! [[ "$VALUE_AFTER" == "$VALUE" || "$VALUE_AFTER" == "${VALUE}." ]]; then
|
||||
error "$API/$DOMAIN/$TYPE=$VALUE update failed (got ${VALUE_AFTER:-API error})."
|
||||
return 1
|
||||
else
|
||||
info "$API/$DOMAIN/$TYPE=$VALUE update succeeded."
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
function log_start_dns {
|
||||
config_assert INTERVAL API DOMAIN TYPE
|
||||
|
||||
local INTERVAL_STR
|
||||
|
||||
# Begin check/update process
|
||||
((CONFIG[INTERVAL]>0)) && INTERVAL_STR="every ${CONFIG[INTERVAL]}s" || INTERVAL_STR="once"
|
||||
if [[ "${CONFIG[SET]}" ]]; then
|
||||
info "Starting: SET ${CONFIG[API]}/${CONFIG[DOMAIN]}/${CONFIG[TYPE]}=${CONFIG[SET]} $INTERVAL_STR..."
|
||||
else
|
||||
info "Starting: GET ${CONFIG[API]}/${CONFIG[DOMAIN]}/${CONFIG[TYPE]} $INTERVAL_STR..."
|
||||
fi
|
||||
}
|
||||
|
||||
function runloop {
|
||||
local APIS="${CONFIG[API]}"
|
||||
|
||||
GET="${CONFIG[GET]}"
|
||||
SET="${CONFIG[SET]}"
|
||||
|
||||
for API in ${APIS//,/ }; do
|
||||
if ((GET==1)); then
|
||||
timed "${CONFIG[TIMEOUT]}" \
|
||||
get_record \
|
||||
"$API" \
|
||||
"${CONFIG[DOMAIN]}" \
|
||||
"${CONFIG[TYPE]}"
|
||||
return $?
|
||||
elif [[ "$SET" ]]; then
|
||||
timed "${CONFIG[TIMEOUT]}" \
|
||||
update_record \
|
||||
"$API" \
|
||||
"${CONFIG[DOMAIN]}" \
|
||||
"${CONFIG[TYPE]}" \
|
||||
"${CONFIG[SET]}" \
|
||||
"${CONFIG[TTL]}" \
|
||||
"${CONFIG[PROXIED]}"
|
||||
return $?
|
||||
else
|
||||
fatal 'You must pass either --get or --set=value'
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
function main {
|
||||
# Load config from file, env variables, and kwargs
|
||||
config_load_all CONFIG_DEFAULTS CLI_ARGS "$@"
|
||||
config_validate CONFIG_VALIDATORS
|
||||
log_start_dns
|
||||
|
||||
repeated "${CONFIG[INTERVAL]}" runloop
|
||||
}
|
||||
|
||||
main "$@"
|
||||
#wait "$!" && STATUS=$? || STATUS=$?
|
||||
#jobs -p >/dev/null 2>&1
|
||||
#jobs -p | xargs 'kill -9 --' >/dev/null 2>&1
|
||||
|
||||
#if ((STATUS>125)); then
|
||||
# codes >= 125 are used by the shell only and cannot be returned from scripts
|
||||
# https://www.tldp.org/LDP/abs/html/exitcodes.html
|
||||
# exit $((STATUS-100))
|
||||
#else
|
||||
# exit $STATUS
|
||||
#fi
|
150
utils/weather.sh
Normal file
150
utils/weather.sh
Normal file
@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env bash
|
||||
# Author: Alexander Epstein https://github.com/alexanderepstein
|
||||
|
||||
currentVersion="1.23.0" #This version variable should not have a v but should contain all other characters ex Github release tag is v1.2.4 currentVersion is 1.2.4
|
||||
LANG="${LANG:-en}"
|
||||
locale=$(echo "$LANG" | cut -c1-2)
|
||||
unset configuredClient
|
||||
if [[ $(echo "$locale" | grep -Eo "[a-z A-Z]*" | wc -c) != 3 ]]; then locale="en"; fi
|
||||
|
||||
## This function determines which http get tool the system has installed and returns an error if there isnt one
|
||||
getConfiguredClient()
|
||||
{
|
||||
if command -v curl &>/dev/null; then
|
||||
configuredClient="curl"
|
||||
elif command -v wget &>/dev/null; then
|
||||
configuredClient="wget"
|
||||
elif command -v http &>/dev/null; then
|
||||
configuredClient="httpie"
|
||||
elif command -v fetch &>/dev/null; then
|
||||
configuredClient="fetch"
|
||||
else
|
||||
echo "Error: This tool requires either curl, wget, httpie or fetch to be installed\." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
## Allows to call the users configured client without if statements everywhere
|
||||
httpGet()
|
||||
{
|
||||
case "$configuredClient" in
|
||||
curl) curl -A curl -s "$@" ;;
|
||||
wget) wget -qO- "$@" ;;
|
||||
httpie) http -b GET "$@" ;;
|
||||
fetch) fetch -q "$@" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
getIPWeather()
|
||||
{
|
||||
country=$(httpGet ipinfo.io/country) > /dev/null ## grab the country
|
||||
if [[ $country == "US" ]]; then ## if were in the us id rather not use longitude and latitude so the output is nicer
|
||||
city=$(httpGet ipinfo.io/city) > /dev/null
|
||||
region=$(httpGet ipinfo.io/region) > /dev/null
|
||||
if [[ $(echo "$region" | wc -w) == 2 ]];then
|
||||
region=$(echo "$region" | grep -Eo "[A-Z]*" | tr -d "[:space:]")
|
||||
fi
|
||||
httpGet $locale.wttr.in/"$city","$region""$1"
|
||||
else ## otherwise we are going to use longitude and latitude
|
||||
location=$(httpGet ipinfo.io/loc) > /dev/null
|
||||
httpGet $locale.wttr.in/"$location""$1"
|
||||
fi
|
||||
}
|
||||
|
||||
getLocationWeather()
|
||||
{
|
||||
args=$(echo "$@" | tr " " + )
|
||||
httpGet $locale.wttr.in/"${args}"
|
||||
}
|
||||
|
||||
checkInternet()
|
||||
{
|
||||
httpGet github.com > /dev/null 2>&1 || { echo "Error: no active internet connection" >&2; return 1; } # query github with a get request
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<EOF
|
||||
Weather
|
||||
Description: Provides a 3 day forecast on your current location or a specified location.
|
||||
With no flags Weather will default to your current location.
|
||||
Usage: weather or weather [flag] or weather [country] or weather [city] [state]
|
||||
weather [i][M] get weather in imperial units, optional M means windspeed in m/s
|
||||
weather [m][M] get weather in metric units, optional M means windspeed in m/s
|
||||
weather [Moon] grabs the phase of the moon
|
||||
-h Show the help
|
||||
-v Get the tool version
|
||||
Examples:
|
||||
weather
|
||||
weather Paris m
|
||||
weather Tokyo
|
||||
weather Moon
|
||||
weather mM
|
||||
EOF
|
||||
}
|
||||
|
||||
getConfiguredClient || exit 1
|
||||
|
||||
while getopts "uvh" opt; do
|
||||
case "$opt" in
|
||||
\?) echo "Invalid option: -$OPTARG" >&2
|
||||
exit 1
|
||||
;;
|
||||
h) usage
|
||||
exit 0
|
||||
;;
|
||||
v) echo "Version $currentVersion"
|
||||
exit 0
|
||||
;;
|
||||
u) checkInternet || exit 1 # check if we have a valid internet connection if this isnt true the rest of the script will not work so stop here
|
||||
update || exit 1
|
||||
exit 0
|
||||
;;
|
||||
:) echo "Option -$OPTARG requires an argument." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# == "0" ]]; then
|
||||
checkInternet || exit 1
|
||||
getIPWeather || exit 1
|
||||
exit 0
|
||||
elif [[ $1 == "help" || $1 == ":help" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
elif [[ $1 == "update" ]]; then
|
||||
checkInternet || exit 1
|
||||
update || exit 1
|
||||
exit 0
|
||||
fi
|
||||
|
||||
checkInternet || exit 1
|
||||
if [[ $1 == "m" ]]; then
|
||||
getIPWeather "?m" || exit 1
|
||||
elif [[ "${@: -1}" == "m" ]];then
|
||||
args=$( echo "${@:1:(($# - 1))}" ?m | sed s/" "//g)
|
||||
getLocationWeather "$args" || exit 1
|
||||
elif [[ $1 == "M" ]]; then
|
||||
getIPWeather "?M" || exit 1
|
||||
elif [[ "${@: -1}" == "M" ]];then
|
||||
args=$( echo "${@:1:(($# - 1))}" ?M | sed s/" "//g)
|
||||
getLocationWeather "$args" || exit 1
|
||||
elif [[ $1 == "mM" || $1 == "Mm" ]]; then
|
||||
getIPWeather "?m?M" || exit 1
|
||||
elif [[ "${@: -1}" == "mM" || "${@:-1}" == "Mm" ]];then
|
||||
args=$( echo "${@:1:(($# - 1))}" ?m?M | sed s/" "//g)
|
||||
getLocationWeather "$args" || exit 1
|
||||
elif [[ $1 == "iM" || $1 == "Mi" ]]; then
|
||||
getIPWeather "?u?M" || exit 1
|
||||
elif [[ "${@: -1}" == "iM" || "${@:-1}" == "Mi" ]];then
|
||||
args=$( echo "${@:1:(($# - 1))}" ?u?M | sed s/" "//g)
|
||||
getLocationWeather "$args" || exit 1
|
||||
elif [[ $1 == "i" ]]; then
|
||||
getIPWeather "?u" || exit 1
|
||||
elif [[ "${@: -1}" == "i" ]];then
|
||||
args=$( echo "${@:1:(($# - 1))}" ?u | sed s/" "//g)
|
||||
getLocationWeather "$args" || exit 1
|
||||
else
|
||||
getLocationWeather "$@" || exit 1
|
||||
fi
|
Loading…
Reference in New Issue
Block a user